2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20 import static android.Manifest.permission.CHANGE_CONFIGURATION;
21 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
22 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
23 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
24 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
25 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
26 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
27 import static android.Manifest.permission.READ_FRAME_BUFFER;
28 import static android.Manifest.permission.REMOVE_TASKS;
29 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
30 import static android.Manifest.permission.STOP_APP_SWITCHES;
31 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
32 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
33 import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
34 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
35 import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT;
36 import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA;
37 import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
38 import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
39 import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
40 import static android.app.AppOpsManager.OP_NONE;
41 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
42 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
43 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
44 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
45 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
46 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
47 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
48 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
49 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
50 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
51 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
52 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
53 import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
54 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
55 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
56 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
57 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
58 import static android.content.pm.PackageManager.GET_PROVIDERS;
59 import static android.content.pm.PackageManager.MATCH_ANY_USER;
60 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
61 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
62 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
63 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
64 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
65 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
66 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
67 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
68 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
69 import static android.os.Build.VERSION_CODES.N;
70 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
71 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
72 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
73 import static android.os.IServiceManager.DUMP_FLAG_PROTO;
74 import static android.os.Process.BLUETOOTH_UID;
75 import static android.os.Process.FIRST_APPLICATION_UID;
76 import static android.os.Process.FIRST_ISOLATED_UID;
77 import static android.os.Process.LAST_ISOLATED_UID;
78 import static android.os.Process.NFC_UID;
79 import static android.os.Process.PHONE_UID;
80 import static android.os.Process.PROC_CHAR;
81 import static android.os.Process.PROC_OUT_LONG;
82 import static android.os.Process.PROC_PARENS;
83 import static android.os.Process.PROC_SPACE_TERM;
84 import static android.os.Process.ProcessStartResult;
85 import static android.os.Process.ROOT_UID;
86 import static android.os.Process.SCHED_FIFO;
87 import static android.os.Process.SCHED_OTHER;
88 import static android.os.Process.SCHED_RESET_ON_FORK;
89 import static android.os.Process.SE_UID;
90 import static android.os.Process.SHELL_UID;
91 import static android.os.Process.SIGNAL_QUIT;
92 import static android.os.Process.SIGNAL_USR1;
93 import static android.os.Process.SYSTEM_UID;
94 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
95 import static android.os.Process.THREAD_GROUP_DEFAULT;
96 import static android.os.Process.THREAD_GROUP_RESTRICTED;
97 import static android.os.Process.THREAD_GROUP_TOP_APP;
98 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
99 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
100 import static android.os.Process.getFreeMemory;
101 import static android.os.Process.getTotalMemory;
102 import static android.os.Process.isThreadInProcess;
103 import static android.os.Process.killProcess;
104 import static android.os.Process.killProcessQuiet;
105 import static android.os.Process.myPid;
106 import static android.os.Process.myUid;
107 import static android.os.Process.readProcFile;
108 import static android.os.Process.removeAllProcessGroups;
109 import static android.os.Process.sendSignal;
110 import static android.os.Process.setProcessGroup;
111 import static android.os.Process.setThreadPriority;
112 import static android.os.Process.setThreadScheduler;
113 import static android.os.Process.startWebView;
114 import static android.os.Process.zygoteProcess;
115 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
116 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
117 import static android.provider.Settings.Global.DEBUG_APP;
118 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
119 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
120 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
121 import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
122 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
123 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
124 import static android.provider.Settings.System.FONT_SCALE;
125 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
126 import static android.text.format.DateUtils.DAY_IN_MILLIS;
127 import static android.view.Display.DEFAULT_DISPLAY;
128 import static android.view.Display.INVALID_DISPLAY;
129 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
130 import static com.android.internal.util.XmlUtils.readIntAttribute;
131 import static com.android.internal.util.XmlUtils.readLongAttribute;
132 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
133 import static com.android.internal.util.XmlUtils.writeIntAttribute;
134 import static com.android.internal.util.XmlUtils.writeLongAttribute;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
141 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
142 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
143 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
144 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
145 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
146 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
147 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
148 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
149 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
150 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
151 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
152 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
153 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
154 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
155 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
156 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
157 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
158 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
159 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
160 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
161 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
162 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
163 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
164 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
165 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
166 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
167 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
168 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
169 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
170 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
171 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
172 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
173 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
174 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
175 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
176 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
177 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
178 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
179 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
180 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
181 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
182 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
183 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
184 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
185 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
186 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
187 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
188 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
189 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
190 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
191 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
192 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
193 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
194 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
195 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
196 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
197 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
198 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
199 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
200 import static com.android.server.am.MemoryStatUtil.hasMemcg;
201 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
202 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
203 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
204 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
205 import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
206 import static android.view.WindowManager.TRANSIT_NONE;
207 import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
208 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
209 import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
210 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
211 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
212 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
213 import static org.xmlpull.v1.XmlPullParser.START_TAG;
215 import android.Manifest;
216 import android.Manifest.permission;
217 import android.annotation.NonNull;
218 import android.annotation.Nullable;
219 import android.annotation.UserIdInt;
220 import android.app.Activity;
221 import android.app.ActivityManager;
222 import android.app.ActivityManager.RunningTaskInfo;
223 import android.app.ActivityManager.StackInfo;
224 import android.app.ActivityManager.TaskSnapshot;
225 import android.app.ActivityManagerInternal;
226 import android.app.ActivityManagerInternal.ScreenObserver;
227 import android.app.ActivityManagerInternal.SleepToken;
228 import android.app.ActivityManagerProto;
229 import android.app.ActivityOptions;
230 import android.app.ActivityThread;
231 import android.app.AlertDialog;
232 import android.app.AppGlobals;
233 import android.app.AppOpsManager;
234 import android.app.ApplicationErrorReport;
235 import android.app.ApplicationThreadConstants;
236 import android.app.BroadcastOptions;
237 import android.app.ContentProviderHolder;
238 import android.app.Dialog;
239 import android.app.GrantedUriPermission;
240 import android.app.IActivityController;
241 import android.app.IActivityManager;
242 import android.app.IApplicationThread;
243 import android.app.IAssistDataReceiver;
244 import android.app.IInstrumentationWatcher;
245 import android.app.INotificationManager;
246 import android.app.IProcessObserver;
247 import android.app.IServiceConnection;
248 import android.app.IStopUserCallback;
249 import android.app.ITaskStackListener;
250 import android.app.IUiAutomationConnection;
251 import android.app.IUidObserver;
252 import android.app.IUserSwitchObserver;
253 import android.app.Instrumentation;
254 import android.app.Notification;
255 import android.app.NotificationManager;
256 import android.app.PendingIntent;
257 import android.app.PictureInPictureParams;
258 import android.app.ProcessMemoryState;
259 import android.app.ProfilerInfo;
260 import android.app.RemoteAction;
261 import android.app.WaitResult;
262 import android.app.WindowConfiguration.ActivityType;
263 import android.app.WindowConfiguration.WindowingMode;
264 import android.app.admin.DevicePolicyCache;
265 import android.app.assist.AssistContent;
266 import android.app.assist.AssistStructure;
267 import android.app.backup.IBackupManager;
268 import android.app.servertransaction.ConfigurationChangeItem;
269 import android.app.usage.UsageEvents;
270 import android.app.usage.UsageStatsManagerInternal;
271 import android.appwidget.AppWidgetManager;
272 import android.content.ActivityNotFoundException;
273 import android.content.BroadcastReceiver;
274 import android.content.ClipData;
275 import android.content.ComponentCallbacks2;
276 import android.content.ComponentName;
277 import android.content.ContentProvider;
278 import android.content.ContentResolver;
279 import android.content.Context;
280 import android.content.DialogInterface;
281 import android.content.IContentProvider;
282 import android.content.IIntentReceiver;
283 import android.content.IIntentSender;
284 import android.content.Intent;
285 import android.content.IntentFilter;
286 import android.content.pm.ActivityInfo;
287 import android.content.pm.ApplicationInfo;
288 import android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy;
289 import android.content.pm.ConfigurationInfo;
290 import android.content.pm.IPackageDataObserver;
291 import android.content.pm.IPackageManager;
292 import android.content.pm.InstrumentationInfo;
293 import android.content.pm.PackageInfo;
294 import android.content.pm.PackageManager;
295 import android.content.pm.PackageManager.NameNotFoundException;
296 import android.content.pm.PackageManagerInternal;
297 import android.content.pm.ParceledListSlice;
298 import android.content.pm.PathPermission;
299 import android.content.pm.PermissionInfo;
300 import android.content.pm.ProviderInfo;
301 import android.content.pm.ResolveInfo;
302 import android.content.pm.SELinuxUtil;
303 import android.content.pm.ServiceInfo;
304 import android.content.pm.UserInfo;
305 import android.content.res.CompatibilityInfo;
306 import android.content.res.Configuration;
307 import android.content.res.Resources;
308 import android.database.ContentObserver;
309 import android.graphics.Bitmap;
310 import android.graphics.Point;
311 import android.graphics.Rect;
312 import android.hardware.display.DisplayManagerInternal;
313 import android.location.LocationManager;
314 import android.media.audiofx.AudioEffect;
315 import android.metrics.LogMaker;
316 import android.net.Proxy;
317 import android.net.ProxyInfo;
318 import android.net.Uri;
319 import android.os.BatteryStats;
320 import android.os.Binder;
321 import android.os.Build;
322 import android.os.Bundle;
323 import android.os.Debug;
324 import android.os.DropBoxManager;
325 import android.os.Environment;
326 import android.os.FactoryTest;
327 import android.os.FileObserver;
328 import android.os.FileUtils;
329 import android.os.Handler;
330 import android.os.IBinder;
331 import android.os.IDeviceIdentifiersPolicyService;
332 import android.os.IPermissionController;
333 import android.os.IProcessInfoService;
334 import android.os.IProgressListener;
335 import android.os.LocaleList;
336 import android.os.Looper;
337 import android.os.Message;
338 import android.os.Parcel;
339 import android.os.ParcelFileDescriptor;
340 import android.os.PersistableBundle;
341 import android.os.PowerManager;
342 import android.os.PowerManager.ServiceType;
343 import android.os.PowerManagerInternal;
344 import android.os.Process;
345 import android.os.RemoteCallbackList;
346 import android.os.RemoteException;
347 import android.os.ResultReceiver;
348 import android.os.ServiceManager;
349 import android.os.ShellCallback;
350 import android.os.StrictMode;
351 import android.os.SystemClock;
352 import android.os.SystemProperties;
353 import android.os.Trace;
354 import android.os.TransactionTooLargeException;
355 import android.os.UpdateLock;
356 import android.os.UserHandle;
357 import android.os.UserManager;
358 import android.os.WorkSource;
359 import android.os.storage.IStorageManager;
360 import android.os.storage.StorageManager;
361 import android.os.storage.StorageManagerInternal;
362 import android.provider.Downloads;
363 import android.provider.Settings;
364 import android.service.voice.IVoiceInteractionSession;
365 import android.service.voice.VoiceInteractionManagerInternal;
366 import android.telecom.TelecomManager;
367 import android.text.TextUtils;
368 import android.text.format.DateUtils;
369 import android.text.format.Time;
370 import android.text.style.SuggestionSpan;
371 import android.util.ArrayMap;
372 import android.util.ArraySet;
373 import android.util.AtomicFile;
374 import android.util.DebugUtils;
375 import android.util.EventLog;
376 import android.util.Log;
377 import android.util.LongSparseArray;
378 import android.util.Pair;
379 import android.util.PrintWriterPrinter;
380 import android.util.Slog;
381 import android.util.SparseArray;
382 import android.util.SparseIntArray;
383 import android.util.StatsLog;
384 import android.util.TimeUtils;
385 import android.util.TimingsTraceLog;
386 import android.util.Xml;
387 import android.util.proto.ProtoOutputStream;
388 import android.util.proto.ProtoUtils;
389 import android.view.Gravity;
390 import android.view.IRecentsAnimationRunner;
391 import android.view.LayoutInflater;
392 import android.view.RemoteAnimationAdapter;
393 import android.view.RemoteAnimationDefinition;
394 import android.view.View;
395 import android.view.WindowManager;
396 import android.view.autofill.AutofillManagerInternal;
398 import com.android.internal.R;
399 import com.android.internal.annotations.GuardedBy;
400 import com.android.internal.annotations.VisibleForTesting;
401 import com.android.internal.app.AssistUtils;
402 import com.android.internal.app.DumpHeapActivity;
403 import com.android.internal.app.IAppOpsCallback;
404 import com.android.internal.app.IAppOpsService;
405 import com.android.internal.app.IVoiceInteractor;
406 import com.android.internal.app.ProcessMap;
407 import com.android.internal.app.SystemUserHomeActivity;
408 import com.android.internal.app.procstats.ProcessStats;
409 import com.android.internal.logging.MetricsLogger;
410 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
411 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
412 import com.android.internal.notification.SystemNotificationChannels;
413 import com.android.internal.os.BackgroundThread;
414 import com.android.internal.os.BatteryStatsImpl;
415 import com.android.internal.os.BinderInternal;
416 import com.android.internal.os.logging.MetricsLoggerWrapper;
417 import com.android.internal.os.ByteTransferPipe;
418 import com.android.internal.os.IResultReceiver;
419 import com.android.internal.os.ProcessCpuTracker;
420 import com.android.internal.os.TransferPipe;
421 import com.android.internal.os.Zygote;
422 import com.android.internal.policy.IKeyguardDismissCallback;
423 import com.android.internal.policy.KeyguardDismissCallback;
424 import com.android.internal.telephony.TelephonyIntents;
425 import com.android.internal.util.ArrayUtils;
426 import com.android.internal.util.DumpUtils;
427 import com.android.internal.util.FastPrintWriter;
428 import com.android.internal.util.FastXmlSerializer;
429 import com.android.internal.util.MemInfoReader;
430 import com.android.internal.util.Preconditions;
431 import com.android.server.AlarmManagerInternal;
432 import com.android.server.AppOpsService;
433 import com.android.server.AttributeCache;
434 import com.android.server.BinderCallsStatsService;
435 import com.android.server.DeviceIdleController;
436 import com.android.server.IntentResolver;
437 import com.android.server.IoThread;
438 import com.android.server.LocalServices;
439 import com.android.server.LockGuard;
440 import com.android.server.NetworkManagementInternal;
441 import com.android.server.RescueParty;
442 import com.android.server.ServiceThread;
443 import com.android.server.SystemConfig;
444 import com.android.server.SystemService;
445 import com.android.server.SystemServiceManager;
446 import com.android.server.ThreadPriorityBooster;
447 import com.android.server.Watchdog;
448 import com.android.server.am.ActivityStack.ActivityState;
449 import com.android.server.am.MemoryStatUtil.MemoryStat;
450 import com.android.server.am.ActivityManagerServiceProto;
451 import com.android.server.am.ActivityManagerServiceDumpActivitiesProto;
452 import com.android.server.am.ActivityManagerServiceDumpBroadcastsProto;
453 import com.android.server.am.ActivityManagerServiceDumpProcessesProto;
454 import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
455 import com.android.server.am.ActivityManagerServiceDumpServicesProto;
456 import com.android.server.am.GrantUriProto;
457 import com.android.server.am.ImportanceTokenProto;
458 import com.android.server.am.MemInfoDumpProto;
459 import com.android.server.am.NeededUriGrantsProto;
460 import com.android.server.am.ProcessOomProto;
461 import com.android.server.am.ProcessToGcProto;
462 import com.android.server.am.StickyBroadcastProto;
463 import com.android.server.firewall.IntentFirewall;
464 import com.android.server.job.JobSchedulerInternal;
465 import com.android.server.pm.Installer;
466 import com.android.server.pm.Installer.InstallerException;
467 import com.android.server.pm.dex.DexManager;
468 import com.android.server.utils.PriorityDump;
469 import com.android.server.vr.VrManagerInternal;
470 import com.android.server.wm.PinnedStackWindowController;
471 import com.android.server.wm.WindowManagerService;
473 import dalvik.system.VMRuntime;
475 import libcore.io.IoUtils;
476 import libcore.util.EmptyArray;
478 import com.google.android.collect.Lists;
479 import com.google.android.collect.Maps;
481 import org.xmlpull.v1.XmlPullParser;
482 import org.xmlpull.v1.XmlPullParserException;
483 import org.xmlpull.v1.XmlSerializer;
486 import java.io.FileDescriptor;
487 import java.io.FileInputStream;
488 import java.io.FileNotFoundException;
489 import java.io.FileOutputStream;
490 import java.io.IOException;
491 import java.io.InputStreamReader;
492 import java.io.PrintWriter;
493 import java.io.StringWriter;
494 import java.io.UnsupportedEncodingException;
495 import java.lang.ref.WeakReference;
496 import java.nio.charset.StandardCharsets;
497 import java.text.DateFormat;
498 import java.text.SimpleDateFormat;
499 import java.util.ArrayList;
500 import java.util.Arrays;
501 import java.util.Collections;
502 import java.util.Comparator;
503 import java.util.Date;
504 import java.util.HashMap;
505 import java.util.HashSet;
506 import java.util.Iterator;
507 import java.util.List;
508 import java.util.Locale;
509 import java.util.Map;
510 import java.util.Objects;
511 import java.util.Set;
512 import java.util.concurrent.CountDownLatch;
513 import java.util.concurrent.Executor;
514 import java.util.concurrent.atomic.AtomicBoolean;
515 import java.util.concurrent.atomic.AtomicLong;
517 public class ActivityManagerService extends IActivityManager.Stub
518 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
521 * Priority we boost main thread and RT of top app to.
523 public static final int TOP_APP_PRIORITY_BOOST = -10;
525 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
526 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
527 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
528 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
529 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
530 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
531 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
532 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
533 private static final String TAG_LRU = TAG + POSTFIX_LRU;
534 private static final String TAG_MU = TAG + POSTFIX_MU;
535 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
536 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
537 private static final String TAG_POWER = TAG + POSTFIX_POWER;
538 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
539 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
540 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
541 private static final String TAG_PSS = TAG + POSTFIX_PSS;
542 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
543 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
544 private static final String TAG_STACK = TAG + POSTFIX_STACK;
545 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
546 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
547 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
548 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
550 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
551 // here so that while the job scheduler can depend on AMS, the other way around
552 // need not be the case.
553 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
555 /** Control over CPU and battery monitoring */
556 // write battery stats every 30 minutes.
557 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
558 static final boolean MONITOR_CPU_USAGE = true;
559 // don't sample cpu less than every 5 seconds.
560 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
561 // wait possibly forever for next cpu sample.
562 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
563 static final boolean MONITOR_THREAD_CPU_USAGE = false;
565 // The flags that are set for all calls we make to the package manager.
566 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
568 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
570 // Maximum number of receivers an app can register.
571 private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
573 // Amount of time after a call to stopAppSwitches() during which we will
574 // prevent further untrusted switches from happening.
575 static final long APP_SWITCH_DELAY_TIME = 5*1000;
577 // How long we wait for a launched process to attach to the activity manager
578 // before we decide it's never going to come up for real.
579 static final int PROC_START_TIMEOUT = 10*1000;
580 // How long we wait for an attached process to publish its content providers
581 // before we decide it must be hung.
582 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
585 * How long we wait for an provider to be published. Should be longer than
586 * {@link #CONTENT_PROVIDER_PUBLISH_TIMEOUT}.
588 static final int CONTENT_PROVIDER_WAIT_TIMEOUT = 20 * 1000;
590 // How long we wait for a launched process to attach to the activity manager
591 // before we decide it's never going to come up for real, when the process was
592 // started with a wrapper for instrumentation (such as Valgrind) because it
593 // could take much longer than usual.
594 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
596 // How long we allow a receiver to run before giving up on it.
597 static final int BROADCAST_FG_TIMEOUT = 10*1000;
598 static final int BROADCAST_BG_TIMEOUT = 60*1000;
600 // How long we wait until we timeout on key dispatching.
601 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
603 // How long we wait until we timeout on key dispatching during instrumentation.
604 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
606 // Disable hidden API checks for the newly started instrumentation.
607 // Must be kept in sync with Am.
608 private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
610 // How long to wait in getAssistContextExtras for the activity and foreground services
611 // to respond with the result.
612 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
614 // How long top wait when going through the modern assist (which doesn't need to block
615 // on getting this result before starting to launch its UI).
616 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
618 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
619 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
621 // Maximum number of persisted Uri grants a package is allowed
622 static final int MAX_PERSISTED_URI_GRANTS = 128;
624 static final int MY_PID = myPid();
626 static final String[] EMPTY_STRING_ARRAY = new String[0];
628 // How many bytes to write into the dropbox log before truncating
629 static final int DROPBOX_MAX_SIZE = 192 * 1024;
630 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
631 // as one line, but close enough for now.
632 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
634 /** If a UID observer takes more than this long, send a WTF. */
635 private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
637 // Access modes for handleIncomingUser.
638 static final int ALLOW_NON_FULL = 0;
639 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
640 static final int ALLOW_FULL_ONLY = 2;
642 // Necessary ApplicationInfo flags to mark an app as persistent
643 private static final int PERSISTENT_MASK =
644 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
646 // Intent sent when remote bugreport collection has been completed
647 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
648 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
650 // Used to indicate that an app transition should be animated.
651 static final boolean ANIMATE = true;
653 // Determines whether to take full screen screenshots
654 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
657 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
659 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
662 * State indicating that there is no need for any blocking for network.
665 static final int NETWORK_STATE_NO_CHANGE = 0;
668 * State indicating that the main thread needs to be informed about the network wait.
671 static final int NETWORK_STATE_BLOCK = 1;
674 * State indicating that any threads waiting for network state to get updated can be unblocked.
677 static final int NETWORK_STATE_UNBLOCK = 2;
679 // Max character limit for a notification title. If the notification title is larger than this
680 // the notification will not be legible to the user.
681 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
683 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
685 /** All system services */
686 SystemServiceManager mSystemServiceManager;
688 // Wrapper around VoiceInteractionServiceManager
689 private AssistUtils mAssistUtils;
691 // Keeps track of the active voice interaction service component, notified from
692 // VoiceInteractionManagerService
693 ComponentName mActiveVoiceInteractionServiceComponent;
695 private Installer mInstaller;
697 /** Run all ActivityStacks through this */
698 final ActivityStackSupervisor mStackSupervisor;
699 private final KeyguardController mKeyguardController;
701 private final ActivityStartController mActivityStartController;
703 private final ClientLifecycleManager mLifecycleManager;
705 final TaskChangeNotificationController mTaskChangeNotificationController;
707 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
709 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
711 public final IntentFirewall mIntentFirewall;
713 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
714 // default action automatically. Important for devices without direct input
716 private boolean mShowDialogs = true;
718 private final VrController mVrController;
720 // VR Vr2d Display Id.
721 int mVr2dDisplayId = INVALID_DISPLAY;
723 // Whether we should use SCHED_FIFO for UI and RenderThreads.
724 private boolean mUseFifoUiScheduling = false;
726 private static final String SYSUI_COMPONENT_NAME = "com.android.systemui/.SystemUIService";
728 BroadcastQueue mFgBroadcastQueue;
729 BroadcastQueue mBgBroadcastQueue;
730 // Convenient for easy iteration over the queues. Foreground is first
731 // so that dispatch of foreground broadcasts gets precedence.
732 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
734 BroadcastStats mLastBroadcastStats;
735 BroadcastStats mCurBroadcastStats;
737 BroadcastQueue broadcastQueueForIntent(Intent intent) {
738 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
739 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
740 "Broadcast intent " + intent + " on "
741 + (isFg ? "foreground" : "background") + " queue");
742 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
746 * The last resumed activity. This is identical to the current resumed activity most
747 * of the time but could be different when we're pausing one activity before we resume
750 private ActivityRecord mLastResumedActivity;
753 * The activity that is currently being traced as the active resumed activity.
755 * @see #updateResumedAppTrace
757 private @Nullable ActivityRecord mTracedResumedActivity;
760 * If non-null, we are tracking the time the user spends in the currently focused app.
762 private AppTimeTracker mCurAppTimeTracker;
765 * List of intents that were used to start the most recent tasks.
767 private final RecentTasks mRecentTasks;
770 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
772 String mDeviceOwnerName;
775 * The controller for all operations related to locktask.
777 private final LockTaskController mLockTaskController;
779 final UserController mUserController;
782 * Packages that are being allowed to perform unrestricted app switches. Mapping is
783 * User -> Type -> uid.
785 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
787 final AppErrors mAppErrors;
789 final AppWarnings mAppWarnings;
792 * Dump of the activity state at the time of the last ANR. Cleared after
793 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
795 String mLastANRState;
798 * Indicates the maximum time spent waiting for the network rules to get updated.
801 long mWaitForNetworkTimeoutMs;
803 /** Total # of UID change events dispatched, shown in dumpsys. */
804 int mUidChangeDispatchCount;
807 * Helper class which strips out priority and proto arguments then calls the dump function with
808 * the appropriate arguments. If priority arguments are omitted, function calls the legacy
810 * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
811 * according to their priority.
813 private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
815 public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
818 doDump(fd, pw, new String[]{"activities"}, asProto);
819 doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto);
823 public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
824 doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
828 public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
829 doDump(fd, pw, args, asProto);
833 public boolean canShowErrorDialogs() {
834 return mShowDialogs && !mSleeping && !mShuttingDown
835 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
836 && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
837 mUserController.getCurrentUserId())
838 && !(UserManager.isDeviceInDemoMode(mContext)
839 && mUserController.getCurrentUser().isDemo());
842 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
843 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
845 static void boostPriorityForLockedSection() {
846 sThreadPriorityBooster.boost();
849 static void resetPriorityAfterLockedSection() {
850 sThreadPriorityBooster.reset();
853 public class PendingAssistExtras extends Binder implements Runnable {
854 public final ActivityRecord activity;
855 public boolean isHome;
856 public final Bundle extras;
857 public final Intent intent;
858 public final String hint;
859 public final IAssistDataReceiver receiver;
860 public final int userHandle;
861 public boolean haveResult = false;
862 public Bundle result = null;
863 public AssistStructure structure = null;
864 public AssistContent content = null;
865 public Bundle receiverExtras;
867 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
868 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
870 activity = _activity;
874 receiver = _receiver;
875 receiverExtras = _receiverExtras;
876 userHandle = _userHandle;
881 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
882 synchronized (this) {
886 pendingAssistExtrasTimedOut(this);
890 final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
893 * Process management.
895 final ProcessList mProcessList = new ProcessList();
898 * All of the applications we currently have running organized by name.
899 * The keys are strings of the application package name (as
900 * returned by the package manager), and the keys are ApplicationRecord
903 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
906 * Tracking long-term execution of processes to look for abuse and other
909 final ProcessStatsService mProcessStats;
912 * The currently running isolated processes.
914 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
917 * Counter for assigning isolated process uids, to avoid frequently reusing the
920 int mNextIsolatedProcessUid = 0;
923 * The currently running heavy-weight process, if any.
925 ProcessRecord mHeavyWeightProcess = null;
928 * Non-persistent appId whitelist for background restrictions
930 int[] mBackgroundAppIdWhitelist = new int[] {
935 * Broadcast actions that will always be deliverable to unlaunched/background apps
937 ArraySet<String> mBackgroundLaunchBroadcasts;
940 * All of the processes we currently have running organized by pid.
941 * The keys are the pid running the application.
943 * <p>NOTE: This object is protected by its own lock, NOT the global
944 * activity manager lock!
946 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
949 * All of the processes that have been forced to be important. The key
950 * is the pid of the caller who requested it (we hold a death
953 abstract class ImportanceToken implements IBinder.DeathRecipient {
958 ImportanceToken(int _pid, IBinder _token, String _reason) {
965 public String toString() {
966 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
967 + " " + reason + " " + pid + " " + token + " }";
970 void writeToProto(ProtoOutputStream proto, long fieldId) {
971 final long pToken = proto.start(fieldId);
972 proto.write(ImportanceTokenProto.PID, pid);
974 proto.write(ImportanceTokenProto.TOKEN, token.toString());
976 proto.write(ImportanceTokenProto.REASON, reason);
980 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
983 * List of records for processes that someone had tried to start before the
984 * system was ready. We don't start them at that point, but ensure they
985 * are started by the time booting is complete.
987 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
990 * List of persistent applications that are in the process
993 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
996 * Processes that are being forcibly torn down.
998 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
1001 * List of running applications, sorted by recent usage.
1002 * The first entry in the list is the least recently used.
1004 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
1007 * Where in mLruProcesses that the processes hosting activities start.
1009 int mLruProcessActivityStart = 0;
1012 * Where in mLruProcesses that the processes hosting services start.
1013 * This is after (lower index) than mLruProcessesActivityStart.
1015 int mLruProcessServiceStart = 0;
1018 * List of processes that should gc as soon as things are idle.
1020 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
1023 * Processes we want to collect PSS data from.
1025 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
1027 private boolean mBinderTransactionTrackingEnabled = false;
1030 * Last time we requested PSS data of all processes.
1032 long mLastFullPssTime = SystemClock.uptimeMillis();
1035 * If set, the next time we collect PSS data we should do a full collection
1036 * with data from native processes and the kernel.
1038 boolean mFullPssPending = false;
1041 * This is the process holding what we currently consider to be
1042 * the "home" activity.
1044 ProcessRecord mHomeProcess;
1047 * This is the process holding the activity the user last visited that
1048 * is in a different process from the one they are currently in.
1050 ProcessRecord mPreviousProcess;
1053 * The time at which the previous process was last visible.
1055 long mPreviousProcessVisibleTime;
1058 * Track all uids that have actively running processes.
1060 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1063 * This is for verifying the UID report flow.
1065 static final boolean VALIDATE_UID_STATES = true;
1066 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1069 * Packages that the user has asked to have run in screen size
1070 * compatibility mode instead of filling the screen.
1072 final CompatModePackages mCompatModePackages;
1075 * Set of IntentSenderRecord objects that are currently active.
1077 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1078 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1081 * Fingerprints (hashCode()) of stack traces that we've
1082 * already logged DropBox entries for. Guarded by itself. If
1083 * something (rogue user app) forces this over
1084 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1086 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1087 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1090 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1091 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1093 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1096 * Resolver for broadcast intents to registered receivers.
1097 * Holds BroadcastFilter (subclass of IntentFilter).
1099 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1100 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1102 protected boolean allowFilterResult(
1103 BroadcastFilter filter, List<BroadcastFilter> dest) {
1104 IBinder target = filter.receiverList.receiver.asBinder();
1105 for (int i = dest.size() - 1; i >= 0; i--) {
1106 if (dest.get(i).receiverList.receiver.asBinder() == target) {
1114 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1115 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1116 || userId == filter.owningUserId) {
1117 return super.newResult(filter, match, userId);
1123 protected BroadcastFilter[] newArray(int size) {
1124 return new BroadcastFilter[size];
1128 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1129 return packageName.equals(filter.packageName);
1134 * State of all active sticky broadcasts per user. Keys are the action of the
1135 * sticky Intent, values are an ArrayList of all broadcasted intents with
1136 * that action (which should usually be one). The SparseArray is keyed
1137 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1138 * for stickies that are sent to all users.
1140 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1141 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1143 final ActiveServices mServices;
1145 final static class Association {
1146 final int mSourceUid;
1147 final String mSourceProcess;
1148 final int mTargetUid;
1149 final ComponentName mTargetComponent;
1150 final String mTargetProcess;
1158 // states of the source process when the bind occurred.
1159 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1160 long mLastStateUptime;
1161 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1162 - ActivityManager.MIN_PROCESS_STATE+1];
1164 Association(int sourceUid, String sourceProcess, int targetUid,
1165 ComponentName targetComponent, String targetProcess) {
1166 mSourceUid = sourceUid;
1167 mSourceProcess = sourceProcess;
1168 mTargetUid = targetUid;
1169 mTargetComponent = targetComponent;
1170 mTargetProcess = targetProcess;
1175 * When service association tracking is enabled, this is all of the associations we
1176 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1177 * -> association data.
1179 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1180 mAssociations = new SparseArray<>();
1181 boolean mTrackingAssociations;
1184 * Backup/restore process management
1186 String mBackupAppName = null;
1187 BackupRecord mBackupTarget = null;
1189 final ProviderMap mProviderMap;
1192 * List of content providers who have clients waiting for them. The
1193 * application is currently being launched and the provider will be
1194 * removed from this list once it is published.
1196 final ArrayList<ContentProviderRecord> mLaunchingProviders
1197 = new ArrayList<ContentProviderRecord>();
1200 * File storing persisted {@link #mGrantedUriPermissions}.
1202 private final AtomicFile mGrantFile;
1204 /** XML constants used in {@link #mGrantFile} */
1205 private static final String TAG_URI_GRANTS = "uri-grants";
1206 private static final String TAG_URI_GRANT = "uri-grant";
1207 private static final String ATTR_USER_HANDLE = "userHandle";
1208 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1209 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1210 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1211 private static final String ATTR_TARGET_PKG = "targetPkg";
1212 private static final String ATTR_URI = "uri";
1213 private static final String ATTR_MODE_FLAGS = "modeFlags";
1214 private static final String ATTR_CREATED_TIME = "createdTime";
1215 private static final String ATTR_PREFIX = "prefix";
1218 * Global set of specific {@link Uri} permissions that have been granted.
1219 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1220 * to {@link UriPermission#uri} to {@link UriPermission}.
1223 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1224 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1226 public static class GrantUri {
1227 public final int sourceUserId;
1228 public final Uri uri;
1229 public boolean prefix;
1231 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1232 this.sourceUserId = sourceUserId;
1234 this.prefix = prefix;
1238 public int hashCode() {
1240 hashCode = 31 * hashCode + sourceUserId;
1241 hashCode = 31 * hashCode + uri.hashCode();
1242 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1247 public boolean equals(Object o) {
1248 if (o instanceof GrantUri) {
1249 GrantUri other = (GrantUri) o;
1250 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1251 && prefix == other.prefix;
1257 public String toString() {
1258 String result = uri.toString() + " [user " + sourceUserId + "]";
1259 if (prefix) result += " [prefix]";
1263 public String toSafeString() {
1264 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1265 if (prefix) result += " [prefix]";
1269 public void writeToProto(ProtoOutputStream proto, long fieldId) {
1270 long token = proto.start(fieldId);
1271 proto.write(GrantUriProto.URI, uri.toString());
1272 proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1276 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1277 if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
1278 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1279 ContentProvider.getUriWithoutUserId(uri), false);
1281 return new GrantUri(defaultSourceUserHandle, uri, false);
1286 boolean mSystemProvidersInstalled;
1288 CoreSettingsObserver mCoreSettingsObserver;
1290 FontScaleSettingObserver mFontScaleSettingObserver;
1292 private final class FontScaleSettingObserver extends ContentObserver {
1293 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1294 private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
1296 public FontScaleSettingObserver() {
1298 ContentResolver resolver = mContext.getContentResolver();
1299 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1300 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
1301 UserHandle.USER_ALL);
1305 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1306 if (mFontScaleUri.equals(uri)) {
1307 updateFontScaleIfNeeded(userId);
1308 } else if (mHideErrorDialogsUri.equals(uri)) {
1309 synchronized (ActivityManagerService.this) {
1310 updateShouldShowDialogsLocked(getGlobalConfiguration());
1316 DevelopmentSettingsObserver mDevelopmentSettingsObserver;
1318 private final class DevelopmentSettingsObserver extends ContentObserver {
1319 private final Uri mUri = Settings.Global
1320 .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
1322 private final ComponentName mBugreportStorageProvider = new ComponentName(
1323 "com.android.shell", "com.android.shell.BugreportStorageProvider");
1325 public DevelopmentSettingsObserver() {
1327 mContext.getContentResolver().registerContentObserver(mUri, false, this,
1328 UserHandle.USER_ALL);
1329 // Always kick once to ensure that we match current state
1334 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1335 if (mUri.equals(uri)) {
1340 public void onChange() {
1341 final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
1342 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
1343 mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
1344 enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1345 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
1351 * Thread-local storage used to carry caller permissions over through
1352 * indirect content-provider access.
1354 private class Identity {
1355 public final IBinder token;
1356 public final int pid;
1357 public final int uid;
1359 Identity(IBinder _token, int _pid, int _uid) {
1366 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1369 * All information we have collected about the runtime performance of
1370 * any user id that can impact battery performance.
1372 final BatteryStatsService mBatteryStatsService;
1375 * Information about component usage
1377 UsageStatsManagerInternal mUsageStatsService;
1380 * Access to DeviceIdleController service.
1382 DeviceIdleController.LocalService mLocalDeviceIdleController;
1385 * Power-save whitelisted app-ids (not including except-idle-whitelisted ones).
1387 int[] mDeviceIdleWhitelist = new int[0];
1390 * Power-save whitelisted app-ids (including except-idle-whitelisted ones).
1392 int[] mDeviceIdleExceptIdleWhitelist = new int[0];
1395 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1397 int[] mDeviceIdleTempWhitelist = new int[0];
1399 static final class PendingTempWhitelist {
1400 final int targetUid;
1401 final long duration;
1404 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1405 targetUid = _targetUid;
1406 duration = _duration;
1410 void writeToProto(ProtoOutputStream proto, long fieldId) {
1411 final long token = proto.start(fieldId);
1412 proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1413 proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1414 proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag);
1419 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1422 * Information about and control over application operations
1424 final AppOpsService mAppOpsService;
1426 /** Current sequencing integer of the configuration, for skipping old configurations. */
1427 private int mConfigurationSeq;
1430 * Temp object used when global and/or display override configuration is updated. It is also
1431 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1434 private Configuration mTempConfig = new Configuration();
1436 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1437 new UpdateConfigurationResult();
1438 private static final class UpdateConfigurationResult {
1439 // Configuration changes that were updated.
1441 // If the activity was relaunched to match the new configuration.
1442 boolean activityRelaunched;
1446 activityRelaunched = false;
1450 boolean mSuppressResizeConfigChanges;
1453 * Hardware-reported OpenGLES version.
1455 final int GL_ES_VERSION;
1458 * List of initialization arguments to pass to all processes when binding applications to them.
1459 * For example, references to the commonly used services.
1461 ArrayMap<String, IBinder> mAppBindArgs;
1462 ArrayMap<String, IBinder> mIsolatedAppBindArgs;
1465 * Temporary to avoid allocations. Protected by main lock.
1467 final StringBuilder mStringBuilder = new StringBuilder(256);
1470 * Used to control how we initialize the service.
1472 ComponentName mTopComponent;
1473 String mTopAction = Intent.ACTION_MAIN;
1476 volatile boolean mProcessesReady = false;
1477 volatile boolean mSystemReady = false;
1478 volatile boolean mOnBattery = false;
1479 volatile int mFactoryTest;
1481 @GuardedBy("this") boolean mBooting = false;
1482 @GuardedBy("this") boolean mCallFinishBooting = false;
1483 @GuardedBy("this") boolean mBootAnimationComplete = false;
1484 @GuardedBy("this") boolean mLaunchWarningShown = false;
1485 private @GuardedBy("this") boolean mCheckedForSetup = false;
1487 final Context mContext;
1490 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1491 * change at runtime. Use mContext for non-UI purposes.
1493 final Context mUiContext;
1496 * The time at which we will allow normal application switches again,
1497 * after a call to {@link #stopAppSwitches()}.
1499 long mAppSwitchesAllowedTime;
1502 * This is set to true after the first switch after mAppSwitchesAllowedTime
1503 * is set; any switches after that will clear the time.
1505 boolean mDidAppSwitch;
1508 * Last time (in uptime) at which we checked for power usage.
1510 long mLastPowerCheckUptime;
1513 * Set while we are wanting to sleep, to prevent any
1514 * activities from being started/resumed.
1516 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1518 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1519 * while in the sleep state until there is a pending transition out of sleep, in which case
1520 * mSleeping is set to false, and remains false while awake.
1522 * Whether mSleeping can quickly toggled between true/false without the device actually
1523 * display changing states is undefined.
1525 private boolean mSleeping = false;
1528 * The process state used for processes that are running the top activities.
1529 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1531 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1534 * Set while we are running a voice interaction. This overrides
1535 * sleeping while it is active.
1537 IVoiceInteractionSession mRunningVoice;
1540 * For some direct access we need to power manager.
1542 PowerManagerInternal mLocalPowerManager;
1545 * We want to hold a wake lock while running a voice interaction session, since
1546 * this may happen with the screen off and we need to keep the CPU running to
1547 * be able to continue to interact with the user.
1549 PowerManager.WakeLock mVoiceWakeLock;
1552 * State of external calls telling us if the device is awake or asleep.
1554 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1557 * State of external calls telling us if the device is awake or asleep.
1559 private boolean mKeyguardShown = false;
1562 * Set if we are shutting down the system, similar to sleeping.
1564 boolean mShuttingDown = false;
1567 * Current sequence id for oom_adj computation traversal.
1572 * Current sequence id for process LRU updating.
1577 * Keep track of the non-cached/empty process we last found, to help
1578 * determine how to distribute cached/empty processes next time.
1580 int mNumNonCachedProcs = 0;
1583 * Keep track of the number of cached hidden procs, to balance oom adj
1584 * distribution between those and empty procs.
1586 int mNumCachedHiddenProcs = 0;
1589 * Keep track of the number of service processes we last found, to
1590 * determine on the next iteration which should be B services.
1592 int mNumServiceProcs = 0;
1593 int mNewNumAServiceProcs = 0;
1594 int mNewNumServiceProcs = 0;
1597 * Allow the current computed overall memory level of the system to go down?
1598 * This is set to false when we are killing processes for reasons other than
1599 * memory management, so that the now smaller process list will not be taken as
1600 * an indication that memory is tighter.
1602 boolean mAllowLowerMemLevel = false;
1605 * The last computed memory level, for holding when we are in a state that
1606 * processes are going away for other reasons.
1608 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1611 * The last total number of process we have, to determine if changes actually look
1612 * like a shrinking number of process due to lower RAM.
1614 int mLastNumProcesses;
1617 * The uptime of the last time we performed idle maintenance.
1619 long mLastIdleTime = SystemClock.uptimeMillis();
1622 * Total time spent with RAM that has been added in the past since the last idle time.
1624 long mLowRamTimeSinceLastIdle = 0;
1627 * If RAM is currently low, when that horrible situation started.
1629 long mLowRamStartTime = 0;
1632 * For reporting to battery stats the current top application.
1634 private String mCurResumedPackage = null;
1635 private int mCurResumedUid = -1;
1638 * For reporting to battery stats the apps currently running foreground
1639 * service. The ProcessMap is package/uid tuples; each of these contain
1640 * an array of the currently foreground processes.
1642 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1643 = new ProcessMap<ArrayList<ProcessRecord>>();
1646 * Set if the systemServer made a call to enterSafeMode.
1651 * If true, we are running under a test environment so will sample PSS from processes
1652 * much more rapidly to try to collect better data when the tests are rapidly
1653 * running through apps.
1655 boolean mTestPssMode = false;
1657 String mDebugApp = null;
1658 boolean mWaitForDebugger = false;
1659 boolean mDebugTransient = false;
1660 String mOrigDebugApp = null;
1661 boolean mOrigWaitForDebugger = false;
1662 boolean mAlwaysFinishActivities = false;
1663 boolean mForceResizableActivities;
1665 * Flag that indicates if multi-window is enabled.
1667 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1668 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1669 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1670 * At least one of the forms of multi-window must be enabled in order for this flag to be
1671 * initialized to 'true'.
1673 * @see #mSupportsSplitScreenMultiWindow
1674 * @see #mSupportsFreeformWindowManagement
1675 * @see #mSupportsPictureInPicture
1676 * @see #mSupportsMultiDisplay
1678 boolean mSupportsMultiWindow;
1679 boolean mSupportsSplitScreenMultiWindow;
1680 boolean mSupportsFreeformWindowManagement;
1681 boolean mSupportsPictureInPicture;
1682 boolean mSupportsMultiDisplay;
1683 boolean mSupportsLeanbackOnly;
1684 IActivityController mController = null;
1685 boolean mControllerIsAMonkey = false;
1686 String mProfileApp = null;
1687 ProcessRecord mProfileProc = null;
1688 ProfilerInfo mProfilerInfo = null;
1691 * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1692 * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1693 * A non-null agent in mProfileInfo overrides this.
1695 private @Nullable Map<String, String> mAppAgentMap = null;
1697 int mProfileType = 0;
1698 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1699 String mMemWatchDumpProcName;
1700 String mMemWatchDumpFile;
1701 int mMemWatchDumpPid;
1702 int mMemWatchDumpUid;
1703 String mTrackAllocationApp = null;
1704 String mNativeDebuggingApp = null;
1706 final long[] mTmpLong = new long[3];
1708 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1711 * A global counter for generating sequence numbers.
1712 * This value will be used when incrementing sequence numbers in individual uidRecords.
1714 * Having a global counter ensures that seq numbers are monotonically increasing for a
1715 * particular uid even when the uidRecord is re-created.
1719 long mProcStateSeqCounter = 0;
1722 * A global counter for generating sequence numbers to uniquely identify pending process starts.
1725 private long mProcStartSeqCounter = 0;
1728 * Contains {@link ProcessRecord} objects for pending process starts.
1730 * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1733 private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1735 private final Injector mInjector;
1737 static final class ProcessChangeItem {
1738 static final int CHANGE_ACTIVITIES = 1<<0;
1743 boolean foregroundActivities;
1746 static final class UidObserverRegistration {
1753 * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
1754 * We show it in dumpsys.
1756 int mSlowDispatchCount;
1758 /** Max time it took for each dispatch. */
1759 int mMaxDispatchTime;
1761 final SparseIntArray lastProcStates;
1763 // Please keep the enum lists in sync
1764 private static int[] ORIG_ENUMS = new int[]{
1765 ActivityManager.UID_OBSERVER_IDLE,
1766 ActivityManager.UID_OBSERVER_ACTIVE,
1767 ActivityManager.UID_OBSERVER_GONE,
1768 ActivityManager.UID_OBSERVER_PROCSTATE,
1770 private static int[] PROTO_ENUMS = new int[]{
1771 ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1772 ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1773 ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1774 ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1777 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1781 cutpoint = _cutpoint;
1782 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1783 lastProcStates = new SparseIntArray();
1785 lastProcStates = null;
1789 void writeToProto(ProtoOutputStream proto, long fieldId) {
1790 final long token = proto.start(fieldId);
1791 proto.write(UidObserverRegistrationProto.UID, uid);
1792 proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1793 ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1794 which, ORIG_ENUMS, PROTO_ENUMS);
1795 proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1796 if (lastProcStates != null) {
1797 final int NI = lastProcStates.size();
1798 for (int i=0; i<NI; i++) {
1799 final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1800 proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1801 proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1809 final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1811 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1812 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1814 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1815 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1817 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1818 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1820 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1821 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1823 OomAdjObserver mCurOomAdjObserver;
1826 interface OomAdjObserver {
1827 void onOomAdjMessage(String msg);
1831 * Runtime CPU use collection thread. This object's lock is used to
1832 * perform synchronization with the thread (notifying it to run).
1834 final Thread mProcessCpuThread;
1837 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1838 * Must acquire this object's lock when accessing it.
1839 * NOTE: this lock will be held while doing long operations (trawling
1840 * through all processes in /proc), so it should never be acquired by
1841 * any critical paths such as when holding the main activity manager lock.
1843 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1844 MONITOR_THREAD_CPU_USAGE);
1845 final AtomicLong mLastCpuTime = new AtomicLong(0);
1846 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1847 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1849 long mLastWriteTime = 0;
1852 * Used to retain an update lock when the foreground activity is in
1855 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1858 * Set to true after the system has finished booting.
1860 boolean mBooted = false;
1863 * Current boot phase.
1867 WindowManagerService mWindowManager;
1868 final ActivityThread mSystemThread;
1870 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1871 final ProcessRecord mApp;
1873 final IApplicationThread mAppThread;
1875 AppDeathRecipient(ProcessRecord app, int pid,
1876 IApplicationThread thread) {
1877 if (DEBUG_ALL) Slog.v(
1878 TAG, "New death recipient " + this
1879 + " for thread " + thread.asBinder());
1882 mAppThread = thread;
1886 public void binderDied() {
1887 if (DEBUG_ALL) Slog.v(
1888 TAG, "Death received in " + this
1889 + " for thread " + mAppThread.asBinder());
1890 synchronized(ActivityManagerService.this) {
1891 appDiedLocked(mApp, mPid, mAppThread, true);
1896 static final int SHOW_ERROR_UI_MSG = 1;
1897 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1898 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1899 static final int UPDATE_CONFIGURATION_MSG = 4;
1900 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1901 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1902 static final int SERVICE_TIMEOUT_MSG = 12;
1903 static final int UPDATE_TIME_ZONE = 13;
1904 static final int SHOW_UID_ERROR_UI_MSG = 14;
1905 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1906 static final int PROC_START_TIMEOUT_MSG = 20;
1907 static final int KILL_APPLICATION_MSG = 22;
1908 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1909 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1910 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1911 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1912 static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1913 static final int CLEAR_DNS_CACHE_MSG = 28;
1914 static final int UPDATE_HTTP_PROXY_MSG = 29;
1915 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1916 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1917 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1918 static final int REPORT_MEM_USAGE_MSG = 33;
1919 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1920 static final int PERSIST_URI_GRANTS_MSG = 38;
1921 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1922 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1923 static final int FINISH_BOOTING_MSG = 45;
1924 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1925 static final int DISMISS_DIALOG_UI_MSG = 48;
1926 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1927 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1928 static final int DELETE_DUMPHEAP_MSG = 51;
1929 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1930 static final int REPORT_TIME_TRACKER_MSG = 54;
1931 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1932 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1933 static final int IDLE_UIDS_MSG = 58;
1934 static final int LOG_STACK_STATE = 60;
1935 static final int VR_MODE_CHANGE_MSG = 61;
1936 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1937 static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1938 static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1939 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1940 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1941 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1942 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1943 static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1945 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1946 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1947 static final int FIRST_COMPAT_MODE_MSG = 300;
1948 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1950 static final String SERVICE_RECORD_KEY = "servicerecord";
1952 static ServiceThread sKillThread = null;
1953 static KillHandler sKillHandler = null;
1955 CompatModeDialog mCompatModeDialog;
1956 long mLastMemUsageReportTime = 0;
1959 * Flag whether the current user is a "monkey", i.e. whether
1960 * the UI is driven by a UI automation tool.
1962 private boolean mUserIsMonkey;
1964 /** The dimensions of the thumbnails in the Recents UI. */
1965 int mThumbnailWidth;
1966 int mThumbnailHeight;
1967 float mFullscreenThumbnailScale;
1969 final ServiceThread mHandlerThread;
1970 final MainHandler mHandler;
1971 final Handler mUiHandler;
1972 final ServiceThread mProcStartHandlerThread;
1973 final Handler mProcStartHandler;
1975 final ActivityManagerConstants mConstants;
1977 // Encapsulates the global setting "hidden_api_blacklist_exemptions"
1978 final HiddenApiSettings mHiddenApiBlacklist;
1980 PackageManagerInternal mPackageManagerInt;
1982 // VoiceInteraction session ID that changes for each new request except when
1983 // being called for multiwindow assist in a single session.
1984 private int mViSessionId = 1000;
1986 final boolean mPermissionReviewRequired;
1988 boolean mHasHeavyWeightFeature;
1991 * Whether to force background check on all apps (for battery saver) or not.
1993 boolean mForceBackgroundCheck;
1995 private static String sTheRealBuildSerial = Build.UNKNOWN;
1998 * Current global configuration information. Contains general settings for the entire system,
1999 * also corresponds to the merged configuration of the default display.
2001 Configuration getGlobalConfiguration() {
2002 return mStackSupervisor.getConfiguration();
2005 final class KillHandler extends Handler {
2006 static final int KILL_PROCESS_GROUP_MSG = 4000;
2008 public KillHandler(Looper looper) {
2009 super(looper, null, true);
2013 public void handleMessage(Message msg) {
2015 case KILL_PROCESS_GROUP_MSG:
2017 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2018 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
2019 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2024 super.handleMessage(msg);
2029 final class UiHandler extends Handler {
2030 public UiHandler() {
2031 super(com.android.server.UiThread.get().getLooper(), null, true);
2035 public void handleMessage(Message msg) {
2037 case SHOW_ERROR_UI_MSG: {
2038 mAppErrors.handleShowAppErrorUi(msg);
2039 ensureBootCompleted();
2041 case SHOW_NOT_RESPONDING_UI_MSG: {
2042 mAppErrors.handleShowAnrUi(msg);
2043 ensureBootCompleted();
2045 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
2046 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
2047 synchronized (ActivityManagerService.this) {
2048 ProcessRecord proc = (ProcessRecord) data.get("app");
2050 Slog.e(TAG, "App not found when showing strict mode dialog.");
2053 if (proc.crashDialog != null) {
2054 Slog.e(TAG, "App already has strict mode dialog: " + proc);
2057 AppErrorResult res = (AppErrorResult) data.get("result");
2058 if (mShowDialogs && !mSleeping && !mShuttingDown) {
2059 Dialog d = new StrictModeViolationDialog(mUiContext,
2060 ActivityManagerService.this, res, proc);
2062 proc.crashDialog = d;
2064 // The device is asleep, so just pretend that the user
2065 // saw a crash dialog and hit "force quit".
2069 ensureBootCompleted();
2071 case SHOW_FACTORY_ERROR_UI_MSG: {
2072 Dialog d = new FactoryErrorDialog(
2073 mUiContext, msg.getData().getCharSequence("msg"));
2075 ensureBootCompleted();
2077 case WAIT_FOR_DEBUGGER_UI_MSG: {
2078 synchronized (ActivityManagerService.this) {
2079 ProcessRecord app = (ProcessRecord)msg.obj;
2080 if (msg.arg1 != 0) {
2081 if (!app.waitedForDebugger) {
2082 Dialog d = new AppWaitingForDebuggerDialog(
2083 ActivityManagerService.this,
2086 app.waitedForDebugger = true;
2090 if (app.waitDialog != null) {
2091 app.waitDialog.dismiss();
2092 app.waitDialog = null;
2097 case SHOW_UID_ERROR_UI_MSG: {
2099 AlertDialog d = new BaseErrorDialog(mUiContext);
2100 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2101 d.setCancelable(false);
2102 d.setTitle(mUiContext.getText(R.string.android_system_label));
2103 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
2104 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2105 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2109 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
2111 AlertDialog d = new BaseErrorDialog(mUiContext);
2112 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2113 d.setCancelable(false);
2114 d.setTitle(mUiContext.getText(R.string.android_system_label));
2115 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
2116 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2117 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2121 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
2122 synchronized (ActivityManagerService.this) {
2123 ActivityRecord ar = (ActivityRecord) msg.obj;
2124 if (mCompatModeDialog != null) {
2125 if (mCompatModeDialog.mAppInfo.packageName.equals(
2126 ar.info.applicationInfo.packageName)) {
2129 mCompatModeDialog.dismiss();
2130 mCompatModeDialog = null;
2132 if (ar != null && false) {
2133 if (mCompatModePackages.getPackageAskCompatModeLocked(
2135 int mode = mCompatModePackages.computeCompatModeLocked(
2136 ar.info.applicationInfo);
2137 if (mode == ActivityManager.COMPAT_MODE_DISABLED
2138 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
2139 mCompatModeDialog = new CompatModeDialog(
2140 ActivityManagerService.this, mUiContext,
2141 ar.info.applicationInfo);
2142 mCompatModeDialog.show();
2149 case DISMISS_DIALOG_UI_MSG: {
2150 final Dialog d = (Dialog) msg.obj;
2154 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2155 dispatchProcessesChanged();
2158 case DISPATCH_PROCESS_DIED_UI_MSG: {
2159 final int pid = msg.arg1;
2160 final int uid = msg.arg2;
2161 dispatchProcessDied(pid, uid);
2164 case DISPATCH_UIDS_CHANGED_UI_MSG: {
2165 dispatchUidsChanged();
2167 case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2168 dispatchOomAdjObserver((String)msg.obj);
2170 case PUSH_TEMP_WHITELIST_UI_MSG: {
2171 pushTempWhitelist();
2177 final class MainHandler extends Handler {
2178 public MainHandler(Looper looper) {
2179 super(looper, null, true);
2183 public void handleMessage(Message msg) {
2185 case UPDATE_CONFIGURATION_MSG: {
2186 final ContentResolver resolver = mContext.getContentResolver();
2187 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2190 case GC_BACKGROUND_PROCESSES_MSG: {
2191 synchronized (ActivityManagerService.this) {
2192 performAppGcsIfAppropriateLocked();
2195 case SERVICE_TIMEOUT_MSG: {
2196 mServices.serviceTimeout((ProcessRecord)msg.obj);
2198 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2199 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2201 case SERVICE_FOREGROUND_CRASH_MSG: {
2202 mServices.serviceForegroundCrash(
2203 (ProcessRecord) msg.obj, msg.getData().getCharSequence(SERVICE_RECORD_KEY));
2205 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2206 RemoteCallbackList<IResultReceiver> callbacks
2207 = (RemoteCallbackList<IResultReceiver>)msg.obj;
2208 int N = callbacks.beginBroadcast();
2209 for (int i = 0; i < N; i++) {
2211 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2212 } catch (RemoteException e) {
2215 callbacks.finishBroadcast();
2216 // We have to clean up the RemoteCallbackList here, because otherwise it will
2217 // needlessly hold the enclosed callbacks until the remote process dies.
2220 case UPDATE_TIME_ZONE: {
2221 synchronized (ActivityManagerService.this) {
2222 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2223 ProcessRecord r = mLruProcesses.get(i);
2224 if (r.thread != null) {
2226 r.thread.updateTimeZone();
2227 } catch (RemoteException ex) {
2228 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2234 case CLEAR_DNS_CACHE_MSG: {
2235 synchronized (ActivityManagerService.this) {
2236 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2237 ProcessRecord r = mLruProcesses.get(i);
2238 if (r.thread != null) {
2240 r.thread.clearDnsCache();
2241 } catch (RemoteException ex) {
2242 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2248 case UPDATE_HTTP_PROXY_MSG: {
2249 ProxyInfo proxy = (ProxyInfo)msg.obj;
2252 String exclList = "";
2253 Uri pacFileUrl = Uri.EMPTY;
2254 if (proxy != null) {
2255 host = proxy.getHost();
2256 port = Integer.toString(proxy.getPort());
2257 exclList = proxy.getExclusionListAsString();
2258 pacFileUrl = proxy.getPacFileUrl();
2260 synchronized (ActivityManagerService.this) {
2261 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2262 ProcessRecord r = mLruProcesses.get(i);
2263 // Don't dispatch to isolated processes as they can't access
2264 // ConnectivityManager and don't have network privileges anyway.
2265 if (r.thread != null && !r.isolated) {
2267 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2268 } catch (RemoteException ex) {
2269 Slog.w(TAG, "Failed to update http proxy for: " +
2270 r.info.processName);
2276 case PROC_START_TIMEOUT_MSG: {
2277 ProcessRecord app = (ProcessRecord)msg.obj;
2278 synchronized (ActivityManagerService.this) {
2279 processStartTimedOutLocked(app);
2282 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2283 ProcessRecord app = (ProcessRecord)msg.obj;
2284 synchronized (ActivityManagerService.this) {
2285 processContentProviderPublishTimedOutLocked(app);
2288 case KILL_APPLICATION_MSG: {
2289 synchronized (ActivityManagerService.this) {
2290 final int appId = msg.arg1;
2291 final int userId = msg.arg2;
2292 Bundle bundle = (Bundle)msg.obj;
2293 String pkg = bundle.getString("pkg");
2294 String reason = bundle.getString("reason");
2295 forceStopPackageLocked(pkg, appId, false, false, true, false,
2296 false, userId, reason);
2299 case FINALIZE_PENDING_INTENT_MSG: {
2300 ((PendingIntentRecord)msg.obj).completeFinalize();
2302 case POST_HEAVY_NOTIFICATION_MSG: {
2303 INotificationManager inm = NotificationManager.getService();
2308 ActivityRecord root = (ActivityRecord)msg.obj;
2309 ProcessRecord process = root.app;
2310 if (process == null) {
2315 Context context = mContext.createPackageContext(process.info.packageName, 0);
2316 String text = mContext.getString(R.string.heavy_weight_notification,
2317 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2318 Notification notification =
2319 new Notification.Builder(context,
2320 SystemNotificationChannels.HEAVY_WEIGHT_APP)
2321 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2325 .setColor(mContext.getColor(
2326 com.android.internal.R.color.system_notification_accent_color))
2327 .setContentTitle(text)
2329 mContext.getText(R.string.heavy_weight_notification_detail))
2330 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2331 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2332 new UserHandle(root.userId)))
2335 inm.enqueueNotificationWithTag("android", "android", null,
2336 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2337 notification, root.userId);
2338 } catch (RuntimeException e) {
2339 Slog.w(ActivityManagerService.TAG,
2340 "Error showing notification for heavy-weight app", e);
2341 } catch (RemoteException e) {
2343 } catch (NameNotFoundException e) {
2344 Slog.w(TAG, "Unable to create context for heavy notification", e);
2347 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2348 INotificationManager inm = NotificationManager.getService();
2353 inm.cancelNotificationWithTag("android", null,
2354 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2355 } catch (RuntimeException e) {
2356 Slog.w(ActivityManagerService.TAG,
2357 "Error canceling notification for service", e);
2358 } catch (RemoteException e) {
2361 case CHECK_EXCESSIVE_POWER_USE_MSG: {
2362 synchronized (ActivityManagerService.this) {
2363 checkExcessivePowerUsageLocked();
2364 removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2365 Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2366 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2369 case REPORT_MEM_USAGE_MSG: {
2370 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2371 Thread thread = new Thread() {
2372 @Override public void run() {
2373 reportMemUsage(memInfos);
2379 case IMMERSIVE_MODE_LOCK_MSG: {
2380 final boolean nextState = (msg.arg1 != 0);
2381 if (mUpdateLock.isHeld() != nextState) {
2382 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2383 "Applying new update lock state '" + nextState
2384 + "' for " + (ActivityRecord)msg.obj);
2386 mUpdateLock.acquire();
2388 mUpdateLock.release();
2393 case PERSIST_URI_GRANTS_MSG: {
2394 writeGrantedUriPermissions();
2397 case UPDATE_TIME_PREFERENCE_MSG: {
2398 // The user's time format preference might have changed.
2399 // For convenience we re-use the Intent extra values.
2400 synchronized (ActivityManagerService.this) {
2401 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2402 ProcessRecord r = mLruProcesses.get(i);
2403 if (r.thread != null) {
2405 r.thread.updateTimePrefs(msg.arg1);
2406 } catch (RemoteException ex) {
2407 Slog.w(TAG, "Failed to update preferences for: "
2408 + r.info.processName);
2415 case ENTER_ANIMATION_COMPLETE_MSG: {
2416 synchronized (ActivityManagerService.this) {
2417 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2418 if (r != null && r.app != null && r.app.thread != null) {
2420 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2421 } catch (RemoteException e) {
2427 case FINISH_BOOTING_MSG: {
2428 if (msg.arg1 != 0) {
2429 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2431 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2433 if (msg.arg2 != 0) {
2434 enableScreenAfterBoot();
2438 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2440 Locale l = (Locale) msg.obj;
2441 IBinder service = ServiceManager.getService("mount");
2442 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2443 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2444 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2445 } catch (RemoteException e) {
2446 Log.e(TAG, "Error storing locale for decryption UI", e);
2450 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2451 final int uid = msg.arg1;
2452 final byte[] firstPacket = (byte[]) msg.obj;
2454 synchronized (mPidsSelfLocked) {
2455 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2456 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2459 p.thread.notifyCleartextNetwork(firstPacket);
2460 } catch (RemoteException ignored) {
2467 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2468 final String procName;
2470 final long memLimit;
2471 final String reportPackage;
2472 synchronized (ActivityManagerService.this) {
2473 procName = mMemWatchDumpProcName;
2474 uid = mMemWatchDumpUid;
2475 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2477 val = mMemWatchProcesses.get(procName, 0);
2480 memLimit = val.first;
2481 reportPackage = val.second;
2484 reportPackage = null;
2487 if (procName == null) {
2491 if (DEBUG_PSS) Slog.d(TAG_PSS,
2492 "Showing dump heap notification from " + procName + "/" + uid);
2494 INotificationManager inm = NotificationManager.getService();
2499 String text = mContext.getString(R.string.dump_heap_notification, procName);
2502 Intent deleteIntent = new Intent();
2503 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2504 Intent intent = new Intent();
2505 intent.setClassName("android", DumpHeapActivity.class.getName());
2506 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2507 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2508 if (reportPackage != null) {
2509 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2511 int userId = UserHandle.getUserId(uid);
2512 Notification notification =
2513 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2514 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2517 .setAutoCancel(true)
2519 .setColor(mContext.getColor(
2520 com.android.internal.R.color.system_notification_accent_color))
2521 .setContentTitle(text)
2523 mContext.getText(R.string.dump_heap_notification_detail))
2524 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2525 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2526 new UserHandle(userId)))
2527 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2528 deleteIntent, 0, UserHandle.SYSTEM))
2532 inm.enqueueNotificationWithTag("android", "android", null,
2533 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2534 notification, userId);
2535 } catch (RuntimeException e) {
2536 Slog.w(ActivityManagerService.TAG,
2537 "Error showing notification for dump heap", e);
2538 } catch (RemoteException e) {
2541 case DELETE_DUMPHEAP_MSG: {
2542 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2543 null, DumpHeapActivity.JAVA_URI,
2544 Intent.FLAG_GRANT_READ_URI_PERMISSION
2545 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2546 UserHandle.myUserId());
2547 synchronized (ActivityManagerService.this) {
2548 mMemWatchDumpFile = null;
2549 mMemWatchDumpProcName = null;
2550 mMemWatchDumpPid = -1;
2551 mMemWatchDumpUid = -1;
2554 case REPORT_TIME_TRACKER_MSG: {
2555 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2556 tracker.deliverResult(mContext);
2558 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2559 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2561 connection.shutdown();
2562 } catch (RemoteException e) {
2563 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2565 // Only a UiAutomation can set this flag and now that
2566 // it is finished we make sure it is reset to its default.
2567 mUserIsMonkey = false;
2569 case IDLE_UIDS_MSG: {
2572 case VR_MODE_CHANGE_MSG: {
2573 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2576 synchronized (ActivityManagerService.this) {
2577 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2578 mWindowManager.disableNonVrUi(disableNonVrUi);
2579 if (disableNonVrUi) {
2580 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2581 // then remove the pinned stack.
2582 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2586 case DISPATCH_SCREEN_AWAKE_MSG: {
2587 final boolean isAwake = msg.arg1 != 0;
2588 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2589 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2592 case DISPATCH_SCREEN_KEYGUARD_MSG: {
2593 final boolean isShowing = msg.arg1 != 0;
2594 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2595 mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2598 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2599 synchronized (ActivityManagerService.this) {
2600 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2601 ProcessRecord r = mLruProcesses.get(i);
2602 if (r.thread != null) {
2604 r.thread.handleTrustStorageUpdate();
2605 } catch (RemoteException ex) {
2606 Slog.w(TAG, "Failed to handle trust storage update for: " +
2607 r.info.processName);
2617 static final int COLLECT_PSS_BG_MSG = 1;
2619 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2621 public void handleMessage(Message msg) {
2623 case COLLECT_PSS_BG_MSG: {
2624 long start = SystemClock.uptimeMillis();
2625 MemInfoReader memInfo = null;
2626 synchronized (ActivityManagerService.this) {
2627 if (mFullPssPending) {
2628 mFullPssPending = false;
2629 memInfo = new MemInfoReader();
2632 if (memInfo != null) {
2633 updateCpuStatsNow();
2634 long nativeTotalPss = 0;
2635 final List<ProcessCpuTracker.Stats> stats;
2636 synchronized (mProcessCpuTracker) {
2637 stats = mProcessCpuTracker.getStats( (st)-> {
2638 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2641 final int N = stats.size();
2642 for (int j = 0; j < N; j++) {
2643 synchronized (mPidsSelfLocked) {
2644 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2645 // This is one of our own processes; skip it.
2649 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2651 memInfo.readMemInfo();
2652 synchronized (ActivityManagerService.this) {
2653 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2654 + (SystemClock.uptimeMillis()-start) + "ms");
2655 final long cachedKb = memInfo.getCachedSizeKb();
2656 final long freeKb = memInfo.getFreeSizeKb();
2657 final long zramKb = memInfo.getZramTotalSizeKb();
2658 final long kernelKb = memInfo.getKernelUsedSizeKb();
2659 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2660 kernelKb*1024, nativeTotalPss*1024);
2661 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2667 long[] tmp = new long[3];
2674 synchronized (ActivityManagerService.this) {
2675 if (mPendingPssProcesses.size() <= 0) {
2676 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2677 "Collected pss of " + num + " processes in "
2678 + (SystemClock.uptimeMillis() - start) + "ms");
2679 mPendingPssProcesses.clear();
2682 proc = mPendingPssProcesses.remove(0);
2683 procState = proc.pssProcState;
2684 statType = proc.pssStatType;
2685 lastPssTime = proc.lastPssTime;
2686 long now = SystemClock.uptimeMillis();
2687 if (proc.thread != null && procState == proc.setProcState
2688 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2692 ProcessList.abortNextPssTime(proc.procStateMemTracker);
2693 if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2695 (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
2702 long startTime = SystemClock.currentThreadTimeMillis();
2703 long pss = Debug.getPss(pid, tmp, null);
2704 long endTime = SystemClock.currentThreadTimeMillis();
2705 synchronized (ActivityManagerService.this) {
2706 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2707 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2709 ProcessList.commitNextPssTime(proc.procStateMemTracker);
2710 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
2711 statType, endTime-startTime, SystemClock.uptimeMillis());
2713 ProcessList.abortNextPssTime(proc.procStateMemTracker);
2714 if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2715 ": " + (proc.thread == null ? "NO_THREAD " : "") +
2716 (proc.pid != pid ? "PID_CHANGED " : "") +
2717 " initState=" + procState + " curState=" +
2718 proc.setProcState + " " +
2719 (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
2729 public void setSystemProcess() {
2731 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2732 DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2733 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2734 ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2735 DUMP_FLAG_PRIORITY_HIGH);
2736 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2737 ServiceManager.addService("dbinfo", new DbBinder(this));
2738 if (MONITOR_CPU_USAGE) {
2739 ServiceManager.addService("cpuinfo", new CpuBinder(this),
2740 /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2742 ServiceManager.addService("permission", new PermissionController(this));
2743 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2745 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2746 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2747 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2749 synchronized (this) {
2750 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2751 app.persistent = true;
2753 app.maxAdj = ProcessList.SYSTEM_ADJ;
2754 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2755 synchronized (mPidsSelfLocked) {
2756 mPidsSelfLocked.put(app.pid, app);
2758 updateLruProcessLocked(app, false, null);
2759 updateOomAdjLocked();
2761 } catch (PackageManager.NameNotFoundException e) {
2762 throw new RuntimeException(
2763 "Unable to find android system package", e);
2766 // Start watching app ops after we and the package manager are up and running.
2767 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2768 new IAppOpsCallback.Stub() {
2769 @Override public void opChanged(int op, int uid, String packageName) {
2770 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2771 if (mAppOpsService.checkOperation(op, uid, packageName)
2772 != AppOpsManager.MODE_ALLOWED) {
2773 runInBackgroundDisabled(uid);
2780 public void setWindowManager(WindowManagerService wm) {
2781 synchronized (this) {
2782 mWindowManager = wm;
2783 mStackSupervisor.setWindowManager(wm);
2784 mLockTaskController.setWindowManager(wm);
2788 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2789 mUsageStatsService = usageStatsManager;
2792 public void startObservingNativeCrashes() {
2793 final NativeCrashListener ncl = new NativeCrashListener(this);
2797 public IAppOpsService getAppOpsService() {
2798 return mAppOpsService;
2801 static class MemBinder extends Binder {
2802 ActivityManagerService mActivityManagerService;
2803 private final PriorityDump.PriorityDumper mPriorityDumper =
2804 new PriorityDump.PriorityDumper() {
2806 public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2808 dump(fd, pw, new String[] {"-a"}, asProto);
2812 public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2813 mActivityManagerService.dumpApplicationMemoryUsage(
2814 fd, pw, " ", args, false, null, asProto);
2818 MemBinder(ActivityManagerService activityManagerService) {
2819 mActivityManagerService = activityManagerService;
2823 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2824 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2825 "meminfo", pw)) return;
2826 PriorityDump.dump(mPriorityDumper, fd, pw, args);
2830 static class GraphicsBinder extends Binder {
2831 ActivityManagerService mActivityManagerService;
2832 GraphicsBinder(ActivityManagerService activityManagerService) {
2833 mActivityManagerService = activityManagerService;
2837 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2838 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2839 "gfxinfo", pw)) return;
2840 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2844 static class DbBinder extends Binder {
2845 ActivityManagerService mActivityManagerService;
2846 DbBinder(ActivityManagerService activityManagerService) {
2847 mActivityManagerService = activityManagerService;
2851 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2852 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2853 "dbinfo", pw)) return;
2854 mActivityManagerService.dumpDbInfo(fd, pw, args);
2858 static class CpuBinder extends Binder {
2859 ActivityManagerService mActivityManagerService;
2860 private final PriorityDump.PriorityDumper mPriorityDumper =
2861 new PriorityDump.PriorityDumper() {
2863 public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2865 if (asProto) return;
2866 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2867 "cpuinfo", pw)) return;
2868 synchronized (mActivityManagerService.mProcessCpuTracker) {
2869 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2870 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2871 SystemClock.uptimeMillis()));
2876 CpuBinder(ActivityManagerService activityManagerService) {
2877 mActivityManagerService = activityManagerService;
2881 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2882 PriorityDump.dump(mPriorityDumper, fd, pw, args);
2886 public static final class Lifecycle extends SystemService {
2887 private final ActivityManagerService mService;
2889 public Lifecycle(Context context) {
2891 mService = new ActivityManagerService(context);
2895 public void onStart() {
2900 public void onBootPhase(int phase) {
2901 mService.mBootPhase = phase;
2902 if (phase == PHASE_SYSTEM_SERVICES_READY) {
2903 mService.mBatteryStatsService.systemServicesReady();
2904 mService.mServices.systemServicesReady();
2909 public void onCleanupUser(int userId) {
2910 mService.mBatteryStatsService.onCleanupUser(userId);
2913 public ActivityManagerService getService() {
2919 * Encapsulates global settings related to hidden API enforcement behaviour, including tracking
2920 * the latest value via a content observer.
2922 static class HiddenApiSettings extends ContentObserver {
2924 private final Context mContext;
2925 private boolean mBlacklistDisabled;
2926 private String mExemptionsStr;
2927 private List<String> mExemptions = Collections.emptyList();
2928 private int mLogSampleRate = -1;
2929 @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT;
2930 @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT;
2932 public HiddenApiSettings(Handler handler, Context context) {
2937 public void registerObserver() {
2938 mContext.getContentResolver().registerContentObserver(
2939 Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
2942 mContext.getContentResolver().registerContentObserver(
2943 Settings.Global.getUriFor(Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE),
2946 mContext.getContentResolver().registerContentObserver(
2947 Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS),
2950 mContext.getContentResolver().registerContentObserver(
2951 Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS),
2957 private void update() {
2958 String exemptions = Settings.Global.getString(mContext.getContentResolver(),
2959 Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS);
2960 if (!TextUtils.equals(exemptions, mExemptionsStr)) {
2961 mExemptionsStr = exemptions;
2962 if ("*".equals(exemptions)) {
2963 mBlacklistDisabled = true;
2964 mExemptions = Collections.emptyList();
2966 mBlacklistDisabled = false;
2967 mExemptions = TextUtils.isEmpty(exemptions)
2968 ? Collections.emptyList()
2969 : Arrays.asList(exemptions.split(","));
2971 if (!zygoteProcess.setApiBlacklistExemptions(mExemptions)) {
2972 Slog.e(TAG, "Failed to set API blacklist exemptions!");
2973 // leave mExemptionsStr as is, so we don't try to send the same list again.
2974 mExemptions = Collections.emptyList();
2977 int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
2978 Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, -1);
2979 if (logSampleRate < 0 || logSampleRate > 0x10000) {
2982 if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
2983 mLogSampleRate = logSampleRate;
2984 zygoteProcess.setHiddenApiAccessLogSampleRate(mLogSampleRate);
2986 mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS);
2987 mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS);
2990 private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) {
2991 int policy = Settings.Global.getInt(mContext.getContentResolver(), settingsKey,
2992 ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT);
2993 if (ApplicationInfo.isValidHiddenApiEnforcementPolicy(policy)) {
2996 return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
3000 boolean isDisabled() {
3001 return mBlacklistDisabled;
3004 @HiddenApiEnforcementPolicy int getPolicyForPrePApps() {
3008 @HiddenApiEnforcementPolicy int getPolicyForPApps() {
3012 public void onChange(boolean selfChange) {
3018 public ActivityManagerService(Injector injector) {
3019 mInjector = injector;
3020 mContext = mInjector.getContext();
3023 mActivityStartController = null;
3025 mAppWarnings = null;
3026 mAppOpsService = mInjector.getAppOpsService(null, null);
3027 mBatteryStatsService = null;
3028 mCompatModePackages = null;
3032 mHandlerThread = null;
3033 mIntentFirewall = null;
3034 mKeyguardController = null;
3035 mPermissionReviewRequired = false;
3036 mProcessCpuThread = null;
3037 mProcessStats = null;
3038 mProviderMap = null;
3039 mRecentTasks = null;
3041 mStackSupervisor = null;
3042 mSystemThread = null;
3043 mTaskChangeNotificationController = null;
3044 mUiHandler = injector.getUiHandler(null);
3045 mUserController = null;
3046 mVrController = null;
3047 mLockTaskController = null;
3048 mLifecycleManager = null;
3049 mProcStartHandlerThread = null;
3050 mProcStartHandler = null;
3051 mHiddenApiBlacklist = null;
3054 // Note: This method is invoked on the main thread but may need to attach various
3055 // handlers to other threads. So take care to be explicit about the looper.
3056 public ActivityManagerService(Context systemContext) {
3057 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
3058 mInjector = new Injector();
3059 mContext = systemContext;
3061 mFactoryTest = FactoryTest.getMode();
3062 mSystemThread = ActivityThread.currentActivityThread();
3063 mUiContext = mSystemThread.getSystemUiContext();
3065 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
3067 mPermissionReviewRequired = mContext.getResources().getBoolean(
3068 com.android.internal.R.bool.config_permissionReviewRequired);
3070 mHandlerThread = new ServiceThread(TAG,
3071 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
3072 mHandlerThread.start();
3073 mHandler = new MainHandler(mHandlerThread.getLooper());
3074 mUiHandler = mInjector.getUiHandler(this);
3076 mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
3077 THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
3078 mProcStartHandlerThread.start();
3079 mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
3081 mConstants = new ActivityManagerConstants(this, mHandler);
3083 /* static; one-time init here */
3084 if (sKillHandler == null) {
3085 sKillThread = new ServiceThread(TAG + ":kill",
3086 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
3087 sKillThread.start();
3088 sKillHandler = new KillHandler(sKillThread.getLooper());
3091 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
3092 "foreground", BROADCAST_FG_TIMEOUT, false);
3093 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
3094 "background", BROADCAST_BG_TIMEOUT, true);
3095 mBroadcastQueues[0] = mFgBroadcastQueue;
3096 mBroadcastQueues[1] = mBgBroadcastQueue;
3098 mServices = new ActiveServices(this);
3099 mProviderMap = new ProviderMap(this);
3100 mAppErrors = new AppErrors(mUiContext, this);
3102 File dataDir = Environment.getDataDirectory();
3103 File systemDir = new File(dataDir, "system");
3106 mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
3108 // TODO: Move creation of battery stats service outside of activity manager service.
3109 mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
3110 mBatteryStatsService.getActiveStatistics().readLocked();
3111 mBatteryStatsService.scheduleWriteToDisk();
3112 mOnBattery = DEBUG_POWER ? true
3113 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
3114 mBatteryStatsService.getActiveStatistics().setCallback(this);
3116 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
3118 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
3120 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
3122 mUserController = new UserController(this);
3124 mVrController = new VrController(this);
3126 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
3127 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
3129 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
3130 mUseFifoUiScheduling = true;
3133 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
3134 mTempConfig.setToDefaults();
3135 mTempConfig.setLocales(LocaleList.getDefault());
3136 mConfigurationSeq = mTempConfig.seq = 1;
3137 mStackSupervisor = createStackSupervisor();
3138 mStackSupervisor.onConfigurationChanged(mTempConfig);
3139 mKeyguardController = mStackSupervisor.getKeyguardController();
3140 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
3141 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
3142 mTaskChangeNotificationController =
3143 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
3144 mActivityStartController = new ActivityStartController(this);
3145 mRecentTasks = createRecentTasks();
3146 mStackSupervisor.setRecentTasks(mRecentTasks);
3147 mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
3148 mLifecycleManager = new ClientLifecycleManager();
3150 mProcessCpuThread = new Thread("CpuTracker") {
3153 synchronized (mProcessCpuTracker) {
3154 mProcessCpuInitLatch.countDown();
3155 mProcessCpuTracker.init();
3160 synchronized(this) {
3161 final long now = SystemClock.uptimeMillis();
3162 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
3163 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
3164 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
3165 // + ", write delay=" + nextWriteDelay);
3166 if (nextWriteDelay < nextCpuDelay) {
3167 nextCpuDelay = nextWriteDelay;
3169 if (nextCpuDelay > 0) {
3170 mProcessCpuMutexFree.set(true);
3171 this.wait(nextCpuDelay);
3174 } catch (InterruptedException e) {
3176 updateCpuStatsNow();
3177 } catch (Exception e) {
3178 Slog.e(TAG, "Unexpected exception collecting process stats", e);
3184 mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
3186 Watchdog.getInstance().addMonitor(this);
3187 Watchdog.getInstance().addThread(mHandler);
3189 // bind background thread to little cores
3190 // this is expected to fail inside of framework tests because apps can't touch cpusets directly
3191 // make sure we've already adjusted system_server's internal view of itself first
3192 updateOomAdjLocked();
3194 Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
3195 Process.THREAD_GROUP_BG_NONINTERACTIVE);
3196 } catch (Exception e) {
3197 Slog.w(TAG, "Setting background thread cpuset failed");
3202 protected ActivityStackSupervisor createStackSupervisor() {
3203 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
3204 supervisor.initialize();
3208 protected RecentTasks createRecentTasks() {
3209 return new RecentTasks(this, mStackSupervisor);
3212 RecentTasks getRecentTasks() {
3213 return mRecentTasks;
3216 public void setSystemServiceManager(SystemServiceManager mgr) {
3217 mSystemServiceManager = mgr;
3220 public void setInstaller(Installer installer) {
3221 mInstaller = installer;
3224 private void start() {
3225 removeAllProcessGroups();
3226 mProcessCpuThread.start();
3228 mBatteryStatsService.publish();
3229 mAppOpsService.publish(mContext);
3230 Slog.d("AppOps", "AppOpsService published");
3231 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
3232 // Wait for the synchronized block started in mProcessCpuThread,
3233 // so that any other acccess to mProcessCpuTracker from main thread
3234 // will be blocked during mProcessCpuTracker initialization.
3236 mProcessCpuInitLatch.await();
3237 } catch (InterruptedException e) {
3238 Slog.wtf(TAG, "Interrupted wait during start", e);
3239 Thread.currentThread().interrupt();
3240 throw new IllegalStateException("Interrupted wait during start");
3244 void onUserStoppedLocked(int userId) {
3245 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3246 mAllowAppSwitchUids.remove(userId);
3249 public void initPowerManagement() {
3250 mStackSupervisor.initPowerManagement();
3251 mBatteryStatsService.initPowerManagement();
3252 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3253 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3254 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3255 mVoiceWakeLock.setReferenceCounted(false);
3258 private ArraySet<String> getBackgroundLaunchBroadcasts() {
3259 if (mBackgroundLaunchBroadcasts == null) {
3260 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3262 return mBackgroundLaunchBroadcasts;
3266 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3267 throws RemoteException {
3268 if (code == SYSPROPS_TRANSACTION) {
3269 // We need to tell all apps about the system property change.
3270 ArrayList<IBinder> procs = new ArrayList<IBinder>();
3271 synchronized(this) {
3272 final int NP = mProcessNames.getMap().size();
3273 for (int ip=0; ip<NP; ip++) {
3274 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3275 final int NA = apps.size();
3276 for (int ia=0; ia<NA; ia++) {
3277 ProcessRecord app = apps.valueAt(ia);
3278 if (app.thread != null) {
3279 procs.add(app.thread.asBinder());
3285 int N = procs.size();
3286 for (int i=0; i<N; i++) {
3287 Parcel data2 = Parcel.obtain();
3289 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3290 Binder.FLAG_ONEWAY);
3291 } catch (RemoteException e) {
3297 return super.onTransact(code, data, reply, flags);
3298 } catch (RuntimeException e) {
3299 // The activity manager only throws certain exceptions intentionally, so let's
3301 if (!(e instanceof SecurityException
3302 || e instanceof IllegalArgumentException
3303 || e instanceof IllegalStateException)) {
3304 Slog.wtf(TAG, "Activity Manager Crash."
3305 + " UID:" + Binder.getCallingUid()
3306 + " PID:" + Binder.getCallingPid()
3307 + " TRANS:" + code, e);
3313 void updateCpuStats() {
3314 final long now = SystemClock.uptimeMillis();
3315 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3318 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3319 synchronized (mProcessCpuThread) {
3320 mProcessCpuThread.notify();
3325 void updateCpuStatsNow() {
3326 synchronized (mProcessCpuTracker) {
3327 mProcessCpuMutexFree.set(false);
3328 final long now = SystemClock.uptimeMillis();
3329 boolean haveNewCpuStats = false;
3331 if (MONITOR_CPU_USAGE &&
3332 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3333 mLastCpuTime.set(now);
3334 mProcessCpuTracker.update();
3335 if (mProcessCpuTracker.hasGoodLastStats()) {
3336 haveNewCpuStats = true;
3337 //Slog.i(TAG, mProcessCpu.printCurrentState());
3338 //Slog.i(TAG, "Total CPU usage: "
3339 // + mProcessCpu.getTotalCpuPercent() + "%");
3341 // Slog the cpu usage if the property is set.
3342 if ("true".equals(SystemProperties.get("events.cpu"))) {
3343 int user = mProcessCpuTracker.getLastUserTime();
3344 int system = mProcessCpuTracker.getLastSystemTime();
3345 int iowait = mProcessCpuTracker.getLastIoWaitTime();
3346 int irq = mProcessCpuTracker.getLastIrqTime();
3347 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3348 int idle = mProcessCpuTracker.getLastIdleTime();
3350 int total = user + system + iowait + irq + softIrq + idle;
3351 if (total == 0) total = 1;
3353 EventLog.writeEvent(EventLogTags.CPU,
3354 ((user+system+iowait+irq+softIrq) * 100) / total,
3355 (user * 100) / total,
3356 (system * 100) / total,
3357 (iowait * 100) / total,
3358 (irq * 100) / total,
3359 (softIrq * 100) / total);
3364 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3365 synchronized(bstats) {
3366 synchronized(mPidsSelfLocked) {
3367 if (haveNewCpuStats) {
3368 if (bstats.startAddingCpuLocked()) {
3371 final int N = mProcessCpuTracker.countStats();
3372 for (int i=0; i<N; i++) {
3373 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3377 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3378 totalUTime += st.rel_utime;
3379 totalSTime += st.rel_stime;
3381 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3382 if (ps == null || !ps.isActive()) {
3383 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3384 pr.info.uid, pr.processName);
3386 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3387 pr.curCpuTime += st.rel_utime + st.rel_stime;
3388 if (pr.lastCpuTime == 0) {
3389 pr.lastCpuTime = pr.curCpuTime;
3392 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3393 if (ps == null || !ps.isActive()) {
3394 st.batteryStats = ps = bstats.getProcessStatsLocked(
3395 bstats.mapUid(st.uid), st.name);
3397 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3400 final int userTime = mProcessCpuTracker.getLastUserTime();
3401 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3402 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3403 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3404 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3405 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3406 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3407 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3412 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3413 mLastWriteTime = now;
3414 mBatteryStatsService.scheduleWriteToDisk();
3421 public void batteryNeedsCpuUpdate() {
3422 updateCpuStatsNow();
3426 public void batteryPowerChanged(boolean onBattery) {
3427 // When plugging in, update the CPU stats first before changing
3429 updateCpuStatsNow();
3430 synchronized (this) {
3431 synchronized(mPidsSelfLocked) {
3432 mOnBattery = DEBUG_POWER ? true : onBattery;
3438 public void batteryStatsReset() {
3439 BinderCallsStatsService.reset();
3443 public void batterySendBroadcast(Intent intent) {
3444 synchronized (this) {
3445 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3446 OP_NONE, null, false, false,
3447 -1, SYSTEM_UID, UserHandle.USER_ALL);
3452 * Initialize the application bind args. These are passed to each
3453 * process when the bindApplication() IPC is sent to the process. They're
3454 * lazily setup to make sure the services are running when they're asked for.
3456 private ArrayMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3457 // Isolated processes won't get this optimization, so that we don't
3458 // violate the rules about which services they have access to.
3460 if (mIsolatedAppBindArgs == null) {
3461 mIsolatedAppBindArgs = new ArrayMap<>(1);
3462 addServiceToMap(mIsolatedAppBindArgs, "package");
3464 return mIsolatedAppBindArgs;
3467 if (mAppBindArgs == null) {
3468 mAppBindArgs = new ArrayMap<>();
3470 // Add common services.
3471 // IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
3472 // Enable the check in ApplicationThread.bindApplication() to make sure.
3473 addServiceToMap(mAppBindArgs, "package");
3474 addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
3475 addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
3476 addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
3477 addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
3478 addServiceToMap(mAppBindArgs, Context.CONNECTIVITY_SERVICE);
3479 addServiceToMap(mAppBindArgs, Context.ACCESSIBILITY_SERVICE);
3480 addServiceToMap(mAppBindArgs, Context.INPUT_METHOD_SERVICE);
3481 addServiceToMap(mAppBindArgs, Context.INPUT_SERVICE);
3482 addServiceToMap(mAppBindArgs, "graphicsstats");
3483 addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
3484 addServiceToMap(mAppBindArgs, "content");
3485 addServiceToMap(mAppBindArgs, Context.JOB_SCHEDULER_SERVICE);
3486 addServiceToMap(mAppBindArgs, Context.NOTIFICATION_SERVICE);
3487 addServiceToMap(mAppBindArgs, Context.VIBRATOR_SERVICE);
3488 addServiceToMap(mAppBindArgs, Context.ACCOUNT_SERVICE);
3489 addServiceToMap(mAppBindArgs, Context.POWER_SERVICE);
3490 addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
3491 addServiceToMap(mAppBindArgs, "mount");
3493 return mAppBindArgs;
3496 private static void addServiceToMap(ArrayMap<String, IBinder> map, String name) {
3497 final IBinder service = ServiceManager.getService(name);
3498 if (service != null) {
3499 map.put(name, service);
3501 Log.i(TAG, "Adding " + name + " to the pre-loaded service cache.");
3507 * Update AMS states when an activity is resumed. This should only be called by
3508 * {@link ActivityStack#onActivityStateChanged(ActivityRecord, ActivityState, String)} when an
3509 * activity is resumed.
3512 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3513 final TaskRecord task = r.getTask();
3514 if (task.isActivityTypeStandard()) {
3515 if (mCurAppTimeTracker != r.appTimeTracker) {
3516 // We are switching app tracking. Complete the current one.
3517 if (mCurAppTimeTracker != null) {
3518 mCurAppTimeTracker.stop();
3519 mHandler.obtainMessage(
3520 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3521 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3522 mCurAppTimeTracker = null;
3524 if (r.appTimeTracker != null) {
3525 mCurAppTimeTracker = r.appTimeTracker;
3526 startTimeTrackingFocusedActivityLocked();
3529 startTimeTrackingFocusedActivityLocked();
3532 r.appTimeTracker = null;
3534 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3535 // TODO: Probably not, because we don't want to resume voice on switching
3536 // back to this activity
3537 if (task.voiceInteractor != null) {
3538 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3540 finishRunningVoiceLocked();
3542 if (mLastResumedActivity != null) {
3543 final IVoiceInteractionSession session;
3545 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3546 if (lastResumedActivityTask != null
3547 && lastResumedActivityTask.voiceSession != null) {
3548 session = lastResumedActivityTask.voiceSession;
3550 session = mLastResumedActivity.voiceSession;
3553 if (session != null) {
3554 // We had been in a voice interaction session, but now focused has
3555 // move to something different. Just finish the session, we can't
3556 // return to it and retain the proper state and synchronization with
3557 // the voice interaction service.
3558 finishVoiceTask(session);
3563 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3564 mUserController.sendForegroundProfileChanged(r.userId);
3566 updateResumedAppTrace(r);
3567 mLastResumedActivity = r;
3569 mWindowManager.setFocusedApp(r.appToken, true);
3571 applyUpdateLockStateLocked(r);
3572 applyUpdateVrModeLocked(r);
3574 EventLogTags.writeAmSetResumedActivity(
3575 r == null ? -1 : r.userId,
3576 r == null ? "NULL" : r.shortComponentName,
3580 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
3581 if (mTracedResumedActivity != null) {
3582 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
3583 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
3585 if (resumed != null) {
3586 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
3587 constructResumedTraceName(resumed.packageName), 0);
3589 mTracedResumedActivity = resumed;
3592 private String constructResumedTraceName(String packageName) {
3593 return "focused app: " + packageName;
3597 public void setFocusedStack(int stackId) {
3598 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3599 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3600 final long callingId = Binder.clearCallingIdentity();
3602 synchronized (this) {
3603 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3604 if (stack == null) {
3605 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3608 final ActivityRecord r = stack.topRunningActivityLocked();
3609 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3610 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3614 Binder.restoreCallingIdentity(callingId);
3619 public void setFocusedTask(int taskId) {
3620 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3621 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3622 final long callingId = Binder.clearCallingIdentity();
3624 synchronized (this) {
3625 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3629 final ActivityRecord r = task.topRunningActivityLocked();
3630 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3631 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3635 Binder.restoreCallingIdentity(callingId);
3639 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3641 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3642 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3643 "registerTaskStackListener()");
3644 mTaskChangeNotificationController.registerTaskStackListener(listener);
3648 * Unregister a task stack listener so that it stops receiving callbacks.
3651 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3652 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3653 "unregisterTaskStackListener()");
3654 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3658 public void notifyActivityDrawn(IBinder token) {
3659 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3660 synchronized (this) {
3661 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3663 r.getStack().notifyActivityDrawnLocked(r);
3668 final void applyUpdateLockStateLocked(ActivityRecord r) {
3669 // Modifications to the UpdateLock state are done on our handler, outside
3670 // the activity manager's locks. The new state is determined based on the
3671 // state *now* of the relevant activity record. The object is passed to
3672 // the handler solely for logging detail, not to be consulted/modified.
3673 final boolean nextState = r != null && r.immersive;
3674 mHandler.sendMessage(
3675 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3678 final void applyUpdateVrModeLocked(ActivityRecord r) {
3679 // VR apps are expected to run in a main display. If an app is turning on VR for
3680 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3681 // fullscreen stack before enabling VR Mode.
3682 // TODO: The goal of this code is to keep the VR app on the main display. When the
3683 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3684 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3685 // option would be a better choice here.
3686 if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3687 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3688 + " to main stack for VR");
3689 final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3690 WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3691 moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3693 mHandler.sendMessage(
3694 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3697 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3698 Message msg = Message.obtain();
3699 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3700 msg.obj = r.getTask().askedCompatMode ? null : r;
3701 mUiHandler.sendMessage(msg);
3704 final AppWarnings getAppWarningsLocked() {
3705 return mAppWarnings;
3709 * Shows app warning dialogs, if necessary.
3711 * @param r activity record for which the warnings may be displayed
3713 final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3714 mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3715 mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3716 mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3719 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3720 String what, Object obj, ProcessRecord srcApp) {
3721 app.lastActivityTime = now;
3723 if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3724 // Don't want to touch dependent processes that are hosting activities.
3728 int lrui = mLruProcesses.lastIndexOf(app);
3730 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3731 + what + " " + obj + " from " + srcApp);
3735 if (lrui >= index) {
3736 // Don't want to cause this to move dependent processes *back* in the
3737 // list as if they were less frequently used.
3741 if (lrui >= mLruProcessActivityStart) {
3742 // Don't want to touch dependent processes that are hosting activities.
3746 mLruProcesses.remove(lrui);
3750 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3751 + " in LRU list: " + app);
3752 mLruProcesses.add(index, app);
3756 static void killProcessGroup(int uid, int pid) {
3757 if (sKillHandler != null) {
3758 sKillHandler.sendMessage(
3759 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3761 Slog.w(TAG, "Asked to kill process group before system bringup!");
3762 Process.killProcessGroup(uid, pid);
3766 final void removeLruProcessLocked(ProcessRecord app) {
3767 int lrui = mLruProcesses.lastIndexOf(app);
3770 if (app.persistent) {
3771 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
3773 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3775 killProcessQuiet(app.pid);
3776 killProcessGroup(app.uid, app.pid);
3778 app.pendingStart = false;
3782 if (lrui <= mLruProcessActivityStart) {
3783 mLruProcessActivityStart--;
3785 if (lrui <= mLruProcessServiceStart) {
3786 mLruProcessServiceStart--;
3788 mLruProcesses.remove(lrui);
3792 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3793 ProcessRecord client) {
3794 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3795 || app.treatLikeActivity || app.recentTasks.size() > 0;
3796 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3797 if (!activityChange && hasActivity) {
3798 // The process has activities, so we are only allowing activity-based adjustments
3799 // to move it. It should be kept in the front of the list with other
3800 // processes that have activities, and we don't want those to change their
3801 // order except due to activity operations.
3806 final long now = SystemClock.uptimeMillis();
3807 app.lastActivityTime = now;
3809 // First a quick reject: if the app is already at the position we will
3810 // put it, then there is nothing to do.
3812 final int N = mLruProcesses.size();
3813 if (N > 0 && mLruProcesses.get(N-1) == app) {
3814 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3818 if (mLruProcessServiceStart > 0
3819 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3820 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3825 int lrui = mLruProcesses.lastIndexOf(app);
3827 if (app.persistent && lrui >= 0) {
3828 // We don't care about the position of persistent processes, as long as
3829 // they are in the list.
3830 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3834 /* In progress: compute new position first, so we can avoid doing work
3835 if the process is not actually going to move. Not yet working.
3838 boolean inActivity = false, inService = false;
3840 // Process has activities, put it at the very tipsy-top.
3841 addIndex = mLruProcesses.size();
3842 nextIndex = mLruProcessServiceStart;
3844 } else if (hasService) {
3845 // Process has services, put it at the top of the service list.
3846 addIndex = mLruProcessActivityStart;
3847 nextIndex = mLruProcessServiceStart;
3851 // Process not otherwise of interest, it goes to the top of the non-service area.
3852 addIndex = mLruProcessServiceStart;
3853 if (client != null) {
3854 int clientIndex = mLruProcesses.lastIndexOf(client);
3855 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3857 if (clientIndex >= 0 && addIndex > clientIndex) {
3858 addIndex = clientIndex;
3861 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3864 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3865 + mLruProcessActivityStart + "): " + app);
3869 if (lrui < mLruProcessActivityStart) {
3870 mLruProcessActivityStart--;
3872 if (lrui < mLruProcessServiceStart) {
3873 mLruProcessServiceStart--;
3876 if (addIndex > lrui) {
3879 if (nextIndex > lrui) {
3883 mLruProcesses.remove(lrui);
3887 mLruProcesses.add(addIndex, app);
3889 mLruProcessActivityStart++;
3892 mLruProcessActivityStart++;
3898 final int N = mLruProcesses.size();
3899 if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3900 && mLruProcessActivityStart < (N - 1)) {
3901 // Process doesn't have activities, but has clients with
3902 // activities... move it up, but one below the top (the top
3903 // should always have a real activity).
3904 if (DEBUG_LRU) Slog.d(TAG_LRU,
3905 "Adding to second-top of LRU activity list: " + app);
3906 mLruProcesses.add(N - 1, app);
3907 // To keep it from spamming the LRU list (by making a bunch of clients),
3908 // we will push down any other entries owned by the app.
3909 final int uid = app.info.uid;
3910 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3911 ProcessRecord subProc = mLruProcesses.get(i);
3912 if (subProc.info.uid == uid) {
3913 // We want to push this one down the list. If the process after
3914 // it is for the same uid, however, don't do so, because we don't
3915 // want them internally to be re-ordered.
3916 if (mLruProcesses.get(i - 1).info.uid != uid) {
3917 if (DEBUG_LRU) Slog.d(TAG_LRU,
3918 "Pushing uid " + uid + " swapping at " + i + ": "
3919 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3920 ProcessRecord tmp = mLruProcesses.get(i);
3921 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3922 mLruProcesses.set(i - 1, tmp);
3926 // A gap, we can stop here.
3931 // Process has activities, put it at the very tipsy-top.
3932 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3933 mLruProcesses.add(app);
3935 nextIndex = mLruProcessServiceStart;
3936 } else if (hasService) {
3937 // Process has services, put it at the top of the service list.
3938 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3939 mLruProcesses.add(mLruProcessActivityStart, app);
3940 nextIndex = mLruProcessServiceStart;
3941 mLruProcessActivityStart++;
3943 // Process not otherwise of interest, it goes to the top of the non-service area.
3944 int index = mLruProcessServiceStart;
3945 if (client != null) {
3946 // If there is a client, don't allow the process to be moved up higher
3947 // in the list than that client.
3948 int clientIndex = mLruProcesses.lastIndexOf(client);
3949 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3950 + " when updating " + app);
3951 if (clientIndex <= lrui) {
3952 // Don't allow the client index restriction to push it down farther in the
3953 // list than it already is.
3956 if (clientIndex >= 0 && index > clientIndex) {
3957 index = clientIndex;
3960 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3961 mLruProcesses.add(index, app);
3962 nextIndex = index-1;
3963 mLruProcessActivityStart++;
3964 mLruProcessServiceStart++;
3967 // If the app is currently using a content provider or service,
3968 // bump those processes as well.
3969 for (int j=app.connections.size()-1; j>=0; j--) {
3970 ConnectionRecord cr = app.connections.valueAt(j);
3971 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3972 && cr.binding.service.app != null
3973 && cr.binding.service.app.lruSeq != mLruSeq
3974 && !cr.binding.service.app.persistent) {
3975 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3976 "service connection", cr, app);
3979 for (int j=app.conProviders.size()-1; j>=0; j--) {
3980 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3981 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3982 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3983 "provider reference", cpr, app);
3988 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3989 if (uid == SYSTEM_UID) {
3990 // The system gets to run in any process. If there are multiple
3991 // processes with the same uid, just pick the first (this
3992 // should never happen).
3993 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3994 if (procs == null) return null;
3995 final int procCount = procs.size();
3996 for (int i = 0; i < procCount; i++) {
3997 final int procUid = procs.keyAt(i);
3998 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3999 // Don't use an app process or different user process for system component.
4002 return procs.valueAt(i);
4005 ProcessRecord proc = mProcessNames.get(processName, uid);
4006 if (false && proc != null && !keepIfLarge
4007 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
4008 && proc.lastCachedPss >= 4000) {
4009 // Turn this condition on to cause killing to happen regularly, for testing.
4010 if (proc.baseProcessTracker != null) {
4011 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
4013 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
4014 } else if (proc != null && !keepIfLarge
4015 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
4016 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
4017 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
4018 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
4019 if (proc.baseProcessTracker != null) {
4020 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
4022 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
4028 void notifyPackageUse(String packageName, int reason) {
4029 synchronized(this) {
4030 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
4034 boolean isNextTransitionForward() {
4035 int transit = mWindowManager.getPendingAppTransition();
4036 return transit == TRANSIT_ACTIVITY_OPEN
4037 || transit == TRANSIT_TASK_OPEN
4038 || transit == TRANSIT_TASK_TO_FRONT;
4041 boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
4042 String processName, String abiOverride, int uid, Runnable crashHandler) {
4043 synchronized(this) {
4044 ApplicationInfo info = new ApplicationInfo();
4045 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
4046 // For isolated processes, the former contains the parent's uid and the latter the
4047 // actual uid of the isolated process.
4048 // In the special case introduced by this method (which is, starting an isolated
4049 // process directly from the SystemServer without an actual parent app process) the
4050 // closest thing to a parent's uid is SYSTEM_UID.
4051 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
4052 // the |isolated| logic in the ProcessRecord constructor.
4053 info.uid = SYSTEM_UID;
4054 info.processName = processName;
4055 info.className = entryPoint;
4056 info.packageName = "android";
4057 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
4058 info.targetSdkVersion = Build.VERSION.SDK_INT;
4059 ProcessRecord proc = startProcessLocked(processName, info /* info */,
4060 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
4061 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
4062 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
4064 return proc != null;
4069 final ProcessRecord startProcessLocked(String processName,
4070 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
4071 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
4072 boolean isolated, boolean keepIfLarge) {
4073 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
4074 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
4075 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
4076 null /* crashHandler */);
4080 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
4081 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
4082 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
4083 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
4084 long startTime = SystemClock.elapsedRealtime();
4087 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
4088 checkTime(startTime, "startProcess: after getProcessRecord");
4090 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
4091 // If we are in the background, then check to see if this process
4092 // is bad. If so, we will just silently fail.
4093 if (mAppErrors.isBadProcessLocked(info)) {
4094 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
4095 + "/" + info.processName);
4099 // When the user is explicitly starting a process, then clear its
4100 // crash count so that we won't make it bad until they see at
4101 // least one crash dialog again, and make the process good again
4102 // if it had been bad.
4103 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
4104 + "/" + info.processName);
4105 mAppErrors.resetProcessCrashTimeLocked(info);
4106 if (mAppErrors.isBadProcessLocked(info)) {
4107 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
4108 UserHandle.getUserId(info.uid), info.uid,
4110 mAppErrors.clearBadProcessLocked(info);
4117 // If this is an isolated process, it can't re-use an existing process.
4121 // We don't have to do anything more if:
4122 // (1) There is an existing application record; and
4123 // (2) The caller doesn't think it is dead, OR there is no thread
4124 // object attached to it so we know it couldn't have crashed; and
4125 // (3) There is a pid assigned to it, so it is either starting or
4127 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
4128 + " app=" + app + " knownToBeDead=" + knownToBeDead
4129 + " thread=" + (app != null ? app.thread : null)
4130 + " pid=" + (app != null ? app.pid : -1));
4131 if (app != null && app.pid > 0) {
4132 if ((!knownToBeDead && !app.killed) || app.thread == null) {
4133 // We already have the app running, or are waiting for it to
4134 // come up (we have a pid but not yet its thread), so keep it.
4135 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
4136 // If this is a new package in the process, add the package to the list
4137 app.addPackage(info.packageName, info.versionCode, mProcessStats);
4138 checkTime(startTime, "startProcess: done, added package to proc");
4142 // An application record is attached to a previous process,
4144 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
4145 checkTime(startTime, "startProcess: bad proc running, killing");
4146 killProcessGroup(app.uid, app.pid);
4147 handleAppDiedLocked(app, true, true);
4148 checkTime(startTime, "startProcess: done killing old proc");
4151 String hostingNameStr = hostingName != null
4152 ? hostingName.flattenToShortString() : null;
4155 checkTime(startTime, "startProcess: creating new process record");
4156 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
4158 Slog.w(TAG, "Failed making new process record for "
4159 + processName + "/" + info.uid + " isolated=" + isolated);
4162 app.crashHandler = crashHandler;
4163 app.isolatedEntryPoint = entryPoint;
4164 app.isolatedEntryPointArgs = entryPointArgs;
4165 checkTime(startTime, "startProcess: done creating new process record");
4167 // If this is a new package in the process, add the package to the list
4168 app.addPackage(info.packageName, info.versionCode, mProcessStats);
4169 checkTime(startTime, "startProcess: added package to existing proc");
4172 // If the system is not ready yet, then hold off on starting this
4173 // process until it is.
4174 if (!mProcessesReady
4175 && !isAllowedWhileBooting(info)
4176 && !allowWhileBooting) {
4177 if (!mProcessesOnHold.contains(app)) {
4178 mProcessesOnHold.add(app);
4180 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
4181 "System not ready, putting on hold: " + app);
4182 checkTime(startTime, "startProcess: returning with proc on hold");
4186 checkTime(startTime, "startProcess: stepping in to startProcess");
4187 final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
4188 checkTime(startTime, "startProcess: done starting proc!");
4189 return success ? app : null;
4192 boolean isAllowedWhileBooting(ApplicationInfo ai) {
4193 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
4197 private final void startProcessLocked(ProcessRecord app,
4198 String hostingType, String hostingNameStr) {
4199 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
4203 private final boolean startProcessLocked(ProcessRecord app,
4204 String hostingType, String hostingNameStr, String abiOverride) {
4205 return startProcessLocked(app, hostingType, hostingNameStr,
4206 false /* disableHiddenApiChecks */, abiOverride);
4210 * @return {@code true} if process start is successful, false otherwise.
4213 private final boolean startProcessLocked(ProcessRecord app, String hostingType,
4214 String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
4215 if (app.pendingStart) {
4218 long startTime = SystemClock.elapsedRealtime();
4219 if (app.pid > 0 && app.pid != MY_PID) {
4220 checkTime(startTime, "startProcess: removing from pids map");
4221 synchronized (mPidsSelfLocked) {
4222 mPidsSelfLocked.remove(app.pid);
4223 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4225 checkTime(startTime, "startProcess: done removing from pids map");
4229 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
4230 "startProcessLocked removing on hold: " + app);
4231 mProcessesOnHold.remove(app);
4233 checkTime(startTime, "startProcess: starting to update cpu stats");
4235 checkTime(startTime, "startProcess: done updating cpu stats");
4239 final int userId = UserHandle.getUserId(app.uid);
4240 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
4241 } catch (RemoteException e) {
4242 throw e.rethrowAsRuntimeException();
4247 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
4248 if (!app.isolated) {
4249 int[] permGids = null;
4251 checkTime(startTime, "startProcess: getting gids from package manager");
4252 final IPackageManager pm = AppGlobals.getPackageManager();
4253 permGids = pm.getPackageGids(app.info.packageName,
4254 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
4255 StorageManagerInternal storageManagerInternal = LocalServices.getService(
4256 StorageManagerInternal.class);
4257 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
4258 app.info.packageName);
4259 } catch (RemoteException e) {
4260 throw e.rethrowAsRuntimeException();
4264 * Add shared application and profile GIDs so applications can share some
4265 * resources like shared libraries and access user-wide resources
4267 if (ArrayUtils.isEmpty(permGids)) {
4270 gids = new int[permGids.length + 3];
4271 System.arraycopy(permGids, 0, gids, 3, permGids.length);
4273 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4274 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4275 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
4277 // Replace any invalid GIDs
4278 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
4279 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
4281 checkTime(startTime, "startProcess: building args");
4282 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4283 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4284 && mTopComponent != null
4285 && app.processName.equals(mTopComponent.getPackageName())) {
4288 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4289 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4293 int runtimeFlags = 0;
4294 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4295 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4296 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4297 // Also turn on CheckJNI for debuggable apps. It's quite
4298 // awkward to turn on otherwise.
4299 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4301 // Run the app in safe mode if its manifest requests so or the
4302 // system is booted in safe mode.
4303 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4304 mSafeMode == true) {
4305 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4307 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4308 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4310 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4311 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4312 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4314 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4315 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4316 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4318 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4319 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4321 if ("1".equals(SystemProperties.get("debug.assert"))) {
4322 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4324 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4325 // Enable all debug flags required by the native debugger.
4326 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
4327 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4328 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
4329 mNativeDebuggingApp = null;
4332 if (app.info.isPrivilegedApp() &&
4333 DexManager.isPackageSelectedToRunOob(app.pkgList.keySet())) {
4334 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4337 if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) {
4338 app.info.maybeUpdateHiddenApiEnforcementPolicy(
4339 mHiddenApiBlacklist.getPolicyForPrePApps(),
4340 mHiddenApiBlacklist.getPolicyForPApps());
4341 @HiddenApiEnforcementPolicy int policy =
4342 app.info.getHiddenApiEnforcementPolicy();
4343 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
4344 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
4345 throw new IllegalStateException("Invalid API policy: " + policy);
4347 runtimeFlags |= policyBits;
4350 String invokeWith = null;
4351 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4352 // Debuggable apps may include a wrapper script with their library directory.
4353 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4354 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4356 if (new File(wrapperFileName).exists()) {
4357 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4360 StrictMode.setThreadPolicy(oldPolicy);
4364 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4365 if (requiredAbi == null) {
4366 requiredAbi = Build.SUPPORTED_ABIS[0];
4369 String instructionSet = null;
4370 if (app.info.primaryCpuAbi != null) {
4371 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4375 app.requiredAbi = requiredAbi;
4376 app.instructionSet = instructionSet;
4378 // the per-user SELinux context must be set
4379 if (TextUtils.isEmpty(app.info.seInfoUser)) {
4380 Slog.wtf(TAG, "SELinux tag not defined",
4381 new IllegalStateException("SELinux tag not defined for "
4382 + app.info.packageName + " (uid " + app.uid + ")"));
4384 final String seInfo = app.info.seInfo
4385 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4386 // Start the process. It will either succeed and return a result containing
4387 // the PID of the new process, or else throw a RuntimeException.
4388 final String entryPoint = "android.app.ActivityThread";
4390 return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4391 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4393 } catch (RuntimeException e) {
4394 Slog.e(TAG, "Failure starting process " + app.processName, e);
4396 // Something went very wrong while trying to start this process; one
4397 // common case is when the package is frozen due to an active
4398 // upgrade. To recover, clean up any active bookkeeping related to
4399 // starting this process. (We already invoked this method once when
4400 // the package was initially frozen through KILL_APPLICATION_MSG, so
4401 // it doesn't hurt to use it again.)
4402 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4403 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4409 private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4410 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4411 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4413 app.pendingStart = true;
4414 app.killedByAm = false;
4415 app.removed = false;
4417 final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4418 app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4419 if (mConstants.FLAG_PROCESS_START_ASYNC) {
4420 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4421 "Posting procStart msg for " + app.toShortString());
4422 mProcStartHandler.post(() -> {
4424 synchronized (ActivityManagerService.this) {
4425 final String reason = isProcStartValidLocked(app, startSeq);
4426 if (reason != null) {
4427 Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4428 + " don't start process, " + reason);
4429 app.pendingStart = false;
4432 app.usingWrapper = invokeWith != null
4433 || SystemProperties.get("wrap." + app.processName) != null;
4434 mPendingStarts.put(startSeq, app);
4436 final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4437 app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4438 requiredAbi, instructionSet, invokeWith, app.startTime);
4439 synchronized (ActivityManagerService.this) {
4440 handleProcessStartedLocked(app, startResult, startSeq);
4442 } catch (RuntimeException e) {
4443 synchronized (ActivityManagerService.this) {
4444 Slog.e(TAG, "Failure starting process " + app.processName, e);
4445 mPendingStarts.remove(startSeq);
4446 app.pendingStart = false;
4447 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4448 false, false, true, false, false,
4449 UserHandle.getUserId(app.userId), "start failure");
4456 final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4457 uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4458 invokeWith, startTime);
4459 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4461 } catch (RuntimeException e) {
4462 Slog.e(TAG, "Failure starting process " + app.processName, e);
4463 app.pendingStart = false;
4464 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4465 false, false, true, false, false,
4466 UserHandle.getUserId(app.userId), "start failure");
4472 private ProcessStartResult startProcess(String hostingType, String entryPoint,
4473 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4474 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4477 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4479 checkTime(startTime, "startProcess: asking zygote to start proc");
4480 final ProcessStartResult startResult;
4481 if (hostingType.equals("webview_service")) {
4482 startResult = startWebView(entryPoint,
4483 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4484 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4485 app.info.dataDir, null,
4486 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4488 startResult = Process.start(entryPoint,
4489 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4490 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4491 app.info.dataDir, invokeWith,
4492 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4494 checkTime(startTime, "startProcess: returned from zygote!");
4497 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4502 private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4503 StringBuilder sb = null;
4504 if (app.killedByAm) {
4505 if (sb == null) sb = new StringBuilder();
4506 sb.append("killedByAm=true;");
4508 if (mProcessNames.get(app.processName, app.uid) != app) {
4509 if (sb == null) sb = new StringBuilder();
4510 sb.append("No entry in mProcessNames;");
4512 if (!app.pendingStart) {
4513 if (sb == null) sb = new StringBuilder();
4514 sb.append("pendingStart=false;");
4516 if (app.startSeq > expectedStartSeq) {
4517 if (sb == null) sb = new StringBuilder();
4518 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4520 return sb == null ? null : sb.toString();
4524 private boolean handleProcessStartedLocked(ProcessRecord pending,
4525 ProcessStartResult startResult, long expectedStartSeq) {
4526 // Indicates that this process start has been taken care of.
4527 if (mPendingStarts.get(expectedStartSeq) == null) {
4528 if (pending.pid == startResult.pid) {
4529 pending.usingWrapper = startResult.usingWrapper;
4530 // TODO: Update already existing clients of usingWrapper
4534 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4535 expectedStartSeq, false);
4539 private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4540 long expectedStartSeq, boolean procAttached) {
4541 mPendingStarts.remove(expectedStartSeq);
4542 final String reason = isProcStartValidLocked(app, expectedStartSeq);
4543 if (reason != null) {
4544 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4546 app.pendingStart = false;
4547 Process.killProcessQuiet(pid);
4548 Process.killProcessGroup(app.uid, app.pid);
4551 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4552 checkTime(app.startTime, "startProcess: done updating battery stats");
4554 EventLog.writeEvent(EventLogTags.AM_PROC_START,
4555 UserHandle.getUserId(app.startUid), pid, app.startUid,
4556 app.processName, app.hostingType,
4557 app.hostingNameStr != null ? app.hostingNameStr : "");
4560 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4561 app.seInfo, app.info.sourceDir, pid);
4562 } catch (RemoteException ex) {
4566 if (app.persistent) {
4567 Watchdog.getInstance().processStarted(app.processName, pid);
4570 checkTime(app.startTime, "startProcess: building log message");
4571 StringBuilder buf = mStringBuilder;
4573 buf.append("Start proc ");
4576 buf.append(app.processName);
4578 UserHandle.formatUid(buf, app.startUid);
4579 if (app.isolatedEntryPoint != null) {
4581 buf.append(app.isolatedEntryPoint);
4584 buf.append(" for ");
4585 buf.append(app.hostingType);
4586 if (app.hostingNameStr != null) {
4588 buf.append(app.hostingNameStr);
4590 reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
4592 app.usingWrapper = usingWrapper;
4593 app.pendingStart = false;
4594 checkTime(app.startTime, "startProcess: starting to update pids map");
4595 ProcessRecord oldApp;
4596 synchronized (mPidsSelfLocked) {
4597 oldApp = mPidsSelfLocked.get(pid);
4599 // If there is already an app occupying that pid that hasn't been cleaned up
4600 if (oldApp != null && !app.isolated) {
4601 // Clean up anything relating to this pid first
4602 Slog.w(TAG, "Reusing pid " + pid
4603 + " while app is still mapped to it");
4604 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4605 true /*replacingPid*/);
4607 synchronized (mPidsSelfLocked) {
4608 this.mPidsSelfLocked.put(pid, app);
4609 if (!procAttached) {
4610 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4612 mHandler.sendMessageDelayed(msg, usingWrapper
4613 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4616 checkTime(app.startTime, "startProcess: done updating pids map");
4620 void updateUsageStats(ActivityRecord component, boolean resumed) {
4621 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4622 "updateUsageStats: comp=" + component + "res=" + resumed);
4623 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4624 StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4625 component.app.uid, component.realActivity.getPackageName(),
4626 component.realActivity.getShortClassName(), resumed ?
4627 StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND :
4628 StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
4630 if (mUsageStatsService != null) {
4631 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4632 UsageEvents.Event.MOVE_TO_FOREGROUND);
4635 synchronized (stats) {
4636 stats.noteActivityResumedLocked(component.app.uid);
4639 if (mUsageStatsService != null) {
4640 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4641 UsageEvents.Event.MOVE_TO_BACKGROUND);
4643 synchronized (stats) {
4644 stats.noteActivityPausedLocked(component.app.uid);
4649 Intent getHomeIntent() {
4650 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4651 intent.setComponent(mTopComponent);
4652 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4653 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4654 intent.addCategory(Intent.CATEGORY_HOME);
4659 boolean startHomeActivityLocked(int userId, String reason) {
4660 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4661 && mTopAction == null) {
4662 // We are running in factory test mode, but unable to find
4663 // the factory test app, so just sit around displaying the
4664 // error message and don't try to start anything.
4667 Intent intent = getHomeIntent();
4668 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4669 if (aInfo != null) {
4670 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4671 // Don't do this if the home app is currently being
4673 aInfo = new ActivityInfo(aInfo);
4674 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4675 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4676 aInfo.applicationInfo.uid, true);
4677 if (app == null || app.instr == null) {
4678 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4679 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4680 // For ANR debugging to verify if the user activity is the one that actually
4682 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4683 mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4686 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4692 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4693 ActivityInfo ai = null;
4694 ComponentName comp = intent.getComponent();
4698 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4700 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4702 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4706 ai = info.activityInfo;
4709 } catch (RemoteException e) {
4716 boolean getCheckedForSetup() {
4717 return mCheckedForSetup;
4720 void setCheckedForSetup(boolean checked) {
4721 mCheckedForSetup = checked;
4724 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4725 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4728 void enforceNotIsolatedCaller(String caller) {
4729 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4730 throw new SecurityException("Isolated process not allowed to call " + caller);
4735 public int getFrontActivityScreenCompatMode() {
4736 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4737 synchronized (this) {
4738 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4743 public void setFrontActivityScreenCompatMode(int mode) {
4744 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4745 "setFrontActivityScreenCompatMode");
4746 synchronized (this) {
4747 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4752 public int getPackageScreenCompatMode(String packageName) {
4753 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4754 synchronized (this) {
4755 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4760 public void setPackageScreenCompatMode(String packageName, int mode) {
4761 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4762 "setPackageScreenCompatMode");
4763 synchronized (this) {
4764 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4769 public boolean getPackageAskScreenCompat(String packageName) {
4770 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4771 synchronized (this) {
4772 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4777 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4778 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4779 "setPackageAskScreenCompat");
4780 synchronized (this) {
4781 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4785 private boolean hasUsageStatsPermission(String callingPackage) {
4786 final int mode = mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS,
4787 Binder.getCallingUid(), callingPackage);
4788 if (mode == AppOpsManager.MODE_DEFAULT) {
4789 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4790 == PackageManager.PERMISSION_GRANTED;
4792 return mode == AppOpsManager.MODE_ALLOWED;
4796 public int getPackageProcessState(String packageName, String callingPackage) {
4797 if (!hasUsageStatsPermission(callingPackage)) {
4798 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4799 "getPackageProcessState");
4802 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4803 synchronized (this) {
4804 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4805 final ProcessRecord proc = mLruProcesses.get(i);
4806 if (procState > proc.setProcState) {
4807 if (proc.pkgList.containsKey(packageName) ||
4808 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4809 procState = proc.setProcState;
4818 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4819 throws RemoteException {
4820 synchronized (this) {
4821 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4823 throw new IllegalArgumentException("Unknown process: " + process);
4825 if (app.thread == null) {
4826 throw new IllegalArgumentException("Process has no app thread");
4828 if (app.trimMemoryLevel >= level) {
4829 throw new IllegalArgumentException(
4830 "Unable to set a higher trim level than current level");
4832 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4833 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4834 throw new IllegalArgumentException("Unable to set a background trim level "
4835 + "on a foreground process");
4837 app.thread.scheduleTrimMemory(level);
4838 app.trimMemoryLevel = level;
4843 private void dispatchProcessesChanged() {
4845 synchronized (this) {
4846 N = mPendingProcessChanges.size();
4847 if (mActiveProcessChanges.length < N) {
4848 mActiveProcessChanges = new ProcessChangeItem[N];
4850 mPendingProcessChanges.toArray(mActiveProcessChanges);
4851 mPendingProcessChanges.clear();
4852 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4853 "*** Delivering " + N + " process changes");
4856 int i = mProcessObservers.beginBroadcast();
4859 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4860 if (observer != null) {
4862 for (int j=0; j<N; j++) {
4863 ProcessChangeItem item = mActiveProcessChanges[j];
4864 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4865 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4866 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4867 + item.uid + ": " + item.foregroundActivities);
4868 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4869 item.foregroundActivities);
4872 } catch (RemoteException e) {
4876 mProcessObservers.finishBroadcast();
4878 synchronized (this) {
4879 for (int j=0; j<N; j++) {
4880 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4885 private void dispatchProcessDied(int pid, int uid) {
4886 int i = mProcessObservers.beginBroadcast();
4889 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4890 if (observer != null) {
4892 observer.onProcessDied(pid, uid);
4893 } catch (RemoteException e) {
4897 mProcessObservers.finishBroadcast();
4901 void dispatchUidsChanged() {
4903 synchronized (this) {
4904 N = mPendingUidChanges.size();
4905 if (mActiveUidChanges.length < N) {
4906 mActiveUidChanges = new UidRecord.ChangeItem[N];
4908 for (int i=0; i<N; i++) {
4909 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4910 mActiveUidChanges[i] = change;
4911 if (change.uidRecord != null) {
4912 change.uidRecord.pendingChange = null;
4913 change.uidRecord = null;
4916 mPendingUidChanges.clear();
4917 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4918 "*** Delivering " + N + " uid changes");
4921 mUidChangeDispatchCount += N;
4922 int i = mUidObservers.beginBroadcast();
4925 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4926 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4928 mUidObservers.finishBroadcast();
4930 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4931 for (int j = 0; j < N; ++j) {
4932 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4933 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4934 mValidateUids.remove(item.uid);
4936 UidRecord validateUid = mValidateUids.get(item.uid);
4937 if (validateUid == null) {
4938 validateUid = new UidRecord(item.uid);
4939 mValidateUids.put(item.uid, validateUid);
4941 if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4942 validateUid.idle = true;
4943 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4944 validateUid.idle = false;
4946 validateUid.curProcState = validateUid.setProcState = item.processState;
4947 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4952 synchronized (this) {
4953 for (int j = 0; j < N; j++) {
4954 mAvailUidChanges.add(mActiveUidChanges[j]);
4959 private void dispatchUidsChangedForObserver(IUidObserver observer,
4960 UidObserverRegistration reg, int changesSize) {
4961 if (observer == null) {
4965 for (int j = 0; j < changesSize; j++) {
4966 UidRecord.ChangeItem item = mActiveUidChanges[j];
4967 final int change = item.change;
4968 if (change == UidRecord.CHANGE_PROCSTATE &&
4969 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4970 // No-op common case: no significant change, the observer is not
4971 // interested in all proc state changes.
4974 final long start = SystemClock.uptimeMillis();
4975 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4976 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4977 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4978 "UID idle uid=" + item.uid);
4979 observer.onUidIdle(item.uid, item.ephemeral);
4981 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4982 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4983 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4984 "UID active uid=" + item.uid);
4985 observer.onUidActive(item.uid);
4988 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4989 if ((change & UidRecord.CHANGE_CACHED) != 0) {
4990 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4991 "UID cached uid=" + item.uid);
4992 observer.onUidCachedChanged(item.uid, true);
4993 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4994 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4995 "UID active uid=" + item.uid);
4996 observer.onUidCachedChanged(item.uid, false);
4999 if ((change & UidRecord.CHANGE_GONE) != 0) {
5000 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
5001 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5002 "UID gone uid=" + item.uid);
5003 observer.onUidGone(item.uid, item.ephemeral);
5005 if (reg.lastProcStates != null) {
5006 reg.lastProcStates.delete(item.uid);
5009 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
5010 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5011 "UID CHANGED uid=" + item.uid
5012 + ": " + item.processState);
5013 boolean doReport = true;
5014 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
5015 final int lastState = reg.lastProcStates.get(item.uid,
5016 ActivityManager.PROCESS_STATE_UNKNOWN);
5017 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
5018 final boolean lastAboveCut = lastState <= reg.cutpoint;
5019 final boolean newAboveCut = item.processState <= reg.cutpoint;
5020 doReport = lastAboveCut != newAboveCut;
5022 doReport = item.processState
5023 != ActivityManager.PROCESS_STATE_NONEXISTENT;
5027 if (reg.lastProcStates != null) {
5028 reg.lastProcStates.put(item.uid, item.processState);
5030 observer.onUidStateChanged(item.uid, item.processState,
5035 final int duration = (int) (SystemClock.uptimeMillis() - start);
5036 if (reg.mMaxDispatchTime < duration) {
5037 reg.mMaxDispatchTime = duration;
5039 if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
5040 reg.mSlowDispatchCount++;
5043 } catch (RemoteException e) {
5047 void dispatchOomAdjObserver(String msg) {
5048 OomAdjObserver observer;
5049 synchronized (this) {
5050 observer = mCurOomAdjObserver;
5053 if (observer != null) {
5054 observer.onOomAdjMessage(msg);
5058 void setOomAdjObserver(int uid, OomAdjObserver observer) {
5059 synchronized (this) {
5060 mCurOomAdjUid = uid;
5061 mCurOomAdjObserver = observer;
5065 void clearOomAdjObserver() {
5066 synchronized (this) {
5068 mCurOomAdjObserver = null;
5072 void reportOomAdjMessageLocked(String tag, String msg) {
5074 if (mCurOomAdjObserver != null) {
5075 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5079 void reportUidInfoMessageLocked(String tag, String msg, int uid) {
5081 if (mCurOomAdjObserver != null && uid == mCurOomAdjUid) {
5082 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5088 public final int startActivity(IApplicationThread caller, String callingPackage,
5089 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5090 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
5091 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
5092 resultWho, requestCode, startFlags, profilerInfo, bOptions,
5093 UserHandle.getCallingUserId());
5097 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
5098 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5099 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5100 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
5101 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
5102 true /*validateIncomingUser*/);
5105 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
5106 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5107 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
5108 boolean validateIncomingUser) {
5109 enforceNotIsolatedCaller("startActivity");
5111 userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
5112 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
5114 // TODO: Switch to user app stacks here.
5115 return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
5117 .setCallingPackage(callingPackage)
5118 .setResolvedType(resolvedType)
5119 .setResultTo(resultTo)
5120 .setResultWho(resultWho)
5121 .setRequestCode(requestCode)
5122 .setStartFlags(startFlags)
5123 .setProfilerInfo(profilerInfo)
5124 .setActivityOptions(bOptions)
5131 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
5132 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5133 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
5136 // This is very dangerous -- it allows you to perform a start activity (including
5137 // permission grants) as any app that may launch one of your own activities. So
5138 // we will only allow this to be done from activities that are part of the core framework,
5139 // and then only when they are running as the system.
5140 final ActivityRecord sourceRecord;
5141 final int targetUid;
5142 final String targetPackage;
5143 final boolean isResolver;
5144 synchronized (this) {
5145 if (resultTo == null) {
5146 throw new SecurityException("Must be called from an activity");
5148 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
5149 if (sourceRecord == null) {
5150 throw new SecurityException("Called with bad activity token: " + resultTo);
5152 if (!sourceRecord.info.packageName.equals("android")) {
5153 throw new SecurityException(
5154 "Must be called from an activity that is declared in the android package");
5156 if (sourceRecord.app == null) {
5157 throw new SecurityException("Called without a process attached to activity");
5159 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
5160 // This is still okay, as long as this activity is running under the
5161 // uid of the original calling activity.
5162 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
5163 throw new SecurityException(
5164 "Calling activity in uid " + sourceRecord.app.uid
5165 + " must be system uid or original calling uid "
5166 + sourceRecord.launchedFromUid);
5169 if (ignoreTargetSecurity) {
5170 if (intent.getComponent() == null) {
5171 throw new SecurityException(
5172 "Component must be specified with ignoreTargetSecurity");
5174 if (intent.getSelector() != null) {
5175 throw new SecurityException(
5176 "Selector not allowed with ignoreTargetSecurity");
5179 targetUid = sourceRecord.launchedFromUid;
5180 targetPackage = sourceRecord.launchedFromPackage;
5181 isResolver = sourceRecord.isResolverOrChildActivity();
5184 if (userId == UserHandle.USER_NULL) {
5185 userId = UserHandle.getUserId(sourceRecord.app.uid);
5188 // TODO: Switch to user app stacks here.
5190 return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
5191 .setCallingUid(targetUid)
5192 .setCallingPackage(targetPackage)
5193 .setResolvedType(resolvedType)
5194 .setResultTo(resultTo)
5195 .setResultWho(resultWho)
5196 .setRequestCode(requestCode)
5197 .setStartFlags(startFlags)
5198 .setActivityOptions(bOptions)
5200 .setIgnoreTargetSecurity(ignoreTargetSecurity)
5201 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
5203 } catch (SecurityException e) {
5204 // XXX need to figure out how to propagate to original app.
5205 // A SecurityException here is generally actually a fault of the original
5206 // calling activity (such as a fairly granting permissions), so propagate it
5209 StringBuilder msg = new StringBuilder();
5210 msg.append("While launching");
5211 msg.append(intent.toString());
5213 msg.append(e.getMessage());
5220 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
5221 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5222 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5223 enforceNotIsolatedCaller("startActivityAndWait");
5224 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5225 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
5226 WaitResult res = new WaitResult();
5227 // TODO: Switch to user app stacks here.
5228 mActivityStartController.obtainStarter(intent, "startActivityAndWait")
5230 .setCallingPackage(callingPackage)
5231 .setResolvedType(resolvedType)
5232 .setResultTo(resultTo)
5233 .setResultWho(resultWho)
5234 .setRequestCode(requestCode)
5235 .setStartFlags(startFlags)
5236 .setActivityOptions(bOptions)
5238 .setProfilerInfo(profilerInfo)
5245 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
5246 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5247 int startFlags, Configuration config, Bundle bOptions, int userId) {
5248 enforceNotIsolatedCaller("startActivityWithConfig");
5249 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5250 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
5251 // TODO: Switch to user app stacks here.
5252 return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
5254 .setCallingPackage(callingPackage)
5255 .setResolvedType(resolvedType)
5256 .setResultTo(resultTo)
5257 .setResultWho(resultWho)
5258 .setRequestCode(requestCode)
5259 .setStartFlags(startFlags)
5260 .setGlobalConfiguration(config)
5261 .setActivityOptions(bOptions)
5267 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
5268 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
5269 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
5270 throws TransactionTooLargeException {
5271 enforceNotIsolatedCaller("startActivityIntentSender");
5272 // Refuse possible leaked file descriptors
5273 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
5274 throw new IllegalArgumentException("File descriptors passed in Intent");
5277 if (!(target instanceof PendingIntentRecord)) {
5278 throw new IllegalArgumentException("Bad PendingIntent object");
5281 PendingIntentRecord pir = (PendingIntentRecord)target;
5283 synchronized (this) {
5284 // If this is coming from the currently resumed activity, it is
5285 // effectively saying that app switches are allowed at this point.
5286 final ActivityStack stack = getFocusedStack();
5287 if (stack.mResumedActivity != null &&
5288 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
5289 mAppSwitchesAllowedTime = 0;
5292 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
5293 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
5298 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
5299 Intent intent, String resolvedType, IVoiceInteractionSession session,
5300 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
5301 Bundle bOptions, int userId) {
5302 enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
5303 if (session == null || interactor == null) {
5304 throw new NullPointerException("null session or interactor");
5306 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5307 ALLOW_FULL_ONLY, "startVoiceActivity", null);
5308 // TODO: Switch to user app stacks here.
5309 return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
5310 .setCallingUid(callingUid)
5311 .setCallingPackage(callingPackage)
5312 .setResolvedType(resolvedType)
5313 .setVoiceSession(session)
5314 .setVoiceInteractor(interactor)
5315 .setStartFlags(startFlags)
5316 .setProfilerInfo(profilerInfo)
5317 .setActivityOptions(bOptions)
5323 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5324 Intent intent, String resolvedType, Bundle bOptions, int userId) {
5325 enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5326 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5327 ALLOW_FULL_ONLY, "startAssistantActivity", null);
5329 return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5330 .setCallingUid(callingUid)
5331 .setCallingPackage(callingPackage)
5332 .setResolvedType(resolvedType)
5333 .setActivityOptions(bOptions)
5339 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5340 IRecentsAnimationRunner recentsAnimationRunner) {
5341 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5342 final int callingPid = Binder.getCallingPid();
5343 final long origId = Binder.clearCallingIdentity();
5345 synchronized (this) {
5346 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5347 final int recentsUid = mRecentTasks.getRecentsComponentUid();
5349 // Start a new recents animation
5350 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5351 mActivityStartController, mWindowManager, mUserController, callingPid);
5352 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5353 recentsUid, assistDataReceiver);
5356 Binder.restoreCallingIdentity(origId);
5361 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5362 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5363 final long callingUid = Binder.getCallingUid();
5364 final long origId = Binder.clearCallingIdentity();
5366 synchronized (this) {
5367 // Cancel the recents animation synchronously (do not hold the WM lock)
5368 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
5369 ? REORDER_MOVE_TO_ORIGINAL_POSITION
5370 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
5373 Binder.restoreCallingIdentity(origId);
5378 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5379 throws RemoteException {
5380 Slog.i(TAG, "Activity tried to startVoiceInteraction");
5381 synchronized (this) {
5382 ActivityRecord activity = getFocusedStack().getTopActivity();
5383 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5384 throw new SecurityException("Only focused activity can call startVoiceInteraction");
5386 if (mRunningVoice != null || activity.getTask().voiceSession != null
5387 || activity.voiceSession != null) {
5388 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5391 if (activity.pendingVoiceInteractionStart) {
5392 Slog.w(TAG, "Pending start of voice interaction already.");
5395 activity.pendingVoiceInteractionStart = true;
5397 LocalServices.getService(VoiceInteractionManagerInternal.class)
5398 .startLocalVoiceInteraction(callingActivity, options);
5402 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5403 LocalServices.getService(VoiceInteractionManagerInternal.class)
5404 .stopLocalVoiceInteraction(callingActivity);
5408 public boolean supportsLocalVoiceInteraction() throws RemoteException {
5409 return LocalServices.getService(VoiceInteractionManagerInternal.class)
5410 .supportsLocalVoiceInteraction();
5414 void onLocalVoiceInteractionStartedLocked(IBinder activity,
5415 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5416 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5417 if (activityToCallback == null) return;
5418 activityToCallback.setVoiceSessionLocked(voiceSession);
5420 // Inform the activity
5422 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5424 long token = Binder.clearCallingIdentity();
5426 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5428 Binder.restoreCallingIdentity(token);
5430 // TODO: VI Should we cache the activity so that it's easier to find later
5431 // rather than scan through all the stacks and activities?
5432 } catch (RemoteException re) {
5433 activityToCallback.clearVoiceSessionLocked();
5434 // TODO: VI Should this terminate the voice session?
5439 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5440 synchronized (this) {
5441 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5443 mVoiceWakeLock.acquire();
5445 mVoiceWakeLock.release();
5452 public boolean startNextMatchingActivity(IBinder callingActivity,
5453 Intent intent, Bundle bOptions) {
5454 // Refuse possible leaked file descriptors
5455 if (intent != null && intent.hasFileDescriptors() == true) {
5456 throw new IllegalArgumentException("File descriptors passed in Intent");
5458 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5460 synchronized (this) {
5461 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5463 SafeActivityOptions.abort(options);
5466 if (r.app == null || r.app.thread == null) {
5467 // The caller is not running... d'oh!
5468 SafeActivityOptions.abort(options);
5471 intent = new Intent(intent);
5472 // The caller is not allowed to change the data.
5473 intent.setDataAndType(r.intent.getData(), r.intent.getType());
5474 // And we are resetting to find the next component...
5475 intent.setComponent(null);
5477 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5479 ActivityInfo aInfo = null;
5481 List<ResolveInfo> resolves =
5482 AppGlobals.getPackageManager().queryIntentActivities(
5483 intent, r.resolvedType,
5484 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5485 UserHandle.getCallingUserId()).getList();
5487 // Look for the original activity in the list...
5488 final int N = resolves != null ? resolves.size() : 0;
5489 for (int i=0; i<N; i++) {
5490 ResolveInfo rInfo = resolves.get(i);
5491 if (rInfo.activityInfo.packageName.equals(r.packageName)
5492 && rInfo.activityInfo.name.equals(r.info.name)) {
5493 // We found the current one... the next matching is
5497 aInfo = resolves.get(i).activityInfo;
5500 Slog.v(TAG, "Next matching activity: found current " + r.packageName
5501 + "/" + r.info.name);
5502 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5503 ? "null" : aInfo.packageName + "/" + aInfo.name));
5508 } catch (RemoteException e) {
5511 if (aInfo == null) {
5512 // Nobody who is next!
5513 SafeActivityOptions.abort(options);
5514 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5518 intent.setComponent(new ComponentName(
5519 aInfo.applicationInfo.packageName, aInfo.name));
5520 intent.setFlags(intent.getFlags()&~(
5521 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5522 Intent.FLAG_ACTIVITY_CLEAR_TOP|
5523 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5524 FLAG_ACTIVITY_NEW_TASK));
5526 // Okay now we need to start the new activity, replacing the
5527 // currently running activity. This is a little tricky because
5528 // we want to start the new one as if the current one is finished,
5529 // but not finish the current one first so that there is no flicker.
5531 final boolean wasFinishing = r.finishing;
5534 // Propagate reply information over to the new activity.
5535 final ActivityRecord resultTo = r.resultTo;
5536 final String resultWho = r.resultWho;
5537 final int requestCode = r.requestCode;
5539 if (resultTo != null) {
5540 resultTo.removeResultsLocked(r, resultWho, requestCode);
5543 final long origId = Binder.clearCallingIdentity();
5544 // TODO(b/64750076): Check if calling pid should really be -1.
5545 final int res = mActivityStartController
5546 .obtainStarter(intent, "startNextMatchingActivity")
5547 .setCaller(r.app.thread)
5548 .setResolvedType(r.resolvedType)
5549 .setActivityInfo(aInfo)
5550 .setResultTo(resultTo != null ? resultTo.appToken : null)
5551 .setResultWho(resultWho)
5552 .setRequestCode(requestCode)
5554 .setCallingUid(r.launchedFromUid)
5555 .setCallingPackage(r.launchedFromPackage)
5556 .setRealCallingPid(-1)
5557 .setRealCallingUid(r.launchedFromUid)
5558 .setActivityOptions(options)
5560 Binder.restoreCallingIdentity(origId);
5562 r.finishing = wasFinishing;
5563 if (res != ActivityManager.START_SUCCESS) {
5571 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5572 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5573 "startActivityFromRecents()");
5575 final int callingPid = Binder.getCallingPid();
5576 final int callingUid = Binder.getCallingUid();
5577 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
5578 final long origId = Binder.clearCallingIdentity();
5580 synchronized (this) {
5581 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5585 Binder.restoreCallingIdentity(origId);
5590 public final int startActivities(IApplicationThread caller, String callingPackage,
5591 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5593 final String reason = "startActivities";
5594 enforceNotIsolatedCaller(reason);
5595 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5596 userId, false, ALLOW_FULL_ONLY, reason, null);
5597 // TODO: Switch to user app stacks here.
5598 int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5599 intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5600 reason, null /* originatingPendingIntent */);
5605 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5606 synchronized (this) {
5607 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5611 r.reportFullyDrawnLocked(restoredFromBundle);
5616 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5617 synchronized (this) {
5618 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5622 final long origId = Binder.clearCallingIdentity();
5624 r.setRequestedOrientation(requestedOrientation);
5626 Binder.restoreCallingIdentity(origId);
5632 public int getRequestedOrientation(IBinder token) {
5633 synchronized (this) {
5634 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5636 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5638 return r.getRequestedOrientation();
5643 * This is the internal entry point for handling Activity.finish().
5645 * @param token The Binder token referencing the Activity we want to finish.
5646 * @param resultCode Result code, if any, from this Activity.
5647 * @param resultData Result data (Intent), if any, from this Activity.
5648 * @param finishTask Whether to finish the task associated with this Activity.
5650 * @return Returns true if the activity successfully finished, or false if it is still running.
5653 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5655 // Refuse possible leaked file descriptors
5656 if (resultData != null && resultData.hasFileDescriptors() == true) {
5657 throw new IllegalArgumentException("File descriptors passed in Intent");
5660 synchronized(this) {
5661 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5665 // Keep track of the root activity of the task before we finish it
5666 TaskRecord tr = r.getTask();
5667 ActivityRecord rootR = tr.getRootActivity();
5668 if (rootR == null) {
5669 Slog.w(TAG, "Finishing task with all activities already finished");
5671 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5673 if (mLockTaskController.activityBlockedFromFinish(r)) {
5677 if (mController != null) {
5678 // Find the first activity that is not finishing.
5679 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5681 // ask watcher if this is allowed
5682 boolean resumeOK = true;
5684 resumeOK = mController.activityResuming(next.packageName);
5685 } catch (RemoteException e) {
5687 Watchdog.getInstance().setActivityController(null);
5691 Slog.i(TAG, "Not finishing activity because controller resumed");
5696 final long origId = Binder.clearCallingIdentity();
5699 final boolean finishWithRootActivity =
5700 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5701 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5702 || (finishWithRootActivity && r == rootR)) {
5703 // If requested, remove the task that is associated to this activity only if it
5704 // was the root activity in the task. The result code and data is ignored
5705 // because we don't support returning them across task boundaries. Also, to
5706 // keep backwards compatibility we remove the task from recents when finishing
5707 // task with root activity.
5708 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5709 finishWithRootActivity, "finish-activity");
5711 Slog.i(TAG, "Removing task failed to finish activity");
5714 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5715 resultData, "app-request", true);
5717 Slog.i(TAG, "Failed to finish by app-request");
5722 Binder.restoreCallingIdentity(origId);
5728 public final void finishHeavyWeightApp() {
5729 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5730 != PackageManager.PERMISSION_GRANTED) {
5731 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5732 + Binder.getCallingPid()
5733 + ", uid=" + Binder.getCallingUid()
5734 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5736 throw new SecurityException(msg);
5739 synchronized(this) {
5740 final ProcessRecord proc = mHeavyWeightProcess;
5745 ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5746 for (int i = 0; i < activities.size(); i++) {
5747 ActivityRecord r = activities.get(i);
5748 if (!r.finishing && r.isInStackLocked()) {
5749 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5750 null, "finish-heavy", true);
5754 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5756 mHeavyWeightProcess = null;
5761 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5763 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5764 != PackageManager.PERMISSION_GRANTED) {
5765 String msg = "Permission Denial: crashApplication() from pid="
5766 + Binder.getCallingPid()
5767 + ", uid=" + Binder.getCallingUid()
5768 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5770 throw new SecurityException(msg);
5773 synchronized(this) {
5774 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5779 public final void finishSubActivity(IBinder token, String resultWho,
5781 synchronized(this) {
5782 final long origId = Binder.clearCallingIdentity();
5783 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5785 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5787 Binder.restoreCallingIdentity(origId);
5792 public boolean finishActivityAffinity(IBinder token) {
5793 synchronized(this) {
5794 final long origId = Binder.clearCallingIdentity();
5796 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5801 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5803 final TaskRecord task = r.getTask();
5804 if (mLockTaskController.activityBlockedFromFinish(r)) {
5807 return task.getStack().finishActivityAffinityLocked(r);
5809 Binder.restoreCallingIdentity(origId);
5815 public void finishVoiceTask(IVoiceInteractionSession session) {
5816 synchronized (this) {
5817 final long origId = Binder.clearCallingIdentity();
5819 // TODO: VI Consider treating local voice interactions and voice tasks
5821 mStackSupervisor.finishVoiceTask(session);
5823 Binder.restoreCallingIdentity(origId);
5830 public boolean releaseActivityInstance(IBinder token) {
5831 synchronized(this) {
5832 final long origId = Binder.clearCallingIdentity();
5834 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5838 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5840 Binder.restoreCallingIdentity(origId);
5846 public void releaseSomeActivities(IApplicationThread appInt) {
5847 synchronized(this) {
5848 final long origId = Binder.clearCallingIdentity();
5850 ProcessRecord app = getRecordForAppLocked(appInt);
5851 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5853 Binder.restoreCallingIdentity(origId);
5859 public boolean willActivityBeVisible(IBinder token) {
5860 synchronized(this) {
5861 ActivityStack stack = ActivityRecord.getStackLocked(token);
5862 if (stack != null) {
5863 return stack.willActivityBeVisibleLocked(token);
5870 public void overridePendingTransition(IBinder token, String packageName,
5871 int enterAnim, int exitAnim) {
5872 synchronized(this) {
5873 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5878 final long origId = Binder.clearCallingIdentity();
5880 if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
5881 mWindowManager.overridePendingAppTransition(packageName,
5882 enterAnim, exitAnim, null);
5885 Binder.restoreCallingIdentity(origId);
5890 * Main function for removing an existing process from the activity manager
5891 * as a result of that process going away. Clears out all connections
5895 private final void handleAppDiedLocked(ProcessRecord app,
5896 boolean restarting, boolean allowRestart) {
5898 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5899 false /*replacingPid*/);
5900 if (!kept && !restarting) {
5901 removeLruProcessLocked(app);
5903 ProcessList.remove(pid);
5907 if (mProfileProc == app) {
5908 clearProfilerLocked();
5911 // Remove this application's activities from active lists.
5912 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5914 app.clearRecentTasks();
5916 app.activities.clear();
5918 if (app.instr != null) {
5919 Slog.w(TAG, "Crash of app " + app.processName
5920 + " running instrumentation " + app.instr.mClass);
5921 Bundle info = new Bundle();
5922 info.putString("shortMsg", "Process crashed.");
5923 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5926 mWindowManager.deferSurfaceLayout();
5928 if (!restarting && hasVisibleActivities
5929 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5930 // If there was nothing to resume, and we are not already restarting this process, but
5931 // there is a visible activity that is hosted by the process... then make sure all
5932 // visible activities are running, taking care of restarting this process.
5933 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5936 mWindowManager.continueSurfaceLayout();
5941 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5942 final IBinder threadBinder = thread.asBinder();
5943 // Find the application record.
5944 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5945 final ProcessRecord rec = mLruProcesses.get(i);
5946 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5953 ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5954 if (thread == null) {
5958 int appIndex = getLRURecordIndexForAppLocked(thread);
5959 if (appIndex >= 0) {
5960 return mLruProcesses.get(appIndex);
5963 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5964 // double-check that.
5965 final IBinder threadBinder = thread.asBinder();
5966 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5967 for (int i = pmap.size()-1; i >= 0; i--) {
5968 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5969 for (int j = procs.size()-1; j >= 0; j--) {
5970 final ProcessRecord proc = procs.valueAt(j);
5971 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5972 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5982 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5983 // If there are no longer any background processes running,
5984 // and the app that died was not running instrumentation,
5985 // then tell everyone we are now low on memory.
5986 boolean haveBg = false;
5987 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5988 ProcessRecord rec = mLruProcesses.get(i);
5989 if (rec.thread != null
5990 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5997 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5999 long now = SystemClock.uptimeMillis();
6000 if (now < (mLastMemUsageReportTime+5*60*1000)) {
6003 mLastMemUsageReportTime = now;
6006 final ArrayList<ProcessMemInfo> memInfos
6007 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
6008 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
6009 long now = SystemClock.uptimeMillis();
6010 for (int i=mLruProcesses.size()-1; i>=0; i--) {
6011 ProcessRecord rec = mLruProcesses.get(i);
6012 if (rec == dyingProc || rec.thread == null) {
6016 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
6017 rec.setProcState, rec.adjType, rec.makeAdjReason()));
6019 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
6020 // The low memory report is overriding any current
6021 // state for a GC request. Make sure to do
6022 // heavy/important/visible/foreground processes first.
6023 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
6024 rec.lastRequestedGc = 0;
6026 rec.lastRequestedGc = rec.lastLowMemory;
6028 rec.reportLowMemory = true;
6029 rec.lastLowMemory = now;
6030 mProcessesToGc.remove(rec);
6031 addProcessToGcListLocked(rec);
6035 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
6036 mHandler.sendMessage(msg);
6038 scheduleAppGcsLocked();
6043 final void appDiedLocked(ProcessRecord app) {
6044 appDiedLocked(app, app.pid, app.thread, false);
6048 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
6049 boolean fromBinderDied) {
6050 // First check if this ProcessRecord is actually active for the pid.
6051 synchronized (mPidsSelfLocked) {
6052 ProcessRecord curProc = mPidsSelfLocked.get(pid);
6053 if (curProc != app) {
6054 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
6059 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6060 synchronized (stats) {
6061 stats.noteProcessDiedLocked(app.info.uid, pid);
6065 if (!fromBinderDied) {
6066 killProcessQuiet(pid);
6068 killProcessGroup(app.uid, pid);
6072 // Clean up already done if the process has been re-started.
6073 if (app.pid == pid && app.thread != null &&
6074 app.thread.asBinder() == thread.asBinder()) {
6075 boolean doLowMem = app.instr == null;
6076 boolean doOomAdj = doLowMem;
6077 if (!app.killedByAm) {
6078 reportUidInfoMessageLocked(TAG,
6079 "Process " + app.processName + " (pid " + pid + ") has died: "
6080 + ProcessList.makeOomAdjString(app.setAdj)
6081 + ProcessList.makeProcStateString(app.setProcState), app.info.uid);
6082 mAllowLowerMemLevel = true;
6084 // Note that we always want to do oom adj to update our state with the
6085 // new number of procs.
6086 mAllowLowerMemLevel = false;
6089 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
6090 app.setAdj, app.setProcState);
6091 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
6092 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
6093 handleAppDiedLocked(app, false, true);
6096 updateOomAdjLocked();
6099 doLowMemReportIfNeededLocked(app);
6101 } else if (app.pid != pid) {
6102 // A new process has already been started.
6103 reportUidInfoMessageLocked(TAG,
6104 "Process " + app.processName + " (pid " + pid
6105 + ") has died and restarted (pid " + app.pid + ").", app.info.uid);
6106 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
6107 } else if (DEBUG_PROCESSES) {
6108 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
6109 + thread.asBinder());
6112 // On the device which doesn't have Cgroup, log LmkStateChanged which is used as a signal
6113 // for pulling memory stats of other running processes when this process died.
6115 StatsLog.write(StatsLog.APP_DIED, SystemClock.elapsedRealtime());
6120 * If a stack trace dump file is configured, dump process stack traces.
6121 * @param clearTraces causes the dump file to be erased prior to the new
6122 * traces being written, if true; when false, the new traces will be
6123 * appended to any existing file content.
6124 * @param firstPids of dalvik VM processes to dump stack traces for first
6125 * @param lastPids of dalvik VM processes to dump stack traces for last
6126 * @param nativePids optional list of native pids to dump stack crawls
6128 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
6129 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
6130 ArrayList<Integer> nativePids) {
6131 ArrayList<Integer> extraPids = null;
6133 // Measure CPU usage as soon as we're called in order to get a realistic sampling
6134 // of the top users at the time of the request.
6135 if (processCpuTracker != null) {
6136 processCpuTracker.init();
6139 } catch (InterruptedException ignored) {
6142 processCpuTracker.update();
6144 // We'll take the stack crawls of just the top apps using CPU.
6145 final int N = processCpuTracker.countWorkingStats();
6146 extraPids = new ArrayList<>();
6147 for (int i = 0; i < N && extraPids.size() < 5; i++) {
6148 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
6149 if (lastPids.indexOfKey(stats.pid) >= 0) {
6150 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
6152 extraPids.add(stats.pid);
6153 } else if (DEBUG_ANR) {
6154 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
6160 boolean useTombstonedForJavaTraces = false;
6163 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
6164 if (tracesDirProp.isEmpty()) {
6165 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
6166 // dumping scheme. All traces are written to a global trace file (usually
6167 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
6168 // the file if requested.
6170 // This mode of operation will be removed in the near future.
6173 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6174 if (globalTracesPath.isEmpty()) {
6175 Slog.w(TAG, "dumpStackTraces: no trace path configured");
6179 tracesFile = new File(globalTracesPath);
6181 if (clearTraces && tracesFile.exists()) {
6182 tracesFile.delete();
6185 tracesFile.createNewFile();
6186 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
6187 } catch (IOException e) {
6188 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
6192 File tracesDir = new File(tracesDirProp);
6193 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
6194 // Each set of ANR traces is written to a separate file and dumpstate will process
6195 // all such files and add them to a captured bug report if they're recent enough.
6196 maybePruneOldTraces(tracesDir);
6198 // NOTE: We should consider creating the file in native code atomically once we've
6199 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
6201 tracesFile = createAnrDumpFile(tracesDir);
6202 if (tracesFile == null) {
6206 useTombstonedForJavaTraces = true;
6209 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
6210 useTombstonedForJavaTraces);
6214 @GuardedBy("ActivityManagerService.class")
6215 private static SimpleDateFormat sAnrFileDateFormat;
6217 private static synchronized File createAnrDumpFile(File tracesDir) {
6218 if (sAnrFileDateFormat == null) {
6219 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
6222 final String formattedDate = sAnrFileDateFormat.format(new Date());
6223 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
6226 if (anrFile.createNewFile()) {
6227 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
6230 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
6232 } catch (IOException ioe) {
6233 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
6240 * Prune all trace files that are more than a day old.
6242 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
6243 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
6244 * since it's the system_server that creates trace files for most ANRs.
6246 private static void maybePruneOldTraces(File tracesDir) {
6247 final long now = System.currentTimeMillis();
6248 final File[] traceFiles = tracesDir.listFiles();
6250 if (traceFiles != null) {
6251 for (File file : traceFiles) {
6252 if ((now - file.lastModified()) > DAY_IN_MILLIS) {
6253 if (!file.delete()) {
6254 Slog.w(TAG, "Unable to prune stale trace file: " + file);
6262 * Legacy code, do not use. Existing users will be deleted.
6267 public static class DumpStackFileObserver extends FileObserver {
6268 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
6269 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
6271 private final String mTracesPath;
6272 private boolean mClosed;
6274 public DumpStackFileObserver(String tracesPath) {
6275 super(tracesPath, FileObserver.CLOSE_WRITE);
6276 mTracesPath = tracesPath;
6280 public synchronized void onEvent(int event, String path) {
6285 public long dumpWithTimeout(int pid, long timeout) {
6286 sendSignal(pid, SIGNAL_QUIT);
6287 final long start = SystemClock.elapsedRealtime();
6289 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6290 synchronized (this) {
6292 wait(waitTime); // Wait for traces file to be closed.
6293 } catch (InterruptedException e) {
6298 // This avoids a corner case of passing a negative time to the native
6299 // trace in case we've already hit the overall timeout.
6300 final long timeWaited = SystemClock.elapsedRealtime() - start;
6301 if (timeWaited >= timeout) {
6306 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6307 ". Attempting native stack collection.");
6309 final long nativeDumpTimeoutMs = Math.min(
6310 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6312 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6313 (int) (nativeDumpTimeoutMs / 1000));
6316 final long end = SystemClock.elapsedRealtime();
6319 return (end - start);
6324 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6325 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6326 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6327 * attempting to obtain native traces in the case of a failure. Returns the total time spent
6330 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6331 final long timeStart = SystemClock.elapsedRealtime();
6332 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6333 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6334 (NATIVE_DUMP_TIMEOUT_MS / 1000));
6337 return SystemClock.elapsedRealtime() - timeStart;
6340 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6341 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6342 boolean useTombstonedForJavaTraces) {
6344 // We don't need any sort of inotify based monitoring when we're dumping traces via
6345 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6346 // control of all writes to the file in question.
6347 final DumpStackFileObserver observer;
6348 if (useTombstonedForJavaTraces) {
6351 // Use a FileObserver to detect when traces finish writing.
6352 // The order of traces is considered important to maintain for legibility.
6353 observer = new DumpStackFileObserver(tracesFile);
6356 // We must complete all stack dumps within 20 seconds.
6357 long remainingTime = 20 * 1000;
6359 if (observer != null) {
6360 observer.startWatching();
6363 // First collect all of the stacks of the most important pids.
6364 if (firstPids != null) {
6365 int num = firstPids.size();
6366 for (int i = 0; i < num; i++) {
6367 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6368 + firstPids.get(i));
6369 final long timeTaken;
6370 if (useTombstonedForJavaTraces) {
6371 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6373 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6376 remainingTime -= timeTaken;
6377 if (remainingTime <= 0) {
6378 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6379 "); deadline exceeded.");
6384 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6389 // Next collect the stacks of the native pids
6390 if (nativePids != null) {
6391 for (int pid : nativePids) {
6392 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6393 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6395 final long start = SystemClock.elapsedRealtime();
6396 Debug.dumpNativeBacktraceToFileTimeout(
6397 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6398 final long timeTaken = SystemClock.elapsedRealtime() - start;
6400 remainingTime -= timeTaken;
6401 if (remainingTime <= 0) {
6402 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6403 "); deadline exceeded.");
6408 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6413 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6414 if (extraPids != null) {
6415 for (int pid : extraPids) {
6416 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6418 final long timeTaken;
6419 if (useTombstonedForJavaTraces) {
6420 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6422 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6425 remainingTime -= timeTaken;
6426 if (remainingTime <= 0) {
6427 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6428 "); deadline exceeded.");
6433 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6438 if (observer != null) {
6439 observer.stopWatching();
6444 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6445 if (true || Build.IS_USER) {
6448 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6449 if (tracesPath == null || tracesPath.length() == 0) {
6453 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6454 StrictMode.allowThreadDiskWrites();
6456 final File tracesFile = new File(tracesPath);
6457 final File tracesDir = tracesFile.getParentFile();
6458 final File tracesTmp = new File(tracesDir, "__tmp__");
6460 if (tracesFile.exists()) {
6462 tracesFile.renameTo(tracesTmp);
6464 StringBuilder sb = new StringBuilder();
6465 Time tobj = new Time();
6466 tobj.set(System.currentTimeMillis());
6467 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6469 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6470 sb.append(" since ");
6472 FileOutputStream fos = new FileOutputStream(tracesFile);
6473 fos.write(sb.toString().getBytes());
6475 fos.write("\n*** No application process!".getBytes());
6478 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6479 } catch (IOException e) {
6480 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6484 if (app != null && app.pid > 0) {
6485 ArrayList<Integer> firstPids = new ArrayList<Integer>();
6486 firstPids.add(app.pid);
6487 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6490 File lastTracesFile = null;
6491 File curTracesFile = null;
6492 for (int i=9; i>=0; i--) {
6493 String name = String.format(Locale.US, "slow%02d.txt", i);
6494 curTracesFile = new File(tracesDir, name);
6495 if (curTracesFile.exists()) {
6496 if (lastTracesFile != null) {
6497 curTracesFile.renameTo(lastTracesFile);
6499 curTracesFile.delete();
6502 lastTracesFile = curTracesFile;
6504 tracesFile.renameTo(curTracesFile);
6505 if (tracesTmp.exists()) {
6506 tracesTmp.renameTo(tracesFile);
6509 StrictMode.setThreadPolicy(oldPolicy);
6514 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6515 if (!mLaunchWarningShown) {
6516 mLaunchWarningShown = true;
6517 mUiHandler.post(new Runnable() {
6520 synchronized (ActivityManagerService.this) {
6521 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6523 mUiHandler.postDelayed(new Runnable() {
6526 synchronized (ActivityManagerService.this) {
6528 mLaunchWarningShown = false;
6539 public boolean clearApplicationUserData(final String packageName, boolean keepState,
6540 final IPackageDataObserver observer, int userId) {
6541 enforceNotIsolatedCaller("clearApplicationUserData");
6542 int uid = Binder.getCallingUid();
6543 int pid = Binder.getCallingPid();
6544 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6545 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6547 final ApplicationInfo appInfo;
6548 final boolean isInstantApp;
6550 long callingId = Binder.clearCallingIdentity();
6552 IPackageManager pm = AppGlobals.getPackageManager();
6553 synchronized(this) {
6554 // Instant packages are not protected
6555 if (getPackageManagerInternalLocked().isPackageDataProtected(
6556 resolvedUserId, packageName)) {
6557 throw new SecurityException(
6558 "Cannot clear data for a protected package: " + packageName);
6561 ApplicationInfo applicationInfo = null;
6563 applicationInfo = pm.getApplicationInfo(packageName,
6564 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6565 } catch (RemoteException e) {
6568 appInfo = applicationInfo;
6570 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6572 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6573 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6574 throw new SecurityException("PID " + pid + " does not have permission "
6575 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6576 + " of package " + packageName);
6579 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6580 .hasInstantApplicationMetadata(packageName, resolvedUserId);
6581 final boolean isUninstalledAppWithoutInstantMetadata =
6582 (appInfo == null && !hasInstantMetadata);
6583 isInstantApp = (appInfo != null && appInfo.isInstantApp())
6584 || hasInstantMetadata;
6585 final boolean canAccessInstantApps = checkComponentPermission(
6586 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6587 == PackageManager.PERMISSION_GRANTED;
6589 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6590 && !canAccessInstantApps)) {
6591 Slog.w(TAG, "Invalid packageName: " + packageName);
6592 if (observer != null) {
6594 observer.onRemoveCompleted(packageName, false);
6595 } catch (RemoteException e) {
6596 Slog.i(TAG, "Observer no longer exists.");
6602 if (appInfo != null) {
6603 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6604 mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6608 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6610 public void onRemoveCompleted(String packageName, boolean succeeded)
6611 throws RemoteException {
6612 if (appInfo != null) {
6613 synchronized (ActivityManagerService.this) {
6614 finishForceStopPackageLocked(packageName, appInfo.uid);
6617 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6618 Uri.fromParts("package", packageName, null));
6619 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6620 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6621 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6623 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6624 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6625 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6628 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6629 null, null, null, null, false, false, resolvedUserId);
6632 if (observer != null) {
6633 observer.onRemoveCompleted(packageName, succeeded);
6639 // Clear application user data
6640 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6642 if (appInfo != null) {
6643 // Restore already established notification state and permission grants,
6644 // so it told us to keep those intact -- it's about to emplace app data
6645 // that is appropriate for those bits of system state.
6647 synchronized (this) {
6648 // Remove all permissions granted from/to this package
6649 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6653 // Reset notification state
6654 INotificationManager inm = NotificationManager.getService();
6655 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6658 // Clear its scheduled jobs
6659 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6660 js.cancelJobsForUid(appInfo.uid, "clear data");
6662 // Clear its pending alarms
6663 AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6664 ami.removeAlarmsForUid(appInfo.uid);
6666 } catch (RemoteException e) {
6669 Binder.restoreCallingIdentity(callingId);
6675 public void killBackgroundProcesses(final String packageName, int userId) {
6676 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6677 != PackageManager.PERMISSION_GRANTED &&
6678 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6679 != PackageManager.PERMISSION_GRANTED) {
6680 String msg = "Permission Denial: killBackgroundProcesses() from pid="
6681 + Binder.getCallingPid()
6682 + ", uid=" + Binder.getCallingUid()
6683 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6685 throw new SecurityException(msg);
6688 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6689 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6690 final int[] userIds = mUserController.expandUserId(userId);
6692 long callingId = Binder.clearCallingIdentity();
6694 IPackageManager pm = AppGlobals.getPackageManager();
6695 for (int targetUserId : userIds) {
6698 appId = UserHandle.getAppId(
6699 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6701 } catch (RemoteException e) {
6704 Slog.w(TAG, "Invalid packageName: " + packageName);
6707 synchronized (this) {
6708 killPackageProcessesLocked(packageName, appId, targetUserId,
6709 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6713 Binder.restoreCallingIdentity(callingId);
6718 public void killAllBackgroundProcesses() {
6719 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6720 != PackageManager.PERMISSION_GRANTED) {
6721 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6722 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6723 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6725 throw new SecurityException(msg);
6728 final long callingId = Binder.clearCallingIdentity();
6730 synchronized (this) {
6731 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6732 final int NP = mProcessNames.getMap().size();
6733 for (int ip = 0; ip < NP; ip++) {
6734 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6735 final int NA = apps.size();
6736 for (int ia = 0; ia < NA; ia++) {
6737 final ProcessRecord app = apps.valueAt(ia);
6738 if (app.persistent) {
6739 // We don't kill persistent processes.
6744 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6751 final int N = procs.size();
6752 for (int i = 0; i < N; i++) {
6753 removeProcessLocked(procs.get(i), false, true, "kill all background");
6756 mAllowLowerMemLevel = true;
6758 updateOomAdjLocked();
6759 doLowMemReportIfNeededLocked(null);
6762 Binder.restoreCallingIdentity(callingId);
6767 * Kills all background processes, except those matching any of the
6768 * specified properties.
6770 * @param minTargetSdk the target SDK version at or above which to preserve
6771 * processes, or {@code -1} to ignore the target SDK
6772 * @param maxProcState the process state at or below which to preserve
6773 * processes, or {@code -1} to ignore the process state
6775 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6776 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6777 != PackageManager.PERMISSION_GRANTED) {
6778 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6779 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6780 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6782 throw new SecurityException(msg);
6785 final long callingId = Binder.clearCallingIdentity();
6787 synchronized (this) {
6788 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6789 final int NP = mProcessNames.getMap().size();
6790 for (int ip = 0; ip < NP; ip++) {
6791 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6792 final int NA = apps.size();
6793 for (int ia = 0; ia < NA; ia++) {
6794 final ProcessRecord app = apps.valueAt(ia);
6797 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6798 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6805 final int N = procs.size();
6806 for (int i = 0; i < N; i++) {
6807 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6811 Binder.restoreCallingIdentity(callingId);
6816 public void forceStopPackage(final String packageName, int userId) {
6817 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6818 != PackageManager.PERMISSION_GRANTED) {
6819 String msg = "Permission Denial: forceStopPackage() from pid="
6820 + Binder.getCallingPid()
6821 + ", uid=" + Binder.getCallingUid()
6822 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6824 throw new SecurityException(msg);
6826 final int callingPid = Binder.getCallingPid();
6827 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6828 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6829 long callingId = Binder.clearCallingIdentity();
6831 IPackageManager pm = AppGlobals.getPackageManager();
6832 synchronized(this) {
6833 int[] users = userId == UserHandle.USER_ALL
6834 ? mUserController.getUsers() : new int[] { userId };
6835 for (int user : users) {
6836 if (getPackageManagerInternalLocked().isPackageStateProtected(
6837 packageName, user)) {
6838 Slog.w(TAG, "Ignoring request to force stop protected package "
6839 + packageName + " u" + user);
6845 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6847 } catch (RemoteException e) {
6850 Slog.w(TAG, "Invalid packageName: " + packageName);
6854 pm.setPackageStoppedState(packageName, true, user);
6855 } catch (RemoteException e) {
6856 } catch (IllegalArgumentException e) {
6857 Slog.w(TAG, "Failed trying to unstop package "
6858 + packageName + ": " + e);
6860 if (mUserController.isUserRunning(user, 0)) {
6861 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6862 finishForceStopPackageLocked(packageName, pkgUid);
6867 Binder.restoreCallingIdentity(callingId);
6872 public void addPackageDependency(String packageName) {
6873 synchronized (this) {
6874 int callingPid = Binder.getCallingPid();
6875 if (callingPid == myPid()) {
6880 synchronized (mPidsSelfLocked) {
6881 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6884 if (proc.pkgDeps == null) {
6885 proc.pkgDeps = new ArraySet<String>(1);
6887 proc.pkgDeps.add(packageName);
6893 * The pkg name and app id have to be specified.
6896 public void killApplication(String pkg, int appId, int userId, String reason) {
6900 // Make sure the uid is valid.
6902 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6905 int callerUid = Binder.getCallingUid();
6906 // Only the system server can kill an application
6907 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6908 // Post an aysnc message to kill the application
6909 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6912 Bundle bundle = new Bundle();
6913 bundle.putString("pkg", pkg);
6914 bundle.putString("reason", reason);
6916 mHandler.sendMessage(msg);
6918 throw new SecurityException(callerUid + " cannot kill pkg: " +
6924 public void closeSystemDialogs(String reason) {
6925 enforceNotIsolatedCaller("closeSystemDialogs");
6927 final int pid = Binder.getCallingPid();
6928 final int uid = Binder.getCallingUid();
6929 final long origId = Binder.clearCallingIdentity();
6931 synchronized (this) {
6932 // Only allow this from foreground processes, so that background
6933 // applications can't abuse it to prevent system UI from being shown.
6934 if (uid >= FIRST_APPLICATION_UID) {
6936 synchronized (mPidsSelfLocked) {
6937 proc = mPidsSelfLocked.get(pid);
6939 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6940 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6941 + " from background process " + proc);
6945 closeSystemDialogsLocked(reason);
6948 Binder.restoreCallingIdentity(origId);
6953 void closeSystemDialogsLocked(String reason) {
6954 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6955 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6956 | Intent.FLAG_RECEIVER_FOREGROUND);
6957 if (reason != null) {
6958 intent.putExtra("reason", reason);
6960 mWindowManager.closeSystemDialogs(reason);
6962 mStackSupervisor.closeSystemDialogsLocked();
6964 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6965 OP_NONE, null, false, false,
6966 -1, SYSTEM_UID, UserHandle.USER_ALL);
6970 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6971 enforceNotIsolatedCaller("getProcessMemoryInfo");
6972 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6973 for (int i=pids.length-1; i>=0; i--) {
6976 synchronized (this) {
6977 synchronized (mPidsSelfLocked) {
6978 proc = mPidsSelfLocked.get(pids[i]);
6979 oomAdj = proc != null ? proc.setAdj : 0;
6982 infos[i] = new Debug.MemoryInfo();
6983 long startTime = SystemClock.currentThreadTimeMillis();
6984 Debug.getMemoryInfo(pids[i], infos[i]);
6985 long endTime = SystemClock.currentThreadTimeMillis();
6987 synchronized (this) {
6988 if (proc.thread != null && proc.setAdj == oomAdj) {
6989 // Record this for posterity if the process has been stable.
6990 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6991 infos[i].getTotalUss(), infos[i].getTotalRss(), false,
6992 ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
7002 public long[] getProcessPss(int[] pids) {
7003 enforceNotIsolatedCaller("getProcessPss");
7004 long[] pss = new long[pids.length];
7005 for (int i=pids.length-1; i>=0; i--) {
7008 synchronized (this) {
7009 synchronized (mPidsSelfLocked) {
7010 proc = mPidsSelfLocked.get(pids[i]);
7011 oomAdj = proc != null ? proc.setAdj : 0;
7014 long[] tmpUss = new long[3];
7015 long startTime = SystemClock.currentThreadTimeMillis();
7016 pss[i] = Debug.getPss(pids[i], tmpUss, null);
7017 long endTime = SystemClock.currentThreadTimeMillis();
7019 synchronized (this) {
7020 if (proc.thread != null && proc.setAdj == oomAdj) {
7021 // Record this for posterity if the process has been stable.
7022 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
7023 ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
7032 public void killApplicationProcess(String processName, int uid) {
7033 if (processName == null) {
7037 int callerUid = Binder.getCallingUid();
7038 // Only the system server can kill an application
7039 if (callerUid == SYSTEM_UID) {
7040 synchronized (this) {
7041 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
7042 if (app != null && app.thread != null) {
7044 app.thread.scheduleSuicide();
7045 } catch (RemoteException e) {
7046 // If the other end already died, then our work here is done.
7049 Slog.w(TAG, "Process/uid not found attempting kill of "
7050 + processName + " / " + uid);
7054 throw new SecurityException(callerUid + " cannot kill app process: " +
7060 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
7061 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
7062 false, true, false, false, UserHandle.getUserId(uid), reason);
7066 private void finishForceStopPackageLocked(final String packageName, int uid) {
7067 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
7068 Uri.fromParts("package", packageName, null));
7069 if (!mProcessesReady) {
7070 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7071 | Intent.FLAG_RECEIVER_FOREGROUND);
7073 intent.putExtra(Intent.EXTRA_UID, uid);
7074 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
7075 broadcastIntentLocked(null, null, intent,
7076 null, null, 0, null, null, null, OP_NONE,
7077 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
7082 private final boolean killPackageProcessesLocked(String packageName, int appId,
7083 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
7084 boolean doit, boolean evenPersistent, String reason) {
7085 ArrayList<ProcessRecord> procs = new ArrayList<>();
7087 // Remove all processes this package may have touched: all with the
7088 // same UID (except for the system or root user), and all whose name
7089 // matches the package name.
7090 final int NP = mProcessNames.getMap().size();
7091 for (int ip=0; ip<NP; ip++) {
7092 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
7093 final int NA = apps.size();
7094 for (int ia=0; ia<NA; ia++) {
7095 ProcessRecord app = apps.valueAt(ia);
7096 if (app.persistent && !evenPersistent) {
7097 // we don't kill persistent processes
7107 // Skip process if it doesn't meet our oom adj requirement.
7108 if (app.setAdj < minOomAdj) {
7112 // If no package is specified, we call all processes under the
7114 if (packageName == null) {
7115 if (userId != UserHandle.USER_ALL && app.userId != userId) {
7118 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
7121 // Package has been specified, we want to hit all processes
7122 // that match it. We need to qualify this by the processes
7123 // that are running under the specified app and user ID.
7125 final boolean isDep = app.pkgDeps != null
7126 && app.pkgDeps.contains(packageName);
7127 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
7130 if (userId != UserHandle.USER_ALL && app.userId != userId) {
7133 if (!app.pkgList.containsKey(packageName) && !isDep) {
7138 // Process has passed all conditions, kill it!
7147 int N = procs.size();
7148 for (int i=0; i<N; i++) {
7149 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
7151 updateOomAdjLocked();
7155 private void cleanupDisabledPackageComponentsLocked(
7156 String packageName, int userId, boolean killProcess, String[] changedClasses) {
7158 Set<String> disabledClasses = null;
7159 boolean packageDisabled = false;
7160 IPackageManager pm = AppGlobals.getPackageManager();
7162 if (changedClasses == null) {
7163 // Nothing changed...
7167 // Determine enable/disable state of the package and its components.
7168 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7169 for (int i = changedClasses.length - 1; i >= 0; i--) {
7170 final String changedClass = changedClasses[i];
7172 if (changedClass.equals(packageName)) {
7174 // Entire package setting changed
7175 enabled = pm.getApplicationEnabledSetting(packageName,
7176 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7177 } catch (Exception e) {
7178 // No such package/component; probably racing with uninstall. In any
7179 // event it means we have nothing further to do here.
7182 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7183 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7184 if (packageDisabled) {
7185 // Entire package is disabled.
7186 // No need to continue to check component states.
7187 disabledClasses = null;
7192 enabled = pm.getComponentEnabledSetting(
7193 new ComponentName(packageName, changedClass),
7194 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7195 } catch (Exception e) {
7196 // As above, probably racing with uninstall.
7199 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7200 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
7201 if (disabledClasses == null) {
7202 disabledClasses = new ArraySet<>(changedClasses.length);
7204 disabledClasses.add(changedClass);
7209 if (!packageDisabled && disabledClasses == null) {
7210 // Nothing to do here...
7214 // Clean-up disabled activities.
7215 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7216 packageName, disabledClasses, true, false, userId) && mBooted) {
7217 mStackSupervisor.resumeFocusedStackTopActivityLocked();
7218 mStackSupervisor.scheduleIdleLocked();
7221 // Clean-up disabled tasks
7222 mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
7224 // Clean-up disabled services.
7225 mServices.bringDownDisabledPackageServicesLocked(
7226 packageName, disabledClasses, userId, false, killProcess, true);
7228 // Clean-up disabled providers.
7229 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7230 mProviderMap.collectPackageProvidersLocked(
7231 packageName, disabledClasses, true, false, userId, providers);
7232 for (int i = providers.size() - 1; i >= 0; i--) {
7233 removeDyingProviderLocked(null, providers.get(i), true);
7236 // Clean-up disabled broadcast receivers.
7237 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7238 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7239 packageName, disabledClasses, userId, true);
7244 final boolean clearBroadcastQueueForUserLocked(int userId) {
7245 boolean didSomething = false;
7246 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7247 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7248 null, null, userId, true);
7250 return didSomething;
7254 final boolean forceStopPackageLocked(String packageName, int appId,
7255 boolean callerWillRestart, boolean purgeCache, boolean doit,
7256 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
7259 if (userId == UserHandle.USER_ALL && packageName == null) {
7260 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
7263 if (appId < 0 && packageName != null) {
7265 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
7266 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
7267 } catch (RemoteException e) {
7272 if (packageName != null) {
7273 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
7274 + " user=" + userId + ": " + reason);
7276 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
7279 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
7282 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
7283 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
7284 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
7286 didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
7288 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7289 packageName, null, doit, evenPersistent, userId)) {
7293 didSomething = true;
7296 if (mServices.bringDownDisabledPackageServicesLocked(
7297 packageName, null, userId, evenPersistent, true, doit)) {
7301 didSomething = true;
7304 if (packageName == null) {
7305 // Remove all sticky broadcasts from this user.
7306 mStickyBroadcasts.remove(userId);
7309 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7310 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7311 userId, providers)) {
7315 didSomething = true;
7317 for (i = providers.size() - 1; i >= 0; i--) {
7318 removeDyingProviderLocked(null, providers.get(i), true);
7321 // Remove transient permissions granted from/to this package/user
7322 removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7325 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7326 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7327 packageName, null, userId, doit);
7331 if (packageName == null || uninstalling) {
7332 // Remove pending intents. For now we only do this when force
7333 // stopping users, because we have some problems when doing this
7334 // for packages -- app widgets are not currently cleaned up for
7335 // such packages, so they can be left with bad pending intents.
7336 if (mIntentSenderRecords.size() > 0) {
7337 Iterator<WeakReference<PendingIntentRecord>> it
7338 = mIntentSenderRecords.values().iterator();
7339 while (it.hasNext()) {
7340 WeakReference<PendingIntentRecord> wpir = it.next();
7345 PendingIntentRecord pir = wpir.get();
7350 if (packageName == null) {
7351 // Stopping user, remove all objects for the user.
7352 if (pir.key.userId != userId) {
7353 // Not the same user, skip it.
7357 if (UserHandle.getAppId(pir.uid) != appId) {
7358 // Different app id, skip it.
7361 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7362 // Different user, skip it.
7365 if (!pir.key.packageName.equals(packageName)) {
7366 // Different package, skip it.
7373 didSomething = true;
7375 makeIntentSenderCanceledLocked(pir);
7376 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7377 pir.key.activity.pendingResults.remove(pir.ref);
7384 if (purgeCache && packageName != null) {
7385 AttributeCache ac = AttributeCache.instance();
7387 ac.removePackage(packageName);
7391 mStackSupervisor.resumeFocusedStackTopActivityLocked();
7392 mStackSupervisor.scheduleIdleLocked();
7396 return didSomething;
7399 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7400 return removeProcessNameLocked(name, uid, null);
7403 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7404 final ProcessRecord expecting) {
7405 ProcessRecord old = mProcessNames.get(name, uid);
7406 // Only actually remove when the currently recorded value matches the
7407 // record that we expected; if it doesn't match then we raced with a
7408 // newly created process and we don't want to destroy the new one.
7409 if ((expecting == null) || (old == expecting)) {
7410 mProcessNames.remove(name, uid);
7412 if (old != null && old.uidRecord != null) {
7413 old.uidRecord.numProcs--;
7414 if (old.uidRecord.numProcs == 0) {
7415 // No more processes using this uid, tell clients it is gone.
7416 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7417 "No more processes in " + old.uidRecord);
7418 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7419 EventLogTags.writeAmUidStopped(uid);
7420 mActiveUids.remove(uid);
7421 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7423 old.uidRecord = null;
7425 mIsolatedProcesses.remove(uid);
7429 private final void addProcessNameLocked(ProcessRecord proc) {
7430 // We shouldn't already have a process under this name, but just in case we
7431 // need to clean up whatever may be there now.
7432 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7433 if (old == proc && proc.persistent) {
7434 // We are re-adding a persistent process. Whatevs! Just leave it there.
7435 Slog.w(TAG, "Re-adding persistent process " + proc);
7436 } else if (old != null) {
7437 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7439 UidRecord uidRec = mActiveUids.get(proc.uid);
7440 if (uidRec == null) {
7441 uidRec = new UidRecord(proc.uid);
7442 // This is the first appearance of the uid, report it now!
7443 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7444 "Creating new process uid: " + uidRec);
7445 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7446 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7447 uidRec.setWhitelist = uidRec.curWhitelist = true;
7449 uidRec.updateHasInternetPermission();
7450 mActiveUids.put(proc.uid, uidRec);
7451 EventLogTags.writeAmUidRunning(uidRec.uid);
7452 noteUidProcessState(uidRec.uid, uidRec.curProcState);
7454 proc.uidRecord = uidRec;
7456 // Reset render thread tid if it was already set, so new process can set it again.
7457 proc.renderThreadTid = 0;
7459 mProcessNames.put(proc.processName, proc.uid, proc);
7460 if (proc.isolated) {
7461 mIsolatedProcesses.put(proc.uid, proc);
7466 boolean removeProcessLocked(ProcessRecord app,
7467 boolean callerWillRestart, boolean allowRestart, String reason) {
7468 final String name = app.processName;
7469 final int uid = app.uid;
7470 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7471 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7473 ProcessRecord old = mProcessNames.get(name, uid);
7475 // This process is no longer active, so nothing to do.
7476 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7479 removeProcessNameLocked(name, uid);
7480 if (mHeavyWeightProcess == app) {
7481 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7482 mHeavyWeightProcess.userId, 0));
7483 mHeavyWeightProcess = null;
7485 boolean needRestart = false;
7486 if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7489 synchronized (mPidsSelfLocked) {
7490 mPidsSelfLocked.remove(pid);
7491 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7493 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7495 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7496 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7499 boolean willRestart = false;
7500 if (app.persistent && !app.isolated) {
7501 if (!callerWillRestart) {
7507 app.kill(reason, true);
7508 handleAppDiedLocked(app, willRestart, allowRestart);
7510 removeLruProcessLocked(app);
7511 addAppLocked(app.info, null, false, null /* ABI override */);
7514 mRemovedProcesses.add(app);
7521 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7522 cleanupAppInLaunchingProvidersLocked(app, true);
7523 removeProcessLocked(app, false, true, "timeout publishing content providers");
7526 private final void processStartTimedOutLocked(ProcessRecord app) {
7527 final int pid = app.pid;
7528 boolean gone = false;
7529 synchronized (mPidsSelfLocked) {
7530 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7531 if (knownApp != null && knownApp.thread == null) {
7532 mPidsSelfLocked.remove(pid);
7538 Slog.w(TAG, "Process " + app + " failed to attach");
7539 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7540 pid, app.uid, app.processName);
7541 removeProcessNameLocked(app.processName, app.uid);
7542 if (mHeavyWeightProcess == app) {
7543 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7544 mHeavyWeightProcess.userId, 0));
7545 mHeavyWeightProcess = null;
7547 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7548 // Take care of any launching providers waiting for this process.
7549 cleanupAppInLaunchingProvidersLocked(app, true);
7550 // Take care of any services that are waiting for the process.
7551 mServices.processStartTimedOutLocked(app);
7552 app.kill("start timeout", true);
7554 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7556 removeLruProcessLocked(app);
7557 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7558 Slog.w(TAG, "Unattached app died before backup, skipping");
7559 mHandler.post(new Runnable() {
7563 IBackupManager bm = IBackupManager.Stub.asInterface(
7564 ServiceManager.getService(Context.BACKUP_SERVICE));
7565 bm.agentDisconnected(app.info.packageName);
7566 } catch (RemoteException e) {
7567 // Can't happen; the backup manager is local
7572 if (isPendingBroadcastProcessLocked(pid)) {
7573 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7574 skipPendingBroadcastLocked(pid);
7577 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7582 private final boolean attachApplicationLocked(IApplicationThread thread,
7583 int pid, int callingUid, long startSeq) {
7585 // Find the application record that is being attached... either via
7586 // the pid if we are running in multiple processes, or just pull the
7587 // next app record if we are emulating process with anonymous threads.
7589 long startTime = SystemClock.uptimeMillis();
7590 if (pid != MY_PID && pid >= 0) {
7591 synchronized (mPidsSelfLocked) {
7592 app = mPidsSelfLocked.get(pid);
7598 // It's possible that process called attachApplication before we got a chance to
7599 // update the internal state.
7600 if (app == null && startSeq > 0) {
7601 final ProcessRecord pending = mPendingStarts.get(startSeq);
7602 if (pending != null && pending.startUid == callingUid
7603 && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7610 Slog.w(TAG, "No pending application record for pid " + pid
7611 + " (IApplicationThread " + thread + "); dropping process");
7612 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7613 if (pid > 0 && pid != MY_PID) {
7614 killProcessQuiet(pid);
7615 //TODO: killProcessGroup(app.info.uid, pid);
7618 thread.scheduleExit();
7619 } catch (Exception e) {
7620 // Ignore exceptions.
7626 // If this application record is still attached to a previous
7627 // process, clean it up now.
7628 if (app.thread != null) {
7629 handleAppDiedLocked(app, true, true);
7632 // Tell the process all about itself.
7634 if (DEBUG_ALL) Slog.v(
7635 TAG, "Binding process pid " + pid + " to record " + app);
7637 final String processName = app.processName;
7639 AppDeathRecipient adr = new AppDeathRecipient(
7641 thread.asBinder().linkToDeath(adr, 0);
7642 app.deathRecipient = adr;
7643 } catch (RemoteException e) {
7644 app.resetPackageList(mProcessStats);
7645 startProcessLocked(app, "link fail", processName);
7649 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7651 app.makeActive(thread, mProcessStats);
7652 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7653 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7654 app.forcingToImportant = null;
7655 updateProcessForegroundLocked(app, false, false);
7656 app.hasShownUi = false;
7657 app.debugging = false;
7659 app.killedByAm = false;
7663 // We carefully use the same state that PackageManager uses for
7664 // filtering, since we use this flag to decide if we need to install
7665 // providers when user is unlocked later
7666 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7668 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7670 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7671 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7673 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7674 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7676 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7679 checkTime(startTime, "attachApplicationLocked: before bindApplication");
7682 Slog.i(TAG, "Launching preboot mode app: " + app);
7685 if (DEBUG_ALL) Slog.v(
7686 TAG, "New app record " + app
7687 + " thread=" + thread.asBinder() + " pid=" + pid);
7689 int testMode = ApplicationThreadConstants.DEBUG_OFF;
7690 if (mDebugApp != null && mDebugApp.equals(processName)) {
7691 testMode = mWaitForDebugger
7692 ? ApplicationThreadConstants.DEBUG_WAIT
7693 : ApplicationThreadConstants.DEBUG_ON;
7694 app.debugging = true;
7695 if (mDebugTransient) {
7696 mDebugApp = mOrigDebugApp;
7697 mWaitForDebugger = mOrigWaitForDebugger;
7701 boolean enableTrackAllocation = false;
7702 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7703 enableTrackAllocation = true;
7704 mTrackAllocationApp = null;
7707 // If the app is being launched for restore or full backup, set it up specially
7708 boolean isRestrictedBackupMode = false;
7709 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7710 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7711 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7712 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7713 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7716 if (app.instr != null) {
7717 notifyPackageUse(app.instr.mClass.getPackageName(),
7718 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7720 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7721 + processName + " with config " + getGlobalConfiguration());
7722 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7723 app.compat = compatibilityInfoForPackageLocked(appInfo);
7725 ProfilerInfo profilerInfo = null;
7726 String preBindAgent = null;
7727 if (mProfileApp != null && mProfileApp.equals(processName)) {
7729 if (mProfilerInfo != null) {
7730 // Send a profiler info object to the app if either a file is given, or
7731 // an agent should be loaded at bind-time.
7732 boolean needsInfo = mProfilerInfo.profileFile != null
7733 || mProfilerInfo.attachAgentDuringBind;
7734 profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7735 if (mProfilerInfo.agent != null) {
7736 preBindAgent = mProfilerInfo.agent;
7739 } else if (app.instr != null && app.instr.mProfileFile != null) {
7740 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7743 if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7744 // We need to do a debuggable check here. See setAgentApp for why the check is
7745 // postponed to here.
7746 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7747 String agent = mAppAgentMap.get(processName);
7748 // Do not overwrite already requested agent.
7749 if (profilerInfo == null) {
7750 profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7751 mAppAgentMap.get(processName), true);
7752 } else if (profilerInfo.agent == null) {
7753 profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7758 if (profilerInfo != null && profilerInfo.profileFd != null) {
7759 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7760 if (TextUtils.equals(mProfileApp, processName) && mProfilerInfo != null) {
7761 clearProfilerLocked();
7765 // We deprecated Build.SERIAL and it is not accessible to
7766 // apps that target the v2 security sandbox and to apps that
7767 // target APIs higher than O MR1. Since access to the serial
7768 // is now behind a permission we push down the value.
7769 final String buildSerial = (appInfo.targetSandboxVersion < 2
7770 && appInfo.targetSdkVersion < Build.VERSION_CODES.P)
7771 ? sTheRealBuildSerial : Build.UNKNOWN;
7773 // Check if this is a secondary process that should be incorporated into some
7774 // currently active instrumentation. (Note we do this AFTER all of the profiling
7775 // stuff above because profiling can currently happen only in the primary
7776 // instrumentation process.)
7777 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7778 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7779 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7780 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7781 if (aInstr.mTargetProcesses.length == 0) {
7782 // This is the wildcard mode, where every process brought up for
7783 // the target instrumentation should be included.
7784 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7786 aInstr.mRunningProcesses.add(app);
7789 for (String proc : aInstr.mTargetProcesses) {
7790 if (proc.equals(app.processName)) {
7792 aInstr.mRunningProcesses.add(app);
7801 // If we were asked to attach an agent on startup, do so now, before we're binding
7802 // application code.
7803 if (preBindAgent != null) {
7804 thread.attachAgent(preBindAgent);
7808 // Figure out whether the app needs to run in autofill compat mode.
7809 boolean isAutofillCompatEnabled = false;
7810 if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
7811 final AutofillManagerInternal afm = LocalServices.getService(
7812 AutofillManagerInternal.class);
7814 isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7815 app.info.packageName, app.info.versionCode, app.userId);
7819 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7820 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7821 if (app.isolatedEntryPoint != null) {
7822 // This is an isolated process which should just call an entry point instead of
7823 // being bound to an application.
7824 thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7825 } else if (app.instr != null) {
7826 thread.bindApplication(processName, appInfo, providers,
7828 profilerInfo, app.instr.mArguments,
7830 app.instr.mUiAutomationConnection, testMode,
7831 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7832 isRestrictedBackupMode || !normalMode, app.persistent,
7833 new Configuration(getGlobalConfiguration()), app.compat,
7834 getCommonServicesLocked(app.isolated),
7835 mCoreSettingsObserver.getCoreSettingsLocked(),
7836 buildSerial, isAutofillCompatEnabled);
7838 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7839 null, null, null, testMode,
7840 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7841 isRestrictedBackupMode || !normalMode, app.persistent,
7842 new Configuration(getGlobalConfiguration()), app.compat,
7843 getCommonServicesLocked(app.isolated),
7844 mCoreSettingsObserver.getCoreSettingsLocked(),
7845 buildSerial, isAutofillCompatEnabled);
7847 if (profilerInfo != null) {
7848 profilerInfo.closeFd();
7849 profilerInfo = null;
7851 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7852 updateLruProcessLocked(app, false, null);
7853 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7854 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7855 } catch (Exception e) {
7856 // todo: Yikes! What should we do? For now we will try to
7857 // start another process, but that could easily get us in
7858 // an infinite loop of restarting processes...
7859 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7861 app.resetPackageList(mProcessStats);
7862 app.unlinkDeathRecipient();
7863 startProcessLocked(app, "bind fail", processName);
7867 // Remove this record from the list of starting applications.
7868 mPersistentStartingProcesses.remove(app);
7869 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7870 "Attach application locked removing on hold: " + app);
7871 mProcessesOnHold.remove(app);
7873 boolean badApp = false;
7874 boolean didSomething = false;
7876 // See if the top visible activity is waiting to run in this process...
7879 if (mStackSupervisor.attachApplicationLocked(app)) {
7880 didSomething = true;
7882 } catch (Exception e) {
7883 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7888 // Find any services that should be running in this process...
7891 didSomething |= mServices.attachApplicationLocked(app, processName);
7892 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7893 } catch (Exception e) {
7894 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7899 // Check if a next-broadcast receiver is in this process...
7900 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7902 didSomething |= sendPendingBroadcastsLocked(app);
7903 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7904 } catch (Exception e) {
7905 // If the app died trying to launch the receiver we declare it 'bad'
7906 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7911 // Check whether the next backup agent is in this process...
7912 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7913 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7914 "New app is backup target, launching agent for " + app);
7915 notifyPackageUse(mBackupTarget.appInfo.packageName,
7916 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7918 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7919 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7920 mBackupTarget.backupMode);
7921 } catch (Exception e) {
7922 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7928 app.kill("error during init", true);
7929 handleAppDiedLocked(app, false, true);
7933 if (!didSomething) {
7934 updateOomAdjLocked();
7935 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7942 public final void attachApplication(IApplicationThread thread, long startSeq) {
7943 synchronized (this) {
7944 int callingPid = Binder.getCallingPid();
7945 final int callingUid = Binder.getCallingUid();
7946 final long origId = Binder.clearCallingIdentity();
7947 attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7948 Binder.restoreCallingIdentity(origId);
7953 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7954 final long origId = Binder.clearCallingIdentity();
7955 synchronized (this) {
7956 ActivityStack stack = ActivityRecord.getStackLocked(token);
7957 if (stack != null) {
7959 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7960 false /* processPausingActivities */, config);
7961 if (stopProfiling) {
7962 if ((mProfileProc == r.app) && mProfilerInfo != null) {
7963 clearProfilerLocked();
7968 Binder.restoreCallingIdentity(origId);
7971 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7972 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7973 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7976 void enableScreenAfterBoot() {
7977 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7978 SystemClock.uptimeMillis());
7979 mWindowManager.enableScreenAfterBoot();
7981 synchronized (this) {
7982 updateEventDispatchingLocked();
7987 public void showBootMessage(final CharSequence msg, final boolean always) {
7988 if (Binder.getCallingUid() != myUid()) {
7989 throw new SecurityException();
7991 mWindowManager.showBootMessage(msg, always);
7995 public void keyguardGoingAway(int flags) {
7996 enforceNotIsolatedCaller("keyguardGoingAway");
7997 final long token = Binder.clearCallingIdentity();
7999 synchronized (this) {
8000 mKeyguardController.keyguardGoingAway(flags);
8003 Binder.restoreCallingIdentity(token);
8008 * @return whther the keyguard is currently locked.
8010 boolean isKeyguardLocked() {
8011 return mKeyguardController.isKeyguardLocked();
8014 final void finishBooting() {
8015 synchronized (this) {
8016 if (!mBootAnimationComplete) {
8017 mCallFinishBooting = true;
8020 mCallFinishBooting = false;
8023 ArraySet<String> completedIsas = new ArraySet<String>();
8024 for (String abi : Build.SUPPORTED_ABIS) {
8025 zygoteProcess.establishZygoteConnectionForAbi(abi);
8026 final String instructionSet = VMRuntime.getInstructionSet(abi);
8027 if (!completedIsas.contains(instructionSet)) {
8029 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
8030 } catch (InstallerException e) {
8031 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
8032 e.getMessage() +")");
8034 completedIsas.add(instructionSet);
8038 IntentFilter pkgFilter = new IntentFilter();
8039 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
8040 pkgFilter.addDataScheme("package");
8041 mContext.registerReceiver(new BroadcastReceiver() {
8043 public void onReceive(Context context, Intent intent) {
8044 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
8046 for (String pkg : pkgs) {
8047 synchronized (ActivityManagerService.this) {
8048 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
8049 0, "query restart")) {
8050 setResultCode(Activity.RESULT_OK);
8059 IntentFilter dumpheapFilter = new IntentFilter();
8060 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
8061 mContext.registerReceiver(new BroadcastReceiver() {
8063 public void onReceive(Context context, Intent intent) {
8064 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
8065 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
8067 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
8072 // Let system services know.
8073 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
8075 synchronized (this) {
8076 // Ensure that any processes we had put on hold are now started
8078 final int NP = mProcessesOnHold.size();
8080 ArrayList<ProcessRecord> procs =
8081 new ArrayList<ProcessRecord>(mProcessesOnHold);
8082 for (int ip=0; ip<NP; ip++) {
8083 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
8085 startProcessLocked(procs.get(ip), "on-hold", null);
8088 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
8091 // Start looking for apps that are abusing wake locks.
8092 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
8093 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
8094 // Tell anyone interested that we are done booting!
8095 SystemProperties.set("sys.boot_completed", "1");
8097 // And trigger dev.bootcomplete if we are not showing encryption progress
8098 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
8099 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
8100 SystemProperties.set("dev.bootcomplete", "1");
8102 mUserController.sendBootCompleted(
8103 new IIntentReceiver.Stub() {
8105 public void performReceive(Intent intent, int resultCode,
8106 String data, Bundle extras, boolean ordered,
8107 boolean sticky, int sendingUser) {
8108 synchronized (ActivityManagerService.this) {
8109 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
8113 mUserController.scheduleStartProfiles();
8118 public void bootAnimationComplete() {
8119 final boolean callFinishBooting;
8120 synchronized (this) {
8121 callFinishBooting = mCallFinishBooting;
8122 mBootAnimationComplete = true;
8124 if (callFinishBooting) {
8125 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8127 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8131 final void ensureBootCompleted() {
8133 boolean enableScreen;
8134 synchronized (this) {
8137 enableScreen = !mBooted;
8142 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8144 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8148 enableScreenAfterBoot();
8153 public final void activityResumed(IBinder token) {
8154 final long origId = Binder.clearCallingIdentity();
8155 synchronized(this) {
8156 ActivityRecord.activityResumedLocked(token);
8157 mWindowManager.notifyAppResumedFinished(token);
8159 Binder.restoreCallingIdentity(origId);
8163 public final void activityPaused(IBinder token) {
8164 final long origId = Binder.clearCallingIdentity();
8165 synchronized(this) {
8166 ActivityStack stack = ActivityRecord.getStackLocked(token);
8167 if (stack != null) {
8168 stack.activityPausedLocked(token, false);
8171 Binder.restoreCallingIdentity(origId);
8175 public final void activityStopped(IBinder token, Bundle icicle,
8176 PersistableBundle persistentState, CharSequence description) {
8177 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
8179 // Refuse possible leaked file descriptors
8180 if (icicle != null && icicle.hasFileDescriptors()) {
8181 throw new IllegalArgumentException("File descriptors passed in Bundle");
8184 final long origId = Binder.clearCallingIdentity();
8186 synchronized (this) {
8187 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8189 r.activityStoppedLocked(icicle, persistentState, description);
8195 Binder.restoreCallingIdentity(origId);
8199 public final void activityDestroyed(IBinder token) {
8200 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
8201 synchronized (this) {
8202 ActivityStack stack = ActivityRecord.getStackLocked(token);
8203 if (stack != null) {
8204 stack.activityDestroyedLocked(token, "activityDestroyed");
8210 public final void activityRelaunched(IBinder token) {
8211 final long origId = Binder.clearCallingIdentity();
8212 synchronized (this) {
8213 mStackSupervisor.activityRelaunchedLocked(token);
8215 Binder.restoreCallingIdentity(origId);
8219 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
8220 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
8221 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
8222 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
8223 synchronized (this) {
8224 ActivityRecord record = ActivityRecord.isInStackLocked(token);
8225 if (record == null) {
8226 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
8227 + "found for: " + token);
8229 record.setSizeConfigurations(horizontalSizeConfiguration,
8230 verticalSizeConfigurations, smallestSizeConfigurations);
8235 public final void notifyLaunchTaskBehindComplete(IBinder token) {
8236 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
8240 public final void notifyEnterAnimationComplete(IBinder token) {
8241 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
8245 public String getCallingPackage(IBinder token) {
8246 synchronized (this) {
8247 ActivityRecord r = getCallingRecordLocked(token);
8248 return r != null ? r.info.packageName : null;
8253 public ComponentName getCallingActivity(IBinder token) {
8254 synchronized (this) {
8255 ActivityRecord r = getCallingRecordLocked(token);
8256 return r != null ? r.intent.getComponent() : null;
8260 private ActivityRecord getCallingRecordLocked(IBinder token) {
8261 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8269 public ComponentName getActivityClassForToken(IBinder token) {
8270 synchronized(this) {
8271 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8275 return r.intent.getComponent();
8280 public String getPackageForToken(IBinder token) {
8281 synchronized(this) {
8282 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8286 return r.packageName;
8291 public boolean isRootVoiceInteraction(IBinder token) {
8292 synchronized(this) {
8293 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8297 return r.rootVoiceInteraction;
8302 public IIntentSender getIntentSender(int type,
8303 String packageName, IBinder token, String resultWho,
8304 int requestCode, Intent[] intents, String[] resolvedTypes,
8305 int flags, Bundle bOptions, int userId) {
8306 enforceNotIsolatedCaller("getIntentSender");
8307 // Refuse possible leaked file descriptors
8308 if (intents != null) {
8309 if (intents.length < 1) {
8310 throw new IllegalArgumentException("Intents array length must be >= 1");
8312 for (int i=0; i<intents.length; i++) {
8313 Intent intent = intents[i];
8314 if (intent != null) {
8315 if (intent.hasFileDescriptors()) {
8316 throw new IllegalArgumentException("File descriptors passed in Intent");
8318 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
8319 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
8320 throw new IllegalArgumentException(
8321 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
8323 intents[i] = new Intent(intent);
8326 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8327 throw new IllegalArgumentException(
8328 "Intent array length does not match resolvedTypes length");
8331 if (bOptions != null) {
8332 if (bOptions.hasFileDescriptors()) {
8333 throw new IllegalArgumentException("File descriptors passed in options");
8337 synchronized(this) {
8338 int callingUid = Binder.getCallingUid();
8339 int origUserId = userId;
8340 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8341 type == ActivityManager.INTENT_SENDER_BROADCAST,
8342 ALLOW_NON_FULL, "getIntentSender", null);
8343 if (origUserId == UserHandle.USER_CURRENT) {
8344 // We don't want to evaluate this until the pending intent is
8345 // actually executed. However, we do want to always do the
8346 // security checking for it above.
8347 userId = UserHandle.USER_CURRENT;
8350 if (callingUid != 0 && callingUid != SYSTEM_UID) {
8351 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8352 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8353 if (!UserHandle.isSameApp(callingUid, uid)) {
8354 String msg = "Permission Denial: getIntentSender() from pid="
8355 + Binder.getCallingPid()
8356 + ", uid=" + Binder.getCallingUid()
8357 + ", (need uid=" + uid + ")"
8358 + " is not allowed to send as package " + packageName;
8360 throw new SecurityException(msg);
8364 return getIntentSenderLocked(type, packageName, callingUid, userId,
8365 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8367 } catch (RemoteException e) {
8368 throw new SecurityException(e);
8373 IIntentSender getIntentSenderLocked(int type, String packageName,
8374 int callingUid, int userId, IBinder token, String resultWho,
8375 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8377 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8378 ActivityRecord activity = null;
8379 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8380 activity = ActivityRecord.isInStackLocked(token);
8381 if (activity == null) {
8382 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8385 if (activity.finishing) {
8386 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8391 // We're going to be splicing together extras before sending, so we're
8392 // okay poking into any contained extras.
8393 if (intents != null) {
8394 for (int i = 0; i < intents.length; i++) {
8395 intents[i].setDefusable(true);
8398 Bundle.setDefusable(bOptions, true);
8400 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8401 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8402 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8403 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8404 |PendingIntent.FLAG_UPDATE_CURRENT);
8406 PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8407 resultWho, requestCode, intents, resolvedTypes, flags,
8408 SafeActivityOptions.fromBundle(bOptions), userId);
8409 WeakReference<PendingIntentRecord> ref;
8410 ref = mIntentSenderRecords.get(key);
8411 PendingIntentRecord rec = ref != null ? ref.get() : null;
8413 if (!cancelCurrent) {
8414 if (updateCurrent) {
8415 if (rec.key.requestIntent != null) {
8416 rec.key.requestIntent.replaceExtras(intents != null ?
8417 intents[intents.length - 1] : null);
8419 if (intents != null) {
8420 intents[intents.length-1] = rec.key.requestIntent;
8421 rec.key.allIntents = intents;
8422 rec.key.allResolvedTypes = resolvedTypes;
8424 rec.key.allIntents = null;
8425 rec.key.allResolvedTypes = null;
8430 makeIntentSenderCanceledLocked(rec);
8431 mIntentSenderRecords.remove(key);
8436 rec = new PendingIntentRecord(this, key, callingUid);
8437 mIntentSenderRecords.put(key, rec.ref);
8438 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8439 if (activity.pendingResults == null) {
8440 activity.pendingResults
8441 = new HashSet<WeakReference<PendingIntentRecord>>();
8443 activity.pendingResults.add(rec.ref);
8449 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8450 Intent intent, String resolvedType,
8451 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8452 if (target instanceof PendingIntentRecord) {
8453 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8454 whitelistToken, finishedReceiver, requiredPermission, options);
8456 if (intent == null) {
8457 // Weird case: someone has given us their own custom IIntentSender, and now
8458 // they have someone else trying to send to it but of course this isn't
8459 // really a PendingIntent, so there is no base Intent, and the caller isn't
8460 // supplying an Intent... but we never want to dispatch a null Intent to
8461 // a receiver, so um... let's make something up.
8462 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8463 intent = new Intent(Intent.ACTION_MAIN);
8466 target.send(code, intent, resolvedType, whitelistToken, null,
8467 requiredPermission, options);
8468 } catch (RemoteException e) {
8470 // Platform code can rely on getting a result back when the send is done, but if
8471 // this intent sender is from outside of the system we can't rely on it doing that.
8472 // So instead we don't give it the result receiver, and instead just directly
8473 // report the finish immediately.
8474 if (finishedReceiver != null) {
8476 finishedReceiver.performReceive(intent, 0,
8477 null, null, false, false, UserHandle.getCallingUserId());
8478 } catch (RemoteException e) {
8486 public void cancelIntentSender(IIntentSender sender) {
8487 if (!(sender instanceof PendingIntentRecord)) {
8490 synchronized(this) {
8491 PendingIntentRecord rec = (PendingIntentRecord)sender;
8493 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8494 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8495 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8496 String msg = "Permission Denial: cancelIntentSender() from pid="
8497 + Binder.getCallingPid()
8498 + ", uid=" + Binder.getCallingUid()
8499 + " is not allowed to cancel package "
8500 + rec.key.packageName;
8502 throw new SecurityException(msg);
8504 } catch (RemoteException e) {
8505 throw new SecurityException(e);
8507 cancelIntentSenderLocked(rec, true);
8511 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8512 makeIntentSenderCanceledLocked(rec);
8513 mIntentSenderRecords.remove(rec.key);
8514 if (cleanActivity && rec.key.activity != null) {
8515 rec.key.activity.pendingResults.remove(rec.ref);
8519 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8520 rec.canceled = true;
8521 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8522 if (callbacks != null) {
8523 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8528 public String getPackageForIntentSender(IIntentSender pendingResult) {
8529 if (!(pendingResult instanceof PendingIntentRecord)) {
8533 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8534 return res.key.packageName;
8535 } catch (ClassCastException e) {
8541 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8542 if (!(sender instanceof PendingIntentRecord)) {
8545 boolean isCancelled;
8546 synchronized(this) {
8547 PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
8548 isCancelled = pendingIntent.canceled;
8550 pendingIntent.registerCancelListenerLocked(receiver);
8555 receiver.send(Activity.RESULT_CANCELED, null);
8556 } catch (RemoteException e) {
8562 public void unregisterIntentSenderCancelListener(IIntentSender sender,
8563 IResultReceiver receiver) {
8564 if (!(sender instanceof PendingIntentRecord)) {
8567 synchronized(this) {
8568 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8573 public int getUidForIntentSender(IIntentSender sender) {
8574 if (sender instanceof PendingIntentRecord) {
8576 PendingIntentRecord res = (PendingIntentRecord)sender;
8578 } catch (ClassCastException e) {
8585 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8586 if (!(pendingResult instanceof PendingIntentRecord)) {
8590 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8591 if (res.key.allIntents == null) {
8594 for (int i=0; i<res.key.allIntents.length; i++) {
8595 Intent intent = res.key.allIntents[i];
8596 if (intent.getPackage() != null && intent.getComponent() != null) {
8601 } catch (ClassCastException e) {
8607 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8608 if (!(pendingResult instanceof PendingIntentRecord)) {
8612 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8613 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8617 } catch (ClassCastException e) {
8623 public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8624 if (pendingResult instanceof PendingIntentRecord) {
8625 final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8626 return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8632 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8633 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8634 "getIntentForIntentSender()");
8635 if (!(pendingResult instanceof PendingIntentRecord)) {
8639 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8640 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8641 } catch (ClassCastException e) {
8647 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8648 if (!(pendingResult instanceof PendingIntentRecord)) {
8652 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8653 synchronized (this) {
8654 return getTagForIntentSenderLocked(res, prefix);
8656 } catch (ClassCastException e) {
8661 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8662 final Intent intent = res.key.requestIntent;
8663 if (intent != null) {
8664 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8665 || res.lastTagPrefix.equals(prefix))) {
8668 res.lastTagPrefix = prefix;
8669 final StringBuilder sb = new StringBuilder(128);
8670 if (prefix != null) {
8673 if (intent.getAction() != null) {
8674 sb.append(intent.getAction());
8675 } else if (intent.getComponent() != null) {
8676 intent.getComponent().appendShortString(sb);
8680 return res.lastTag = sb.toString();
8686 public void setProcessLimit(int max) {
8687 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8688 "setProcessLimit()");
8689 synchronized (this) {
8690 mConstants.setOverrideMaxCachedProcesses(max);
8696 public int getProcessLimit() {
8697 synchronized (this) {
8698 return mConstants.getOverrideMaxCachedProcesses();
8702 void importanceTokenDied(ImportanceToken token) {
8703 synchronized (ActivityManagerService.this) {
8704 synchronized (mPidsSelfLocked) {
8706 = mImportantProcesses.get(token.pid);
8710 mImportantProcesses.remove(token.pid);
8711 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8715 pr.forcingToImportant = null;
8716 updateProcessForegroundLocked(pr, false, false);
8718 updateOomAdjLocked();
8723 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8724 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8725 "setProcessImportant()");
8726 synchronized(this) {
8727 boolean changed = false;
8729 synchronized (mPidsSelfLocked) {
8730 ProcessRecord pr = mPidsSelfLocked.get(pid);
8731 if (pr == null && isForeground) {
8732 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8735 ImportanceToken oldToken = mImportantProcesses.get(pid);
8736 if (oldToken != null) {
8737 oldToken.token.unlinkToDeath(oldToken, 0);
8738 mImportantProcesses.remove(pid);
8740 pr.forcingToImportant = null;
8744 if (isForeground && token != null) {
8745 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8747 public void binderDied() {
8748 importanceTokenDied(this);
8752 token.linkToDeath(newToken, 0);
8753 mImportantProcesses.put(pid, newToken);
8754 pr.forcingToImportant = newToken;
8756 } catch (RemoteException e) {
8757 // If the process died while doing this, we will later
8758 // do the cleanup with the process death link.
8764 updateOomAdjLocked();
8770 public boolean isAppForeground(int uid) {
8771 int callerUid = Binder.getCallingUid();
8772 if (UserHandle.isCore(callerUid) || callerUid == uid) {
8773 return isAppForegroundInternal(uid);
8778 private boolean isAppForegroundInternal(int uid) {
8779 synchronized (this) {
8780 UidRecord uidRec = mActiveUids.get(uid);
8781 if (uidRec == null || uidRec.idle) {
8784 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8788 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8789 // be guarded by permission checking.
8790 int getUidState(int uid) {
8791 synchronized (this) {
8792 return getUidStateLocked(uid);
8796 int getUidStateLocked(int uid) {
8797 UidRecord uidRec = mActiveUids.get(uid);
8798 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8802 public boolean isInMultiWindowMode(IBinder token) {
8803 final long origId = Binder.clearCallingIdentity();
8805 synchronized(this) {
8806 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8810 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8811 return r.inMultiWindowMode();
8814 Binder.restoreCallingIdentity(origId);
8819 public boolean isInPictureInPictureMode(IBinder token) {
8820 final long origId = Binder.clearCallingIdentity();
8822 synchronized(this) {
8823 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8826 Binder.restoreCallingIdentity(origId);
8830 private boolean isInPictureInPictureMode(ActivityRecord r) {
8831 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8832 || r.getStack().isInStackLocked(r) == null) {
8836 // If we are animating to fullscreen then we have already dispatched the PIP mode
8837 // changed, so we should reflect that check here as well.
8838 final PinnedActivityStack stack = r.getStack();
8839 final PinnedStackWindowController windowController = stack.getWindowContainerController();
8840 return !windowController.isAnimatingBoundsToFullscreen();
8844 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8845 final long origId = Binder.clearCallingIdentity();
8847 synchronized(this) {
8848 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8849 "enterPictureInPictureMode", token, params);
8851 // If the activity is already in picture in picture mode, then just return early
8852 if (isInPictureInPictureMode(r)) {
8856 // Activity supports picture-in-picture, now check that we can enter PiP at this
8858 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8859 false /* beforeStopping */)) {
8863 final Runnable enterPipRunnable = () -> {
8864 // Only update the saved args from the args that are set
8865 r.pictureInPictureArgs.copyOnlySet(params);
8866 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8867 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8868 // Adjust the source bounds by the insets for the transition down
8869 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8870 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8871 "enterPictureInPictureMode");
8872 final PinnedActivityStack stack = r.getStack();
8873 stack.setPictureInPictureAspectRatio(aspectRatio);
8874 stack.setPictureInPictureActions(actions);
8875 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
8876 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
8877 logPictureInPictureArgs(params);
8880 if (isKeyguardLocked()) {
8881 // If the keyguard is showing or occluded, then try and dismiss it before
8882 // entering picture-in-picture (this will prompt the user to authenticate if the
8883 // device is currently locked).
8885 dismissKeyguard(token, new KeyguardDismissCallback() {
8887 public void onDismissSucceeded() throws RemoteException {
8888 mHandler.post(enterPipRunnable);
8890 }, null /* message */);
8891 } catch (RemoteException e) {
8895 // Enter picture in picture immediately otherwise
8896 enterPipRunnable.run();
8901 Binder.restoreCallingIdentity(origId);
8906 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8907 final long origId = Binder.clearCallingIdentity();
8909 synchronized(this) {
8910 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8911 "setPictureInPictureParams", token, params);
8913 // Only update the saved args from the args that are set
8914 r.pictureInPictureArgs.copyOnlySet(params);
8915 if (r.inPinnedWindowingMode()) {
8916 // If the activity is already in picture-in-picture, update the pinned stack now
8917 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8918 // be used the next time the activity enters PiP
8919 final PinnedActivityStack stack = r.getStack();
8920 if (!stack.isAnimatingBoundsToFullscreen()) {
8921 stack.setPictureInPictureAspectRatio(
8922 r.pictureInPictureArgs.getAspectRatio());
8923 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8926 logPictureInPictureArgs(params);
8929 Binder.restoreCallingIdentity(origId);
8934 public int getMaxNumPictureInPictureActions(IBinder token) {
8935 // Currently, this is a static constant, but later, we may change this to be dependent on
8936 // the context of the activity
8940 private void logPictureInPictureArgs(PictureInPictureParams params) {
8941 if (params.hasSetActions()) {
8942 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8943 params.getActions().size());
8945 if (params.hasSetAspectRatio()) {
8946 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8947 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8948 MetricsLogger.action(lm);
8953 * Checks the state of the system and the activity associated with the given {@param token} to
8954 * verify that picture-in-picture is supported for that activity.
8956 * @return the activity record for the given {@param token} if all the checks pass.
8958 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8959 IBinder token, PictureInPictureParams params) {
8960 if (!mSupportsPictureInPicture) {
8961 throw new IllegalStateException(caller
8962 + ": Device doesn't support picture-in-picture mode.");
8965 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8967 throw new IllegalStateException(caller
8968 + ": Can't find activity for token=" + token);
8971 if (!r.supportsPictureInPicture()) {
8972 throw new IllegalStateException(caller
8973 + ": Current activity does not support picture-in-picture.");
8976 if (params.hasSetAspectRatio()
8977 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8978 params.getAspectRatio())) {
8979 final float minAspectRatio = mContext.getResources().getFloat(
8980 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8981 final float maxAspectRatio = mContext.getResources().getFloat(
8982 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8983 throw new IllegalArgumentException(String.format(caller
8984 + ": Aspect ratio is too extreme (must be between %f and %f).",
8985 minAspectRatio, maxAspectRatio));
8988 // Truncate the number of actions if necessary
8989 params.truncateActions(getMaxNumPictureInPictureActions(token));
8994 // =========================================================
8996 // =========================================================
8998 static class ProcessInfoService extends IProcessInfoService.Stub {
8999 final ActivityManagerService mActivityManagerService;
9000 ProcessInfoService(ActivityManagerService activityManagerService) {
9001 mActivityManagerService = activityManagerService;
9005 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
9006 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
9007 /*in*/ pids, /*out*/ states, null);
9011 public void getProcessStatesAndOomScoresFromPids(
9012 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
9013 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
9014 /*in*/ pids, /*out*/ states, /*out*/ scores);
9019 * For each PID in the given input array, write the current process state
9020 * for that process into the states array, or -1 to indicate that no
9021 * process with the given PID exists. If scores array is provided, write
9022 * the oom score for the process into the scores array, with INVALID_ADJ
9023 * indicating the PID doesn't exist.
9025 public void getProcessStatesAndOomScoresForPIDs(
9026 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
9027 if (scores != null) {
9028 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
9029 "getProcessStatesAndOomScoresForPIDs()");
9033 throw new NullPointerException("pids");
9034 } else if (states == null) {
9035 throw new NullPointerException("states");
9036 } else if (pids.length != states.length) {
9037 throw new IllegalArgumentException("pids and states arrays have different lengths!");
9038 } else if (scores != null && pids.length != scores.length) {
9039 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
9042 synchronized (mPidsSelfLocked) {
9043 for (int i = 0; i < pids.length; i++) {
9044 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
9045 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
9047 if (scores != null) {
9048 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
9054 // =========================================================
9056 // =========================================================
9058 static class PermissionController extends IPermissionController.Stub {
9059 ActivityManagerService mActivityManagerService;
9060 PermissionController(ActivityManagerService activityManagerService) {
9061 mActivityManagerService = activityManagerService;
9065 public boolean checkPermission(String permission, int pid, int uid) {
9066 return mActivityManagerService.checkPermission(permission, pid,
9067 uid) == PackageManager.PERMISSION_GRANTED;
9071 public int noteOp(String op, int uid, String packageName) {
9072 return mActivityManagerService.mAppOpsService
9073 .noteOperation(AppOpsManager.strOpToOp(op), uid, packageName);
9077 public String[] getPackagesForUid(int uid) {
9078 return mActivityManagerService.mContext.getPackageManager()
9079 .getPackagesForUid(uid);
9083 public boolean isRuntimePermission(String permission) {
9085 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
9086 .getPermissionInfo(permission, 0);
9087 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
9088 == PermissionInfo.PROTECTION_DANGEROUS;
9089 } catch (NameNotFoundException nnfe) {
9090 Slog.e(TAG, "No such permission: "+ permission, nnfe);
9096 public int getPackageUid(String packageName, int flags) {
9098 return mActivityManagerService.mContext.getPackageManager()
9099 .getPackageUid(packageName, flags);
9100 } catch (NameNotFoundException nnfe) {
9106 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
9108 public int checkComponentPermission(String permission, int pid, int uid,
9109 int owningUid, boolean exported) {
9110 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
9111 owningUid, exported);
9115 public Object getAMSLock() {
9116 return ActivityManagerService.this;
9120 int checkComponentPermission(String permission, int pid, int uid,
9121 int owningUid, boolean exported) {
9122 if (pid == MY_PID) {
9123 return PackageManager.PERMISSION_GRANTED;
9125 return ActivityManager.checkComponentPermission(permission, uid,
9126 owningUid, exported);
9130 * As the only public entry point for permissions checking, this method
9131 * can enforce the semantic that requesting a check on a null global
9132 * permission is automatically denied. (Internally a null permission
9133 * string is used when calling {@link #checkComponentPermission} in cases
9134 * when only uid-based security is needed.)
9136 * This can be called with or without the global lock held.
9139 public int checkPermission(String permission, int pid, int uid) {
9140 if (permission == null) {
9141 return PackageManager.PERMISSION_DENIED;
9143 return checkComponentPermission(permission, pid, uid, -1, true);
9147 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
9148 if (permission == null) {
9149 return PackageManager.PERMISSION_DENIED;
9152 // We might be performing an operation on behalf of an indirect binder
9153 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
9154 // client identity accordingly before proceeding.
9155 Identity tlsIdentity = sCallerIdentity.get();
9156 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9157 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
9158 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
9159 uid = tlsIdentity.uid;
9160 pid = tlsIdentity.pid;
9163 return checkComponentPermission(permission, pid, uid, -1, true);
9167 * Binder IPC calls go through the public entry point.
9168 * This can be called with or without the global lock held.
9170 int checkCallingPermission(String permission) {
9171 return checkPermission(permission,
9172 Binder.getCallingPid(),
9173 UserHandle.getAppId(Binder.getCallingUid()));
9177 * This can be called with or without the global lock held.
9179 void enforceCallingPermission(String permission, String func) {
9180 if (checkCallingPermission(permission)
9181 == PackageManager.PERMISSION_GRANTED) {
9185 String msg = "Permission Denial: " + func + " from pid="
9186 + Binder.getCallingPid()
9187 + ", uid=" + Binder.getCallingUid()
9188 + " requires " + permission;
9190 throw new SecurityException(msg);
9194 * This can be called with or without the global lock held.
9196 void enforcePermission(String permission, int pid, int uid, String func) {
9197 if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
9201 String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
9202 + " requires " + permission;
9204 throw new SecurityException(msg);
9208 * This can be called with or without the global lock held.
9210 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
9211 if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
9212 enforceCallingPermission(permission, func);
9217 * Determine if UID is holding permissions required to access {@link Uri} in
9218 * the given {@link ProviderInfo}. Final permission checking is always done
9219 * in {@link ContentProvider}.
9221 private final boolean checkHoldingPermissionsLocked(
9222 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
9223 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9224 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
9225 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
9226 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
9227 != PERMISSION_GRANTED) {
9231 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
9234 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
9235 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
9236 if (pi.applicationInfo.uid == uid) {
9238 } else if (!pi.exported) {
9242 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
9243 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
9245 // check if target holds top-level <provider> permissions
9246 if (!readMet && pi.readPermission != null && considerUidPermissions
9247 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
9250 if (!writeMet && pi.writePermission != null && considerUidPermissions
9251 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
9255 // track if unprotected read/write is allowed; any denied
9256 // <path-permission> below removes this ability
9257 boolean allowDefaultRead = pi.readPermission == null;
9258 boolean allowDefaultWrite = pi.writePermission == null;
9260 // check if target holds any <path-permission> that match uri
9261 final PathPermission[] pps = pi.pathPermissions;
9263 final String path = grantUri.uri.getPath();
9265 while (i > 0 && (!readMet || !writeMet)) {
9267 PathPermission pp = pps[i];
9268 if (pp.match(path)) {
9270 final String pprperm = pp.getReadPermission();
9271 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9272 "Checking read perm for " + pprperm + " for " + pp.getPath()
9273 + ": match=" + pp.match(path)
9274 + " check=" + pm.checkUidPermission(pprperm, uid));
9275 if (pprperm != null) {
9276 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
9277 == PERMISSION_GRANTED) {
9280 allowDefaultRead = false;
9285 final String ppwperm = pp.getWritePermission();
9286 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9287 "Checking write perm " + ppwperm + " for " + pp.getPath()
9288 + ": match=" + pp.match(path)
9289 + " check=" + pm.checkUidPermission(ppwperm, uid));
9290 if (ppwperm != null) {
9291 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
9292 == PERMISSION_GRANTED) {
9295 allowDefaultWrite = false;
9303 // grant unprotected <provider> read/write, if not blocked by
9304 // <path-permission> above
9305 if (allowDefaultRead) readMet = true;
9306 if (allowDefaultWrite) writeMet = true;
9308 } catch (RemoteException e) {
9312 return readMet && writeMet;
9315 public boolean isAppStartModeDisabled(int uid, String packageName) {
9316 synchronized (this) {
9317 return getAppStartModeLocked(uid, packageName, 0, -1, false, true, false)
9318 == ActivityManager.APP_START_MODE_DISABLED;
9322 // Unified app-op and target sdk check
9323 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9324 // Apps that target O+ are always subject to background check
9325 if (packageTargetSdk >= Build.VERSION_CODES.O) {
9326 if (DEBUG_BACKGROUND_CHECK) {
9327 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
9329 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9331 // ...and legacy apps get an AppOp check
9332 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
9334 if (DEBUG_BACKGROUND_CHECK) {
9335 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
9338 case AppOpsManager.MODE_ALLOWED:
9339 // If force-background-check is enabled, restrict all apps that aren't whitelisted.
9340 if (mForceBackgroundCheck &&
9341 !UserHandle.isCore(uid) &&
9342 !isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ true)) {
9343 if (DEBUG_BACKGROUND_CHECK) {
9344 Slog.i(TAG, "Force background check: " +
9345 uid + "/" + packageName + " restricted");
9347 return ActivityManager.APP_START_MODE_DELAYED;
9349 return ActivityManager.APP_START_MODE_NORMAL;
9350 case AppOpsManager.MODE_IGNORED:
9351 return ActivityManager.APP_START_MODE_DELAYED;
9353 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9357 // Service launch is available to apps with run-in-background exemptions but
9358 // some other background operations are not. If we're doing a check
9359 // of service-launch policy, allow those callers to proceed unrestricted.
9360 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9362 if (mPackageManagerInt.isPackagePersistent(packageName)) {
9363 if (DEBUG_BACKGROUND_CHECK) {
9364 Slog.i(TAG, "App " + uid + "/" + packageName
9365 + " is persistent; not restricted in background");
9367 return ActivityManager.APP_START_MODE_NORMAL;
9370 // Non-persistent but background whitelisted?
9371 if (uidOnBackgroundWhitelist(uid)) {
9372 if (DEBUG_BACKGROUND_CHECK) {
9373 Slog.i(TAG, "App " + uid + "/" + packageName
9374 + " on background whitelist; not restricted in background");
9376 return ActivityManager.APP_START_MODE_NORMAL;
9379 // Is this app on the battery whitelist?
9380 if (isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ false)) {
9381 if (DEBUG_BACKGROUND_CHECK) {
9382 Slog.i(TAG, "App " + uid + "/" + packageName
9383 + " on idle whitelist; not restricted in background");
9385 return ActivityManager.APP_START_MODE_NORMAL;
9388 // None of the service-policy criteria apply, so we apply the common criteria
9389 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9392 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9393 int callingPid, boolean alwaysRestrict, boolean disabledOnly, boolean forcedStandby) {
9394 UidRecord uidRec = mActiveUids.get(uid);
9395 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9396 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9397 + (uidRec != null ? uidRec.idle : false));
9398 if (uidRec == null || alwaysRestrict || forcedStandby || uidRec.idle) {
9400 if (uidRec == null) {
9401 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9402 UserHandle.getUserId(uid), packageName);
9404 ephemeral = uidRec.ephemeral;
9408 // We are hard-core about ephemeral apps not running in the background.
9409 return ActivityManager.APP_START_MODE_DISABLED;
9412 // The caller is only interested in whether app starts are completely
9413 // disabled for the given package (that is, it is an instant app). So
9414 // we don't need to go further, which is all just seeing if we should
9415 // apply a "delayed" mode for a regular app.
9416 return ActivityManager.APP_START_MODE_NORMAL;
9418 final int startMode = (alwaysRestrict)
9419 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9420 : appServicesRestrictedInBackgroundLocked(uid, packageName,
9422 if (DEBUG_BACKGROUND_CHECK) {
9423 Slog.d(TAG, "checkAllowBackground: uid=" + uid
9424 + " pkg=" + packageName + " startMode=" + startMode
9425 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid, false)
9426 + " onwhitelist(ei)=" + isOnDeviceIdleWhitelistLocked(uid, true));
9428 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9429 // This is an old app that has been forced into a "compatible as possible"
9430 // mode of background check. To increase compatibility, we will allow other
9431 // foreground apps to cause its services to start.
9432 if (callingPid >= 0) {
9434 synchronized (mPidsSelfLocked) {
9435 proc = mPidsSelfLocked.get(callingPid);
9438 !ActivityManager.isProcStateBackground(proc.curProcState)) {
9439 // Whoever is instigating this is in the foreground, so we will allow it
9441 return ActivityManager.APP_START_MODE_NORMAL;
9448 return ActivityManager.APP_START_MODE_NORMAL;
9452 * @return whether a UID is in the system, user or temp doze whitelist.
9454 boolean isOnDeviceIdleWhitelistLocked(int uid, boolean allowExceptIdleToo) {
9455 final int appId = UserHandle.getAppId(uid);
9457 final int[] whitelist = allowExceptIdleToo
9458 ? mDeviceIdleExceptIdleWhitelist
9459 : mDeviceIdleWhitelist;
9461 return Arrays.binarySearch(whitelist, appId) >= 0
9462 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9463 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9466 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9467 ProviderInfo pi = null;
9468 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9473 pi = AppGlobals.getPackageManager().resolveContentProvider(
9474 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9476 } catch (RemoteException ex) {
9482 void grantEphemeralAccessLocked(int userId, Intent intent,
9483 int targetAppId, int ephemeralAppId) {
9484 getPackageManagerInternalLocked().
9485 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9489 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9490 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9491 if (targetUris != null) {
9492 return targetUris.get(grantUri);
9498 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9499 String targetPkg, int targetUid, GrantUri grantUri) {
9500 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9501 if (targetUris == null) {
9502 targetUris = Maps.newArrayMap();
9503 mGrantedUriPermissions.put(targetUid, targetUris);
9506 UriPermission perm = targetUris.get(grantUri);
9508 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9509 targetUris.put(grantUri, perm);
9516 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9517 final int modeFlags) {
9518 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9519 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9520 : UriPermission.STRENGTH_OWNED;
9522 // Root gets to do everything.
9527 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9528 if (perms == null) return false;
9530 // First look for exact match
9531 final UriPermission exactPerm = perms.get(grantUri);
9532 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9536 // No exact match, look for prefixes
9537 final int N = perms.size();
9538 for (int i = 0; i < N; i++) {
9539 final UriPermission perm = perms.valueAt(i);
9540 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9541 && perm.getStrength(modeFlags) >= minStrength) {
9550 * @param uri This uri must NOT contain an embedded userId.
9551 * @param userId The userId in which the uri is to be resolved.
9554 public int checkUriPermission(Uri uri, int pid, int uid,
9555 final int modeFlags, int userId, IBinder callerToken) {
9556 enforceNotIsolatedCaller("checkUriPermission");
9558 // Another redirected-binder-call permissions check as in
9559 // {@link checkPermissionWithToken}.
9560 Identity tlsIdentity = sCallerIdentity.get();
9561 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9562 uid = tlsIdentity.uid;
9563 pid = tlsIdentity.pid;
9566 // Our own process gets to do everything.
9567 if (pid == MY_PID) {
9568 return PackageManager.PERMISSION_GRANTED;
9570 synchronized (this) {
9571 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9572 ? PackageManager.PERMISSION_GRANTED
9573 : PackageManager.PERMISSION_DENIED;
9578 * Check if the targetPkg can be granted permission to access uri by
9579 * the callingUid using the given modeFlags. Throws a security exception
9580 * if callingUid is not allowed to do this. Returns the uid of the target
9581 * if the URI permission grant should be performed; returns -1 if it is not
9582 * needed (for example targetPkg already has permission to access the URI).
9583 * If you already know the uid of the target, you can supply it in
9584 * lastTargetUid else set that to -1.
9587 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9588 final int modeFlags, int lastTargetUid) {
9589 if (!Intent.isAccessUriMode(modeFlags)) {
9593 if (targetPkg != null) {
9594 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9595 "Checking grant " + targetPkg + " permission to " + grantUri);
9598 final IPackageManager pm = AppGlobals.getPackageManager();
9600 // If this is not a content: uri, we can't do anything with it.
9601 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9602 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9603 "Can't grant URI permission for non-content URI: " + grantUri);
9607 // Bail early if system is trying to hand out permissions directly; it
9608 // must always grant permissions on behalf of someone explicit.
9609 final int callingAppId = UserHandle.getAppId(callingUid);
9610 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9611 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9612 // Exempted authority for
9613 // 1. cropping user photos and sharing a generated license html
9614 // file in Settings app
9615 // 2. sharing a generated license html file in TvSettings app
9617 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9618 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9623 final String authority = grantUri.uri.getAuthority();
9624 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9625 MATCH_DEBUG_TRIAGED_MISSING);
9627 Slog.w(TAG, "No content provider found for permission check: " +
9628 grantUri.uri.toSafeString());
9632 int targetUid = lastTargetUid;
9633 if (targetUid < 0 && targetPkg != null) {
9635 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9636 UserHandle.getUserId(callingUid));
9637 if (targetUid < 0) {
9638 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9639 "Can't grant URI permission no uid for: " + targetPkg);
9642 } catch (RemoteException ex) {
9647 // Figure out the value returned when access is allowed
9648 final int allowedResult;
9649 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9650 // If we're extending a persistable grant, then we need to return
9651 // "targetUid" so that we always create a grant data structure to
9652 // support take/release APIs
9653 allowedResult = targetUid;
9655 // Otherwise, we can return "-1" to indicate that no grant data
9656 // structures need to be created
9660 if (targetUid >= 0) {
9661 // First... does the target actually need this permission?
9662 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9663 // No need to grant the target this permission.
9664 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9665 "Target " + targetPkg + " already has full permission to " + grantUri);
9666 return allowedResult;
9669 // First... there is no target package, so can anyone access it?
9670 boolean allowed = pi.exported;
9671 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9672 if (pi.readPermission != null) {
9676 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9677 if (pi.writePermission != null) {
9681 if (pi.pathPermissions != null) {
9682 final int N = pi.pathPermissions.length;
9683 for (int i=0; i<N; i++) {
9684 if (pi.pathPermissions[i] != null
9685 && pi.pathPermissions[i].match(grantUri.uri.getPath())) {
9686 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9687 if (pi.pathPermissions[i].getReadPermission() != null) {
9691 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9692 if (pi.pathPermissions[i].getWritePermission() != null) {
9701 return allowedResult;
9705 /* There is a special cross user grant if:
9706 * - The target is on another user.
9707 * - Apps on the current user can access the uri without any uid permissions.
9708 * In this case, we grant a uri permission, even if the ContentProvider does not normally
9709 * grant uri permissions.
9711 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9712 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9713 modeFlags, false /*without considering the uid permissions*/);
9715 // Second... is the provider allowing granting of URI permissions?
9716 if (!specialCrossUserGrant) {
9717 if (!pi.grantUriPermissions) {
9718 throw new SecurityException("Provider " + pi.packageName
9720 + " does not allow granting of Uri permissions (uri "
9723 if (pi.uriPermissionPatterns != null) {
9724 final int N = pi.uriPermissionPatterns.length;
9725 boolean allowed = false;
9726 for (int i=0; i<N; i++) {
9727 if (pi.uriPermissionPatterns[i] != null
9728 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9734 throw new SecurityException("Provider " + pi.packageName
9736 + " does not allow granting of permission to path of Uri "
9742 // Third... does the caller itself have permission to access
9744 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9745 // Require they hold a strong enough Uri permission
9746 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9747 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9748 throw new SecurityException(
9749 "UID " + callingUid + " does not have permission to " + grantUri
9750 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9751 + "or related APIs");
9753 throw new SecurityException(
9754 "UID " + callingUid + " does not have permission to " + grantUri);
9762 * @param uri This uri must NOT contain an embedded userId.
9763 * @param userId The userId in which the uri is to be resolved.
9766 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9767 final int modeFlags, int userId) {
9768 enforceNotIsolatedCaller("checkGrantUriPermission");
9769 synchronized(this) {
9770 return checkGrantUriPermissionLocked(callingUid, targetPkg,
9771 new GrantUri(userId, uri, false), modeFlags, -1);
9776 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9777 final int modeFlags, UriPermissionOwner owner) {
9778 if (!Intent.isAccessUriMode(modeFlags)) {
9782 // So here we are: the caller has the assumed permission
9783 // to the uri, and the target doesn't. Let's now give this to
9786 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9787 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9789 final String authority = grantUri.uri.getAuthority();
9790 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9791 MATCH_DEBUG_TRIAGED_MISSING);
9793 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9797 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9798 grantUri.prefix = true;
9800 final UriPermission perm = findOrCreateUriPermissionLocked(
9801 pi.packageName, targetPkg, targetUid, grantUri);
9802 perm.grantModes(modeFlags, owner);
9806 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9807 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9808 if (targetPkg == null) {
9809 throw new NullPointerException("targetPkg");
9812 final IPackageManager pm = AppGlobals.getPackageManager();
9814 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9815 } catch (RemoteException ex) {
9819 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9821 if (targetUid < 0) {
9825 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9829 static class NeededUriGrants extends ArrayList<GrantUri> {
9830 final String targetPkg;
9831 final int targetUid;
9834 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9835 this.targetPkg = targetPkg;
9836 this.targetUid = targetUid;
9840 void writeToProto(ProtoOutputStream proto, long fieldId) {
9841 long token = proto.start(fieldId);
9842 proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9843 proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9844 proto.write(NeededUriGrantsProto.FLAGS, flags);
9846 final int N = this.size();
9847 for (int i=0; i<N; i++) {
9848 this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9855 * Like checkGrantUriPermissionLocked, but takes an Intent.
9858 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9859 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9860 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9861 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9862 + " clip=" + (intent != null ? intent.getClipData() : null)
9863 + " from " + intent + "; flags=0x"
9864 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9866 if (targetPkg == null) {
9867 throw new NullPointerException("targetPkg");
9870 if (intent == null) {
9873 Uri data = intent.getData();
9874 ClipData clip = intent.getClipData();
9875 if (data == null && clip == null) {
9878 // Default userId for uris in the intent (if they don't specify it themselves)
9879 int contentUserHint = intent.getContentUserHint();
9880 if (contentUserHint == UserHandle.USER_CURRENT) {
9881 contentUserHint = UserHandle.getUserId(callingUid);
9883 final IPackageManager pm = AppGlobals.getPackageManager();
9885 if (needed != null) {
9886 targetUid = needed.targetUid;
9889 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9891 } catch (RemoteException ex) {
9894 if (targetUid < 0) {
9895 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9896 "Can't grant URI permission no uid for: " + targetPkg
9897 + " on user " + targetUserId);
9902 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9903 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9905 if (targetUid > 0) {
9906 if (needed == null) {
9907 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9909 needed.add(grantUri);
9913 for (int i=0; i<clip.getItemCount(); i++) {
9914 Uri uri = clip.getItemAt(i).getUri();
9916 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9917 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9919 if (targetUid > 0) {
9920 if (needed == null) {
9921 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9923 needed.add(grantUri);
9926 Intent clipIntent = clip.getItemAt(i).getIntent();
9927 if (clipIntent != null) {
9928 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9929 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9930 if (newNeeded != null) {
9942 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9945 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9946 UriPermissionOwner owner) {
9947 if (needed != null) {
9948 for (int i=0; i<needed.size(); i++) {
9949 GrantUri grantUri = needed.get(i);
9950 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9951 grantUri, needed.flags, owner);
9957 void grantUriPermissionFromIntentLocked(int callingUid,
9958 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9959 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9960 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9961 if (needed == null) {
9965 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9969 * @param uri This uri must NOT contain an embedded userId.
9970 * @param userId The userId in which the uri is to be resolved.
9973 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9974 final int modeFlags, int userId) {
9975 enforceNotIsolatedCaller("grantUriPermission");
9976 GrantUri grantUri = new GrantUri(userId, uri, false);
9977 synchronized(this) {
9978 final ProcessRecord r = getRecordForAppLocked(caller);
9980 throw new SecurityException("Unable to find app for caller "
9982 + " when granting permission to uri " + grantUri);
9984 if (targetPkg == null) {
9985 throw new IllegalArgumentException("null target");
9987 if (grantUri == null) {
9988 throw new IllegalArgumentException("null uri");
9991 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9992 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9993 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9994 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9996 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9997 UserHandle.getUserId(r.uid));
10002 void removeUriPermissionIfNeededLocked(UriPermission perm) {
10003 if (perm.modeFlags == 0) {
10004 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10006 if (perms != null) {
10007 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10008 "Removing " + perm.targetUid + " permission to " + perm.uri);
10010 perms.remove(perm.uri);
10011 if (perms.isEmpty()) {
10012 mGrantedUriPermissions.remove(perm.targetUid);
10019 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
10020 final int modeFlags) {
10021 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10022 "Revoking all granted permissions to " + grantUri);
10024 final IPackageManager pm = AppGlobals.getPackageManager();
10025 final String authority = grantUri.uri.getAuthority();
10026 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
10027 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10029 Slog.w(TAG, "No content provider found for permission revoke: "
10030 + grantUri.toSafeString());
10034 // Does the caller have this permission on the URI?
10035 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
10036 // If they don't have direct access to the URI, then revoke any
10037 // ownerless URI permissions that have been granted to them.
10038 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10039 if (perms != null) {
10040 boolean persistChanged = false;
10041 for (int i = perms.size()-1; i >= 0; i--) {
10042 final UriPermission perm = perms.valueAt(i);
10043 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
10046 if (perm.uri.sourceUserId == grantUri.sourceUserId
10047 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
10048 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10049 "Revoking non-owned " + perm.targetUid
10050 + " permission to " + perm.uri);
10051 persistChanged |= perm.revokeModes(
10052 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
10053 if (perm.modeFlags == 0) {
10058 if (perms.isEmpty()) {
10059 mGrantedUriPermissions.remove(callingUid);
10061 if (persistChanged) {
10062 schedulePersistUriGrants();
10068 boolean persistChanged = false;
10070 // Go through all of the permissions and remove any that match.
10071 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
10072 final int targetUid = mGrantedUriPermissions.keyAt(i);
10073 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10075 for (int j = perms.size()-1; j >= 0; j--) {
10076 final UriPermission perm = perms.valueAt(j);
10077 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
10080 if (perm.uri.sourceUserId == grantUri.sourceUserId
10081 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
10082 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10083 "Revoking " + perm.targetUid + " permission to " + perm.uri);
10084 persistChanged |= perm.revokeModes(
10085 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
10086 targetPackage == null);
10087 if (perm.modeFlags == 0) {
10093 if (perms.isEmpty()) {
10094 mGrantedUriPermissions.removeAt(i);
10098 if (persistChanged) {
10099 schedulePersistUriGrants();
10104 * @param uri This uri must NOT contain an embedded userId.
10105 * @param userId The userId in which the uri is to be resolved.
10108 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
10109 final int modeFlags, int userId) {
10110 enforceNotIsolatedCaller("revokeUriPermission");
10111 synchronized(this) {
10112 final ProcessRecord r = getRecordForAppLocked(caller);
10114 throw new SecurityException("Unable to find app for caller "
10116 + " when revoking permission to uri " + uri);
10119 Slog.w(TAG, "revokeUriPermission: null uri");
10123 if (!Intent.isAccessUriMode(modeFlags)) {
10127 final String authority = uri.getAuthority();
10128 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
10129 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10131 Slog.w(TAG, "No content provider found for permission revoke: "
10132 + uri.toSafeString());
10136 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
10142 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
10145 * @param packageName Package name to match, or {@code null} to apply to all
10147 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
10149 * @param persistable If persistable grants should be removed.
10150 * @param targetOnly When {@code true}, only remove permissions where the app is the target,
10154 private void removeUriPermissionsForPackageLocked(
10155 String packageName, int userHandle, boolean persistable, boolean targetOnly) {
10156 if (userHandle == UserHandle.USER_ALL && packageName == null) {
10157 throw new IllegalArgumentException("Must narrow by either package or user");
10160 boolean persistChanged = false;
10162 int N = mGrantedUriPermissions.size();
10163 for (int i = 0; i < N; i++) {
10164 final int targetUid = mGrantedUriPermissions.keyAt(i);
10165 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10167 // Only inspect grants matching user
10168 if (userHandle == UserHandle.USER_ALL
10169 || userHandle == UserHandle.getUserId(targetUid)) {
10170 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
10171 final UriPermission perm = it.next();
10173 // Only inspect grants matching package
10174 if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
10175 || perm.targetPkg.equals(packageName)) {
10176 // Hacky solution as part of fixing a security bug; ignore
10177 // grants associated with DownloadManager so we don't have
10178 // to immediately launch it to regrant the permissions
10179 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
10180 && !persistable) continue;
10182 persistChanged |= perm.revokeModes(persistable
10183 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
10185 // Only remove when no modes remain; any persisted grants
10186 // will keep this alive.
10187 if (perm.modeFlags == 0) {
10193 if (perms.isEmpty()) {
10194 mGrantedUriPermissions.remove(targetUid);
10201 if (persistChanged) {
10202 schedulePersistUriGrants();
10207 public IBinder newUriPermissionOwner(String name) {
10208 enforceNotIsolatedCaller("newUriPermissionOwner");
10209 synchronized(this) {
10210 UriPermissionOwner owner = new UriPermissionOwner(this, name);
10211 return owner.getExternalTokenLocked();
10216 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
10217 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
10218 synchronized(this) {
10219 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10221 throw new IllegalArgumentException("Activity does not exist; token="
10224 return r.getUriPermissionsLocked().getExternalTokenLocked();
10228 * @param uri This uri must NOT contain an embedded userId.
10229 * @param sourceUserId The userId in which the uri is to be resolved.
10230 * @param targetUserId The userId of the app that receives the grant.
10233 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
10234 final int modeFlags, int sourceUserId, int targetUserId) {
10235 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
10236 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
10237 "grantUriPermissionFromOwner", null);
10238 synchronized(this) {
10239 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10240 if (owner == null) {
10241 throw new IllegalArgumentException("Unknown owner: " + token);
10243 if (fromUid != Binder.getCallingUid()) {
10244 if (Binder.getCallingUid() != myUid()) {
10245 // Only system code can grant URI permissions on behalf
10247 throw new SecurityException("nice try");
10250 if (targetPkg == null) {
10251 throw new IllegalArgumentException("null target");
10254 throw new IllegalArgumentException("null uri");
10257 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
10258 modeFlags, owner, targetUserId);
10263 * @param uri This uri must NOT contain an embedded userId.
10264 * @param userId The userId in which the uri is to be resolved.
10267 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
10268 synchronized(this) {
10269 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10270 if (owner == null) {
10271 throw new IllegalArgumentException("Unknown owner: " + token);
10275 owner.removeUriPermissionsLocked(mode);
10277 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
10278 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
10283 private void schedulePersistUriGrants() {
10284 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
10285 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
10286 10 * DateUtils.SECOND_IN_MILLIS);
10290 private void writeGrantedUriPermissions() {
10291 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
10293 final long startTime = SystemClock.uptimeMillis();
10295 // Snapshot permissions so we can persist without lock
10296 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
10297 synchronized (this) {
10298 final int size = mGrantedUriPermissions.size();
10299 for (int i = 0; i < size; i++) {
10300 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10301 for (UriPermission perm : perms.values()) {
10302 if (perm.persistedModeFlags != 0) {
10303 persist.add(perm.snapshot());
10309 FileOutputStream fos = null;
10311 fos = mGrantFile.startWrite(startTime);
10313 XmlSerializer out = new FastXmlSerializer();
10314 out.setOutput(fos, StandardCharsets.UTF_8.name());
10315 out.startDocument(null, true);
10316 out.startTag(null, TAG_URI_GRANTS);
10317 for (UriPermission.Snapshot perm : persist) {
10318 out.startTag(null, TAG_URI_GRANT);
10319 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
10320 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
10321 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
10322 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
10323 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
10324 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
10325 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
10326 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
10327 out.endTag(null, TAG_URI_GRANT);
10329 out.endTag(null, TAG_URI_GRANTS);
10332 mGrantFile.finishWrite(fos);
10333 } catch (IOException e) {
10335 mGrantFile.failWrite(fos);
10341 private void readGrantedUriPermissionsLocked() {
10342 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
10344 final long now = System.currentTimeMillis();
10346 FileInputStream fis = null;
10348 fis = mGrantFile.openRead();
10349 final XmlPullParser in = Xml.newPullParser();
10350 in.setInput(fis, StandardCharsets.UTF_8.name());
10353 while ((type = in.next()) != END_DOCUMENT) {
10354 final String tag = in.getName();
10355 if (type == START_TAG) {
10356 if (TAG_URI_GRANT.equals(tag)) {
10357 final int sourceUserId;
10358 final int targetUserId;
10359 final int userHandle = readIntAttribute(in,
10360 ATTR_USER_HANDLE, UserHandle.USER_NULL);
10361 if (userHandle != UserHandle.USER_NULL) {
10362 // For backwards compatibility.
10363 sourceUserId = userHandle;
10364 targetUserId = userHandle;
10366 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
10367 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
10369 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
10370 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
10371 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
10372 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
10373 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
10374 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
10376 // Sanity check that provider still belongs to source package
10377 // Both direct boot aware and unaware packages are fine as we
10378 // will do filtering at query time to avoid multiple parsing.
10379 final ProviderInfo pi = getProviderInfoLocked(
10380 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
10381 | MATCH_DIRECT_BOOT_UNAWARE);
10382 if (pi != null && sourcePkg.equals(pi.packageName)) {
10383 int targetUid = -1;
10385 targetUid = AppGlobals.getPackageManager().getPackageUid(
10386 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
10387 } catch (RemoteException e) {
10389 if (targetUid != -1) {
10390 final UriPermission perm = findOrCreateUriPermissionLocked(
10391 sourcePkg, targetPkg, targetUid,
10392 new GrantUri(sourceUserId, uri, prefix));
10393 perm.initPersistedModes(modeFlags, createdTime);
10396 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10397 + " but instead found " + pi);
10402 } catch (FileNotFoundException e) {
10403 // Missing grants is okay
10404 } catch (IOException e) {
10405 Slog.wtf(TAG, "Failed reading Uri grants", e);
10406 } catch (XmlPullParserException e) {
10407 Slog.wtf(TAG, "Failed reading Uri grants", e);
10409 IoUtils.closeQuietly(fis);
10414 * @param uri This uri must NOT contain an embedded userId.
10415 * @param toPackage Name of package whose uri is being granted to (if {@code null}, uses
10417 * @param userId The userId in which the uri is to be resolved.
10420 public void takePersistableUriPermission(Uri uri, final int modeFlags,
10421 @Nullable String toPackage, int userId) {
10423 if (toPackage != null) {
10424 enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10425 "takePersistableUriPermission");
10426 uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10428 enforceNotIsolatedCaller("takePersistableUriPermission");
10429 uid = Binder.getCallingUid();
10432 Preconditions.checkFlagsArgument(modeFlags,
10433 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10435 synchronized (this) {
10436 boolean persistChanged = false;
10437 GrantUri grantUri = new GrantUri(userId, uri, false);
10439 UriPermission exactPerm = findUriPermissionLocked(uid, grantUri);
10440 UriPermission prefixPerm = findUriPermissionLocked(uid,
10441 new GrantUri(userId, uri, true));
10443 final boolean exactValid = (exactPerm != null)
10444 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10445 final boolean prefixValid = (prefixPerm != null)
10446 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10448 if (!(exactValid || prefixValid)) {
10449 throw new SecurityException("No persistable permission grants found for UID "
10450 + uid + " and Uri " + grantUri.toSafeString());
10454 persistChanged |= exactPerm.takePersistableModes(modeFlags);
10457 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10460 persistChanged |= maybePrunePersistedUriGrantsLocked(uid);
10462 if (persistChanged) {
10463 schedulePersistUriGrants();
10469 * @param uri This uri must NOT contain an embedded userId.
10470 * @param toPackage Name of the target package whose uri is being released (if {@code null},
10471 * uses calling uid)
10472 * @param userId The userId in which the uri is to be resolved.
10475 public void releasePersistableUriPermission(Uri uri, final int modeFlags,
10476 @Nullable String toPackage, int userId) {
10479 if (toPackage != null) {
10480 enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10481 "releasePersistableUriPermission");
10482 uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10484 enforceNotIsolatedCaller("releasePersistableUriPermission");
10485 uid = Binder.getCallingUid();
10488 Preconditions.checkFlagsArgument(modeFlags,
10489 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10491 synchronized (this) {
10492 boolean persistChanged = false;
10494 UriPermission exactPerm = findUriPermissionLocked(uid,
10495 new GrantUri(userId, uri, false));
10496 UriPermission prefixPerm = findUriPermissionLocked(uid,
10497 new GrantUri(userId, uri, true));
10498 if (exactPerm == null && prefixPerm == null && toPackage == null) {
10499 throw new SecurityException("No permission grants found for UID " + uid
10500 + " and Uri " + uri.toSafeString());
10503 if (exactPerm != null) {
10504 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10505 removeUriPermissionIfNeededLocked(exactPerm);
10507 if (prefixPerm != null) {
10508 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10509 removeUriPermissionIfNeededLocked(prefixPerm);
10512 if (persistChanged) {
10513 schedulePersistUriGrants();
10519 * Prune any older {@link UriPermission} for the given UID until outstanding
10520 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10522 * @return if any mutations occured that require persisting.
10525 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10526 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10527 if (perms == null) return false;
10528 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10530 final ArrayList<UriPermission> persisted = Lists.newArrayList();
10531 for (UriPermission perm : perms.values()) {
10532 if (perm.persistedModeFlags != 0) {
10533 persisted.add(perm);
10537 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10538 if (trimCount <= 0) return false;
10540 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10541 for (int i = 0; i < trimCount; i++) {
10542 final UriPermission perm = persisted.get(i);
10544 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10545 "Trimming grant created at " + perm.persistedCreateTime);
10547 perm.releasePersistableModes(~0);
10548 removeUriPermissionIfNeededLocked(perm);
10555 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10556 String packageName, boolean incoming) {
10557 enforceNotIsolatedCaller("getPersistedUriPermissions");
10558 Preconditions.checkNotNull(packageName, "packageName");
10560 final int callingUid = Binder.getCallingUid();
10561 final int callingUserId = UserHandle.getUserId(callingUid);
10562 final IPackageManager pm = AppGlobals.getPackageManager();
10564 final int packageUid = pm.getPackageUid(packageName,
10565 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10566 if (packageUid != callingUid) {
10567 throw new SecurityException(
10568 "Package " + packageName + " does not belong to calling UID " + callingUid);
10570 } catch (RemoteException e) {
10571 throw new SecurityException("Failed to verify package name ownership");
10574 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10575 synchronized (this) {
10577 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10579 if (perms == null) {
10580 Slog.w(TAG, "No permission grants found for " + packageName);
10582 for (int j = 0; j < perms.size(); j++) {
10583 final UriPermission perm = perms.valueAt(j);
10584 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10585 result.add(perm.buildPersistedPublicApiObject());
10590 final int size = mGrantedUriPermissions.size();
10591 for (int i = 0; i < size; i++) {
10592 final ArrayMap<GrantUri, UriPermission> perms =
10593 mGrantedUriPermissions.valueAt(i);
10594 for (int j = 0; j < perms.size(); j++) {
10595 final UriPermission perm = perms.valueAt(j);
10596 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10597 result.add(perm.buildPersistedPublicApiObject());
10603 return new ParceledListSlice<android.content.UriPermission>(result);
10607 public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10608 @Nullable String packageName, int userId) {
10609 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10610 "getGrantedUriPermissions");
10612 final List<GrantedUriPermission> result = new ArrayList<>();
10613 synchronized (this) {
10614 final int size = mGrantedUriPermissions.size();
10615 for (int i = 0; i < size; i++) {
10616 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10617 for (int j = 0; j < perms.size(); j++) {
10618 final UriPermission perm = perms.valueAt(j);
10619 if ((packageName == null || packageName.equals(perm.targetPkg))
10620 && perm.targetUserId == userId
10621 && perm.persistedModeFlags != 0) {
10622 result.add(perm.buildGrantedUriPermission());
10627 return new ParceledListSlice<>(result);
10631 public void clearGrantedUriPermissions(String packageName, int userId) {
10632 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10633 "clearGrantedUriPermissions");
10634 synchronized(this) {
10635 removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10640 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10641 synchronized (this) {
10642 ProcessRecord app =
10643 who != null ? getRecordForAppLocked(who) : null;
10644 if (app == null) return;
10646 Message msg = Message.obtain();
10647 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10649 msg.arg1 = waiting ? 1 : 0;
10650 mUiHandler.sendMessage(msg);
10655 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10656 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10657 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10658 outInfo.availMem = getFreeMemory();
10659 outInfo.totalMem = getTotalMemory();
10660 outInfo.threshold = homeAppMem;
10661 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10662 outInfo.hiddenAppThreshold = cachedAppMem;
10663 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10664 ProcessList.SERVICE_ADJ);
10665 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10666 ProcessList.VISIBLE_APP_ADJ);
10667 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10668 ProcessList.FOREGROUND_APP_ADJ);
10671 // =========================================================
10673 // =========================================================
10676 public List<IBinder> getAppTasks(String callingPackage) {
10677 int callingUid = Binder.getCallingUid();
10678 long ident = Binder.clearCallingIdentity();
10680 synchronized(this) {
10681 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10684 Binder.restoreCallingIdentity(ident);
10689 public List<RunningTaskInfo> getTasks(int maxNum) {
10690 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10694 public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10695 @WindowingMode int ignoreWindowingMode) {
10696 final int callingUid = Binder.getCallingUid();
10697 ArrayList<RunningTaskInfo> list = new ArrayList<>();
10699 synchronized(this) {
10700 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10702 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10704 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10705 ignoreWindowingMode, callingUid, allowed);
10711 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10712 if (mRecentTasks.isCallerRecents(callingUid)) {
10713 // Always allow the recents component to get tasks
10717 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10718 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10720 if (checkPermission(android.Manifest.permission.GET_TASKS,
10721 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10722 // Temporary compatibility: some existing apps on the system image may
10723 // still be requesting the old permission and not switched to the new
10724 // one; if so, we'll still allow them full access. This means we need
10725 // to see if they are holding the old permission and are a system app.
10727 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10729 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10730 + " is using old GET_TASKS but privileged; allowing");
10732 } catch (RemoteException e) {
10737 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10738 + " does not hold REAL_GET_TASKS; limiting output");
10744 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10746 final int callingUid = Binder.getCallingUid();
10747 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10748 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10749 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10751 final boolean detailed = checkCallingPermission(
10752 android.Manifest.permission.GET_DETAILED_TASKS)
10753 == PackageManager.PERMISSION_GRANTED;
10755 synchronized (this) {
10756 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10762 public ActivityManager.TaskDescription getTaskDescription(int id) {
10763 synchronized (this) {
10764 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10765 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10766 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10768 return tr.lastTaskDescription;
10775 public int addAppTask(IBinder activityToken, Intent intent,
10776 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10777 final int callingUid = Binder.getCallingUid();
10778 final long callingIdent = Binder.clearCallingIdentity();
10781 synchronized (this) {
10782 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10784 throw new IllegalArgumentException("Activity does not exist; token="
10787 ComponentName comp = intent.getComponent();
10788 if (comp == null) {
10789 throw new IllegalArgumentException("Intent " + intent
10790 + " must specify explicit component");
10792 if (thumbnail.getWidth() != mThumbnailWidth
10793 || thumbnail.getHeight() != mThumbnailHeight) {
10794 throw new IllegalArgumentException("Bad thumbnail size: got "
10795 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10796 + mThumbnailWidth + "x" + mThumbnailHeight);
10798 if (intent.getSelector() != null) {
10799 intent.setSelector(null);
10801 if (intent.getSourceBounds() != null) {
10802 intent.setSourceBounds(null);
10804 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10805 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10806 // The caller has added this as an auto-remove task... that makes no
10807 // sense, so turn off auto-remove.
10808 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10811 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
10812 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
10813 if (ainfo.applicationInfo.uid != callingUid) {
10814 throw new SecurityException(
10815 "Can't add task for another application: target uid="
10816 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10819 final ActivityStack stack = r.getStack();
10820 final TaskRecord task = stack.createTaskRecord(
10821 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
10822 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
10823 if (!mRecentTasks.addToBottom(task)) {
10824 // The app has too many tasks already and we can't add any more
10825 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
10826 return INVALID_TASK_ID;
10828 task.lastTaskDescription.copyFrom(description);
10830 // TODO: Send the thumbnail to WM to store it.
10832 return task.taskId;
10835 Binder.restoreCallingIdentity(callingIdent);
10840 public Point getAppTaskThumbnailSize() {
10841 synchronized (this) {
10842 return new Point(mThumbnailWidth, mThumbnailHeight);
10847 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10848 synchronized (this) {
10849 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10851 r.setTaskDescription(td);
10852 final TaskRecord task = r.getTask();
10853 task.updateTaskDescription();
10854 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10860 public void setTaskResizeable(int taskId, int resizeableMode) {
10861 synchronized (this) {
10862 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10863 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10864 if (task == null) {
10865 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10868 task.setResizeMode(resizeableMode);
10873 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10874 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10875 long ident = Binder.clearCallingIdentity();
10877 synchronized (this) {
10878 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10879 if (task == null) {
10880 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10883 // Place the task in the right stack if it isn't there already based on
10884 // the requested bounds.
10885 // The stack transition logic is:
10886 // - a null bounds on a freeform task moves that task to fullscreen
10887 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10888 // that task to freeform
10889 // - otherwise the task is not moved
10890 ActivityStack stack = task.getStack();
10891 if (!task.getWindowConfiguration().canResizeTask()) {
10892 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10894 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10895 stack = stack.getDisplay().getOrCreateStack(
10896 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10897 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10898 stack = stack.getDisplay().getOrCreateStack(
10899 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10902 // Reparent the task to the right stack if necessary
10903 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10904 if (stack != task.getStack()) {
10905 // Defer resume until the task is resized below
10906 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10907 DEFER_RESUME, "resizeTask");
10908 preserveWindow = false;
10911 // After reparenting (which only resizes the task to the stack bounds), resize the
10912 // task to the actual bounds provided
10913 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10916 Binder.restoreCallingIdentity(ident);
10921 public Rect getTaskBounds(int taskId) {
10922 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10923 long ident = Binder.clearCallingIdentity();
10924 Rect rect = new Rect();
10926 synchronized (this) {
10927 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10928 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10929 if (task == null) {
10930 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10933 if (task.getStack() != null) {
10934 // Return the bounds from window manager since it will be adjusted for various
10935 // things like the presense of a docked stack for tasks that aren't resizeable.
10936 task.getWindowContainerBounds(rect);
10938 // Task isn't in window manager yet since it isn't associated with a stack.
10939 // Return the persist value from activity manager
10940 if (!task.matchParentBounds()) {
10941 rect.set(task.getBounds());
10942 } else if (task.mLastNonFullscreenBounds != null) {
10943 rect.set(task.mLastNonFullscreenBounds);
10948 Binder.restoreCallingIdentity(ident);
10954 public void cancelTaskWindowTransition(int taskId) {
10955 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10956 "cancelTaskWindowTransition()");
10957 final long ident = Binder.clearCallingIdentity();
10959 synchronized (this) {
10960 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10961 MATCH_TASK_IN_STACKS_ONLY);
10962 if (task == null) {
10963 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10966 task.cancelWindowTransition();
10969 Binder.restoreCallingIdentity(ident);
10974 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10975 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10976 final long ident = Binder.clearCallingIdentity();
10978 final TaskRecord task;
10979 synchronized (this) {
10980 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10981 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10982 if (task == null) {
10983 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10987 // Don't call this while holding the lock as this operation might hit the disk.
10988 return task.getSnapshot(reducedResolution);
10990 Binder.restoreCallingIdentity(ident);
10995 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10996 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10997 userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
10999 final File passedIconFile = new File(filePath);
11000 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
11001 passedIconFile.getName());
11002 if (!legitIconFile.getPath().equals(filePath)
11003 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
11004 throw new IllegalArgumentException("Bad file path: " + filePath
11005 + " passed for userId " + userId);
11007 return mRecentTasks.getTaskDescriptionIcon(filePath);
11011 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
11012 throws RemoteException {
11013 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
11014 final ActivityOptions activityOptions = safeOptions != null
11015 ? safeOptions.getOptions(mStackSupervisor)
11017 if (activityOptions == null
11018 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
11019 || activityOptions.getCustomInPlaceResId() == 0) {
11020 throw new IllegalArgumentException("Expected in-place ActivityOption " +
11021 "with valid animation");
11023 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
11024 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
11025 activityOptions.getCustomInPlaceResId());
11026 mWindowManager.executeAppTransition();
11030 public void removeStack(int stackId) {
11031 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
11032 synchronized (this) {
11033 final long ident = Binder.clearCallingIdentity();
11035 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11036 if (stack == null) {
11037 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
11040 if (!stack.isActivityTypeStandardOrUndefined()) {
11041 throw new IllegalArgumentException(
11042 "Removing non-standard stack is not allowed.");
11044 mStackSupervisor.removeStack(stack);
11046 Binder.restoreCallingIdentity(ident);
11052 * Removes stacks in the input windowing modes from the system if they are of activity type
11053 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
11056 public void removeStacksInWindowingModes(int[] windowingModes) {
11057 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11058 "removeStacksInWindowingModes()");
11059 synchronized (this) {
11060 final long ident = Binder.clearCallingIdentity();
11062 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
11064 Binder.restoreCallingIdentity(ident);
11070 public void removeStacksWithActivityTypes(int[] activityTypes) {
11071 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11072 "removeStacksWithActivityTypes()");
11073 synchronized (this) {
11074 final long ident = Binder.clearCallingIdentity();
11076 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
11078 Binder.restoreCallingIdentity(ident);
11084 * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
11087 String getPendingTempWhitelistTagForUidLocked(int uid) {
11088 final PendingTempWhitelist ptw = mPendingTempWhitelist.get(uid);
11089 return ptw != null ? ptw.tag : null;
11093 boolean isActivityStartsLoggingEnabled() {
11094 return mConstants.mFlagActivityStartsLoggingEnabled;
11098 public void moveStackToDisplay(int stackId, int displayId) {
11099 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
11101 synchronized (this) {
11102 final long ident = Binder.clearCallingIdentity();
11104 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
11105 + " to displayId=" + displayId);
11106 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
11108 Binder.restoreCallingIdentity(ident);
11114 public boolean removeTask(int taskId) {
11115 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
11116 synchronized (this) {
11117 final long ident = Binder.clearCallingIdentity();
11119 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
11122 Binder.restoreCallingIdentity(ident);
11128 * TODO: Add mController hook
11131 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
11132 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
11134 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
11135 synchronized(this) {
11136 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
11137 false /* fromRecents */);
11141 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
11142 boolean fromRecents) {
11144 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11145 Binder.getCallingUid(), -1, -1, "Task to front")) {
11146 SafeActivityOptions.abort(options);
11149 final long origId = Binder.clearCallingIdentity();
11151 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11152 if (task == null) {
11153 Slog.d(TAG, "Could not find task for id: "+ taskId);
11156 if (mLockTaskController.isLockTaskModeViolation(task)) {
11157 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
11160 ActivityOptions realOptions = options != null
11161 ? options.getOptions(mStackSupervisor)
11163 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
11164 false /* forceNonResizable */);
11166 final ActivityRecord topActivity = task.getTopActivity();
11167 if (topActivity != null) {
11169 // We are reshowing a task, use a starting window to hide the initial draw delay
11170 // so the transition can start earlier.
11171 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
11172 true /* taskSwitch */, fromRecents);
11175 Binder.restoreCallingIdentity(origId);
11177 SafeActivityOptions.abort(options);
11181 * Attempts to move a task backwards in z-order (the order of activities within the task is
11184 * There are several possible results of this call:
11185 * - if the task is locked, then we will show the lock toast
11186 * - if there is a task behind the provided task, then that task is made visible and resumed as
11187 * this task is moved to the back
11188 * - otherwise, if there are no other tasks in the stack:
11189 * - if this task is in the pinned stack, then we remove the stack completely, which will
11190 * have the effect of moving the task to the top or bottom of the fullscreen stack
11191 * (depending on whether it is visible)
11192 * - otherwise, we simply return home and hide this task
11194 * @param token A reference to the activity we wish to move
11195 * @param nonRoot If false then this only works if the activity is the root
11196 * of a task; if true it will work for any activity in a task.
11197 * @return Returns true if the move completed, false if not.
11200 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
11201 enforceNotIsolatedCaller("moveActivityTaskToBack");
11202 synchronized(this) {
11203 final long origId = Binder.clearCallingIdentity();
11205 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
11206 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11207 if (task != null) {
11208 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
11211 Binder.restoreCallingIdentity(origId);
11218 public void moveTaskBackwards(int task) {
11219 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
11220 "moveTaskBackwards()");
11222 synchronized(this) {
11223 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11224 Binder.getCallingUid(), -1, -1, "Task backwards")) {
11227 final long origId = Binder.clearCallingIdentity();
11228 moveTaskBackwardsLocked(task);
11229 Binder.restoreCallingIdentity(origId);
11233 private final void moveTaskBackwardsLocked(int task) {
11234 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
11238 public int createStackOnDisplay(int displayId) throws RemoteException {
11239 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
11240 synchronized (this) {
11241 final ActivityDisplay display =
11242 mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
11243 if (display == null) {
11244 return INVALID_STACK_ID;
11246 // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
11247 final ActivityStack stack = display.createStack(
11248 WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
11250 return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
11255 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
11256 synchronized (this) {
11257 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
11258 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
11259 return stack.mDisplayId;
11261 return DEFAULT_DISPLAY;
11266 public void exitFreeformMode(IBinder token) throws RemoteException {
11267 synchronized (this) {
11268 long ident = Binder.clearCallingIdentity();
11270 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11272 throw new IllegalArgumentException(
11273 "exitFreeformMode: No activity record matching token=" + token);
11276 final ActivityStack stack = r.getStack();
11277 if (stack == null || !stack.inFreeformWindowingMode()) {
11278 throw new IllegalStateException(
11279 "exitFreeformMode: You can only go fullscreen from freeform.");
11282 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11284 Binder.restoreCallingIdentity(ident);
11290 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
11291 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
11292 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
11293 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
11296 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
11297 synchronized (this) {
11298 final long ident = Binder.clearCallingIdentity();
11300 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11301 if (task == null) {
11302 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
11306 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
11307 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
11309 if (!task.isActivityTypeStandardOrUndefined()) {
11310 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11311 + " non-standard task " + taskId + " to windowing mode="
11315 final ActivityStack stack = task.getStack();
11317 stack.moveToFront("setTaskWindowingMode", task);
11319 stack.setWindowingMode(windowingMode);
11321 Binder.restoreCallingIdentity(ident);
11327 * Moves the specified task to the primary-split-screen stack.
11329 * @param taskId Id of task to move.
11330 * @param createMode The mode the primary split screen stack should be created in if it doesn't
11331 * exist already. See
11332 * {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
11334 * {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
11335 * @param toTop If the task and stack should be moved to the top.
11336 * @param animate Whether we should play an animation for the moving the task.
11337 * @param initialBounds If the primary stack gets created, it will use these bounds for the
11338 * stack. Pass {@code null} to use default bounds.
11339 * @param showRecents If the recents activity should be shown on the other side of the task
11340 * going into split-screen mode.
11343 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
11344 boolean animate, Rect initialBounds, boolean showRecents) {
11345 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11346 "setTaskWindowingModeSplitScreenPrimary()");
11347 synchronized (this) {
11348 long ident = Binder.clearCallingIdentity();
11350 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11351 if (task == null) {
11352 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
11355 if (DEBUG_STACK) Slog.d(TAG_STACK,
11356 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
11357 + " to createMode=" + createMode + " toTop=" + toTop);
11358 if (!task.isActivityTypeStandardOrUndefined()) {
11359 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11360 + " non-standard task " + taskId + " to split-screen windowing mode");
11363 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
11364 final int windowingMode = task.getWindowingMode();
11365 final ActivityStack stack = task.getStack();
11367 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
11369 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
11370 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
11371 return windowingMode != task.getWindowingMode();
11373 Binder.restoreCallingIdentity(ident);
11379 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
11380 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
11381 synchronized (this) {
11382 long ident = Binder.clearCallingIdentity();
11384 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11385 if (task == null) {
11386 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
11390 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
11391 + " to stackId=" + stackId + " toTop=" + toTop);
11393 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11394 if (stack == null) {
11395 throw new IllegalStateException(
11396 "moveTaskToStack: No stack for stackId=" + stackId);
11398 if (!stack.isActivityTypeStandardOrUndefined()) {
11399 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
11400 + taskId + " to stack " + stackId);
11402 if (stack.inSplitScreenPrimaryWindowingMode()) {
11403 mWindowManager.setDockedStackCreateState(
11404 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
11406 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
11407 "moveTaskToStack");
11409 Binder.restoreCallingIdentity(ident);
11415 * Dismisses split-screen multi-window mode.
11416 * @param toTop If true the current primary split-screen stack will be placed or left on top.
11419 public void dismissSplitScreenMode(boolean toTop) {
11420 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
11421 final long ident = Binder.clearCallingIdentity();
11423 synchronized (this) {
11424 final ActivityStack stack =
11425 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
11426 if (stack == null) {
11427 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
11432 // Caller wants the current split-screen primary stack to be the top stack after
11433 // it goes fullscreen, so move it to the front.
11434 stack.moveToFront("dismissSplitScreenMode");
11435 } else if (mStackSupervisor.isFocusedStack(stack)) {
11436 // In this case the current split-screen primary stack shouldn't be the top
11437 // stack after it goes fullscreen, but it current has focus, so we move the
11438 // focus to the top-most split-screen secondary stack next to it.
11439 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
11440 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
11441 if (otherStack != null) {
11442 otherStack.moveToFront("dismissSplitScreenMode_other");
11446 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11449 Binder.restoreCallingIdentity(ident);
11455 * @param animate True if the dismissal should be animated.
11456 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
11457 * default animation duration should be used.
11460 public void dismissPip(boolean animate, int animationDuration) {
11461 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11462 final long ident = Binder.clearCallingIdentity();
11464 synchronized (this) {
11465 final PinnedActivityStack stack =
11466 mStackSupervisor.getDefaultDisplay().getPinnedStack();
11467 if (stack == null) {
11468 Slog.w(TAG, "dismissPip: pinned stack not found.");
11471 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11472 throw new IllegalArgumentException("Stack: " + stack
11473 + " doesn't support animated resize.");
11476 stack.animateResizePinnedStack(null /* sourceHintBounds */,
11477 null /* destBounds */, animationDuration, false /* fromFullscreen */);
11479 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11483 Binder.restoreCallingIdentity(ident);
11488 * Moves the top activity in the input stackId to the pinned stack.
11490 * @param stackId Id of stack to move the top activity to pinned stack.
11491 * @param bounds Bounds to use for pinned stack.
11493 * @return True if the top activity of the input stack was successfully moved to the pinned
11497 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11498 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11499 "moveTopActivityToPinnedStack()");
11500 synchronized (this) {
11501 if (!mSupportsPictureInPicture) {
11502 throw new IllegalStateException("moveTopActivityToPinnedStack:"
11503 + "Device doesn't support picture-in-picture mode");
11506 long ident = Binder.clearCallingIdentity();
11508 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11510 Binder.restoreCallingIdentity(ident);
11516 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11517 boolean preserveWindows, boolean animate, int animationDuration) {
11518 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11519 long ident = Binder.clearCallingIdentity();
11521 synchronized (this) {
11523 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11524 if (stack == null) {
11525 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11528 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11529 throw new IllegalArgumentException("Stack: " + stackId
11530 + " doesn't support animated resize.");
11532 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11533 animationDuration, false /* fromFullscreen */);
11535 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11536 if (stack == null) {
11537 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11540 mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11541 null /* tempTaskInsetBounds */, preserveWindows,
11542 allowResizeInDockedMode, !DEFER_RESUME);
11546 Binder.restoreCallingIdentity(ident);
11551 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11552 Rect tempDockedTaskInsetBounds,
11553 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11554 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11555 long ident = Binder.clearCallingIdentity();
11557 synchronized (this) {
11558 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11559 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11563 Binder.restoreCallingIdentity(ident);
11568 public void setSplitScreenResizing(boolean resizing) {
11569 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
11570 final long ident = Binder.clearCallingIdentity();
11572 synchronized (this) {
11573 mStackSupervisor.setSplitScreenResizing(resizing);
11576 Binder.restoreCallingIdentity(ident);
11581 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11582 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11583 final long ident = Binder.clearCallingIdentity();
11585 synchronized (this) {
11586 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11589 Binder.restoreCallingIdentity(ident);
11594 * Try to place task to provided position. The final position might be different depending on
11595 * current user and stacks state. The task will be moved to target stack if it's currently in
11599 public void positionTaskInStack(int taskId, int stackId, int position) {
11600 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11601 synchronized (this) {
11602 long ident = Binder.clearCallingIdentity();
11604 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11605 + taskId + " in stackId=" + stackId + " at position=" + position);
11606 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11607 if (task == null) {
11608 throw new IllegalArgumentException("positionTaskInStack: no task for id="
11612 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11614 if (stack == null) {
11615 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11618 if (!stack.isActivityTypeStandardOrUndefined()) {
11619 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11620 + " the position of task " + taskId + " in/to non-standard stack");
11623 // TODO: Have the callers of this API call a separate reparent method if that is
11624 // what they intended to do vs. having this method also do reparenting.
11625 if (task.getStack() == stack) {
11626 // Change position in current stack.
11627 stack.positionChildAt(task, position);
11629 // Reparent to new stack.
11630 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11631 !DEFER_RESUME, "positionTaskInStack");
11634 Binder.restoreCallingIdentity(ident);
11640 public List<StackInfo> getAllStackInfos() {
11641 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11642 long ident = Binder.clearCallingIdentity();
11644 synchronized (this) {
11645 return mStackSupervisor.getAllStackInfosLocked();
11648 Binder.restoreCallingIdentity(ident);
11653 public StackInfo getStackInfo(int windowingMode, int activityType) {
11654 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11655 long ident = Binder.clearCallingIdentity();
11657 synchronized (this) {
11658 return mStackSupervisor.getStackInfo(windowingMode, activityType);
11661 Binder.restoreCallingIdentity(ident);
11666 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11667 synchronized(this) {
11668 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11673 public void updateDeviceOwner(String packageName) {
11674 final int callingUid = Binder.getCallingUid();
11675 if (callingUid != 0 && callingUid != SYSTEM_UID) {
11676 throw new SecurityException("updateDeviceOwner called from non-system process");
11678 synchronized (this) {
11679 mDeviceOwnerName = packageName;
11684 public void updateLockTaskPackages(int userId, String[] packages) {
11685 final int callingUid = Binder.getCallingUid();
11686 if (callingUid != 0 && callingUid != SYSTEM_UID) {
11687 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11688 "updateLockTaskPackages()");
11690 synchronized (this) {
11691 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11692 Arrays.toString(packages));
11693 mLockTaskController.updateLockTaskPackages(userId, packages);
11698 public void updateLockTaskFeatures(int userId, int flags) {
11699 final int callingUid = Binder.getCallingUid();
11700 if (callingUid != 0 && callingUid != SYSTEM_UID) {
11701 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11702 "updateLockTaskFeatures()");
11704 synchronized (this) {
11705 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11706 Integer.toHexString(flags));
11707 mLockTaskController.updateLockTaskFeatures(userId, flags);
11711 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11712 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11713 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11717 final ActivityStack stack = mStackSupervisor.getFocusedStack();
11718 if (stack == null || task != stack.topTask()) {
11719 throw new IllegalArgumentException("Invalid task, not in foreground");
11722 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11723 // system or a specific app.
11724 // * System-initiated requests will only start the pinned mode (screen pinning)
11725 // * App-initiated requests
11726 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
11727 // - will start the pinned mode, otherwise
11728 final int callingUid = Binder.getCallingUid();
11729 long ident = Binder.clearCallingIdentity();
11731 // When a task is locked, dismiss the pinned stack if it exists
11732 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11734 mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11736 Binder.restoreCallingIdentity(ident);
11741 public void startLockTaskModeByToken(IBinder token) {
11742 synchronized (this) {
11743 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11747 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11752 public void startSystemLockTaskMode(int taskId) throws RemoteException {
11753 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11754 // This makes inner call to look as if it was initiated by system.
11755 long ident = Binder.clearCallingIdentity();
11757 synchronized (this) {
11758 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11760 // When starting lock task mode the stack must be in front and focused
11761 task.getStack().moveToFront("startSystemLockTaskMode");
11762 startLockTaskModeLocked(task, true /* isSystemCaller */);
11765 Binder.restoreCallingIdentity(ident);
11770 public void stopLockTaskModeByToken(IBinder token) {
11771 synchronized (this) {
11772 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11776 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11781 * This API should be called by SystemUI only when user perform certain action to dismiss
11782 * lock task mode. We should only dismiss pinned lock task mode in this case.
11785 public void stopSystemLockTaskMode() throws RemoteException {
11786 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11787 stopLockTaskModeInternal(null, true /* isSystemCaller */);
11790 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11791 final int callingUid = Binder.getCallingUid();
11792 long ident = Binder.clearCallingIdentity();
11794 synchronized (this) {
11795 mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11797 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11798 // task and jumping straight into a call in the case of emergency call back.
11799 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11801 tm.showInCallScreen(false);
11804 Binder.restoreCallingIdentity(ident);
11809 public boolean isInLockTaskMode() {
11810 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11814 public int getLockTaskModeState() {
11815 synchronized (this) {
11816 return mLockTaskController.getLockTaskModeState();
11821 public void showLockTaskEscapeMessage(IBinder token) {
11822 synchronized (this) {
11823 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11827 mLockTaskController.showLockTaskToast();
11832 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11833 throws RemoteException {
11834 synchronized (this) {
11835 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11837 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11841 final long origId = Binder.clearCallingIdentity();
11843 r.setDisablePreviewScreenshots(disable);
11845 Binder.restoreCallingIdentity(origId);
11850 // =========================================================
11851 // CONTENT PROVIDERS
11852 // =========================================================
11854 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11855 List<ProviderInfo> providers = null;
11857 providers = AppGlobals.getPackageManager()
11858 .queryContentProviders(app.processName, app.uid,
11859 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11860 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11862 } catch (RemoteException ex) {
11864 if (DEBUG_MU) Slog.v(TAG_MU,
11865 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11866 int userId = app.userId;
11867 if (providers != null) {
11868 int N = providers.size();
11869 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11870 for (int i=0; i<N; i++) {
11871 // TODO: keep logic in sync with installEncryptionUnawareProviders
11873 (ProviderInfo)providers.get(i);
11874 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11875 cpi.name, cpi.flags);
11876 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11877 // This is a singleton provider, but a user besides the
11878 // default user is asking to initialize a process it runs
11879 // in... well, no, it doesn't actually run in this process,
11880 // it runs in the process of the default user. Get rid of it.
11881 providers.remove(i);
11887 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11888 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11890 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11891 mProviderMap.putProviderByClass(comp, cpr);
11893 if (DEBUG_MU) Slog.v(TAG_MU,
11894 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11895 app.pubProviders.put(cpi.name, cpr);
11896 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11897 // Don't add this if it is a platform component that is marked
11898 // to run in multiple processes, because this is actually
11899 // part of the framework so doesn't make sense to track as a
11900 // separate apk in the process.
11901 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11904 notifyPackageUse(cpi.applicationInfo.packageName,
11905 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11912 * Check if the calling UID has a possible chance at accessing the provider
11913 * at the given authority and user.
11915 public String checkContentProviderAccess(String authority, int userId) {
11916 if (userId == UserHandle.USER_ALL) {
11917 mContext.enforceCallingOrSelfPermission(
11918 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11919 userId = UserHandle.getCallingUserId();
11922 ProviderInfo cpi = null;
11924 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11925 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11926 | PackageManager.MATCH_DISABLED_COMPONENTS
11927 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11928 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11930 } catch (RemoteException ignored) {
11933 return "Failed to find provider " + authority + " for user " + userId
11934 + "; expected to find a valid ContentProvider for this authority";
11937 ProcessRecord r = null;
11938 synchronized (mPidsSelfLocked) {
11939 r = mPidsSelfLocked.get(Binder.getCallingPid());
11942 return "Failed to find PID " + Binder.getCallingPid();
11945 synchronized (this) {
11946 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11951 * Check if {@link ProcessRecord} has a possible chance at accessing the
11952 * given {@link ProviderInfo}. Final permission checking is always done
11953 * in {@link ContentProvider}.
11955 private final String checkContentProviderPermissionLocked(
11956 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11957 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11958 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11959 boolean checkedGrants = false;
11961 // Looking for cross-user grants before enforcing the typical cross-users permissions
11962 int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11963 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11964 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11967 checkedGrants = true;
11969 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11970 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11971 if (userId != tmpTargetUserId) {
11972 // When we actually went to determine the final targer user ID, this ended
11973 // up different than our initial check for the authority. This is because
11974 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11975 // SELF. So we need to re-check the grants again.
11976 checkedGrants = false;
11979 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11980 cpi.applicationInfo.uid, cpi.exported)
11981 == PackageManager.PERMISSION_GRANTED) {
11984 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11985 cpi.applicationInfo.uid, cpi.exported)
11986 == PackageManager.PERMISSION_GRANTED) {
11990 PathPermission[] pps = cpi.pathPermissions;
11992 int i = pps.length;
11995 PathPermission pp = pps[i];
11996 String pprperm = pp.getReadPermission();
11997 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11998 cpi.applicationInfo.uid, cpi.exported)
11999 == PackageManager.PERMISSION_GRANTED) {
12002 String ppwperm = pp.getWritePermission();
12003 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
12004 cpi.applicationInfo.uid, cpi.exported)
12005 == PackageManager.PERMISSION_GRANTED) {
12010 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
12014 final String suffix;
12015 if (!cpi.exported) {
12016 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
12017 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
12018 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
12020 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
12022 final String msg = "Permission Denial: opening provider " + cpi.name
12023 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
12024 + ", uid=" + callingUid + ")" + suffix;
12030 * Returns if the ContentProvider has granted a uri to callingUid
12032 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
12033 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
12034 if (perms != null) {
12035 for (int i=perms.size()-1; i>=0; i--) {
12036 GrantUri grantUri = perms.keyAt(i);
12037 if (grantUri.sourceUserId == userId || !checkUser) {
12038 if (matchesProvider(grantUri.uri, cpi)) {
12048 * Returns true if the uri authority is one of the authorities specified in the provider.
12050 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
12051 String uriAuth = uri.getAuthority();
12052 String cpiAuth = cpi.authority;
12053 if (cpiAuth.indexOf(';') == -1) {
12054 return cpiAuth.equals(uriAuth);
12056 String[] cpiAuths = cpiAuth.split(";");
12057 int length = cpiAuths.length;
12058 for (int i = 0; i < length; i++) {
12059 if (cpiAuths[i].equals(uriAuth)) return true;
12064 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
12065 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
12067 for (int i=0; i<r.conProviders.size(); i++) {
12068 ContentProviderConnection conn = r.conProviders.get(i);
12069 if (conn.provider == cpr) {
12070 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
12071 "Adding provider requested by "
12072 + r.processName + " from process "
12073 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
12074 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
12076 conn.stableCount++;
12077 conn.numStableIncs++;
12079 conn.unstableCount++;
12080 conn.numUnstableIncs++;
12085 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
12087 conn.stableCount = 1;
12088 conn.numStableIncs = 1;
12090 conn.unstableCount = 1;
12091 conn.numUnstableIncs = 1;
12093 cpr.connections.add(conn);
12094 r.conProviders.add(conn);
12095 startAssociationLocked(r.uid, r.processName, r.curProcState,
12096 cpr.uid, cpr.name, cpr.info.processName);
12099 cpr.addExternalProcessHandleLocked(externalProcessToken);
12103 boolean decProviderCountLocked(ContentProviderConnection conn,
12104 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
12105 if (conn != null) {
12106 cpr = conn.provider;
12107 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
12108 "Removing provider requested by "
12109 + conn.client.processName + " from process "
12110 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
12111 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
12113 conn.stableCount--;
12115 conn.unstableCount--;
12117 if (conn.stableCount == 0 && conn.unstableCount == 0) {
12118 cpr.connections.remove(conn);
12119 conn.client.conProviders.remove(conn);
12120 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
12121 // The client is more important than last activity -- note the time this
12122 // is happening, so we keep the old provider process around a bit as last
12123 // activity to avoid thrashing it.
12124 if (cpr.proc != null) {
12125 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
12128 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
12133 cpr.removeExternalProcessHandleLocked(externalProcessToken);
12137 private void checkTime(long startTime, String where) {
12138 long now = SystemClock.uptimeMillis();
12139 if ((now-startTime) > 50) {
12140 // If we are taking more than 50ms, log about it.
12141 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
12145 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
12147 PROC_SPACE_TERM|PROC_PARENS,
12148 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
12151 private final long[] mProcessStateStatsLongs = new long[1];
12153 private boolean isProcessAliveLocked(ProcessRecord proc) {
12154 if (proc.pid <= 0) {
12155 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
12158 if (proc.procStatFile == null) {
12159 proc.procStatFile = "/proc/" + proc.pid + "/stat";
12161 mProcessStateStatsLongs[0] = 0;
12162 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
12163 mProcessStateStatsLongs, null)) {
12164 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
12167 final long state = mProcessStateStatsLongs[0];
12168 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
12170 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
12173 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
12174 String name, IBinder token, boolean stable, int userId) {
12175 ContentProviderRecord cpr;
12176 ContentProviderConnection conn = null;
12177 ProviderInfo cpi = null;
12178 boolean providerRunning = false;
12180 synchronized(this) {
12181 long startTime = SystemClock.uptimeMillis();
12183 ProcessRecord r = null;
12184 if (caller != null) {
12185 r = getRecordForAppLocked(caller);
12187 throw new SecurityException(
12188 "Unable to find app for caller " + caller
12189 + " (pid=" + Binder.getCallingPid()
12190 + ") when getting content provider " + name);
12194 boolean checkCrossUser = true;
12196 checkTime(startTime, "getContentProviderImpl: getProviderByName");
12198 // First check if this content provider has been published...
12199 cpr = mProviderMap.getProviderByName(name, userId);
12200 // If that didn't work, check if it exists for user 0 and then
12201 // verify that it's a singleton provider before using it.
12202 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
12203 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
12206 if (isSingleton(cpi.processName, cpi.applicationInfo,
12207 cpi.name, cpi.flags)
12208 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
12209 userId = UserHandle.USER_SYSTEM;
12210 checkCrossUser = false;
12218 if (cpr != null && cpr.proc != null) {
12219 providerRunning = !cpr.proc.killed;
12221 // Note if killedByAm is also set, this means the provider process has just been
12222 // killed by AM (in ProcessRecord.kill()), but appDiedLocked() hasn't been called
12223 // yet. So we need to call appDiedLocked() here and let it clean up.
12224 // (See the commit message on I2c4ba1e87c2d47f2013befff10c49b3dc337a9a7 to see
12225 // how to test this case.)
12226 if (cpr.proc.killed && cpr.proc.killedByAm) {
12227 checkTime(startTime, "getContentProviderImpl: before appDied (killedByAm)");
12228 final long iden = Binder.clearCallingIdentity();
12230 appDiedLocked(cpr.proc);
12232 Binder.restoreCallingIdentity(iden);
12234 checkTime(startTime, "getContentProviderImpl: after appDied (killedByAm)");
12238 if (providerRunning) {
12241 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12242 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
12244 throw new SecurityException(msg);
12246 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12248 if (r != null && cpr.canRunHere(r)) {
12249 // This provider has been published or is in the process
12250 // of being published... but it is also allowed to run
12251 // in the caller's process, so don't make a connection
12252 // and just let the caller instantiate its own instance.
12253 ContentProviderHolder holder = cpr.newHolder(null);
12254 // don't give caller the provider object, it needs
12255 // to make its own.
12256 holder.provider = null;
12259 // Don't expose providers between normal apps and instant apps
12261 if (AppGlobals.getPackageManager()
12262 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
12265 } catch (RemoteException e) {
12268 final long origId = Binder.clearCallingIdentity();
12270 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
12272 // In this case the provider instance already exists, so we can
12273 // return it right away.
12274 conn = incProviderCountLocked(r, cpr, token, stable);
12275 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
12276 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12277 // If this is a perceptible app accessing the provider,
12278 // make sure to count it as being accessed and thus
12279 // back up on the LRU list. This is good because
12280 // content providers are often expensive to start.
12281 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
12282 updateLruProcessLocked(cpr.proc, false, null);
12283 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
12287 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
12288 final int verifiedAdj = cpr.proc.verifiedAdj;
12289 boolean success = updateOomAdjLocked(cpr.proc, true);
12290 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
12291 // if the process has been successfully adjusted. So to reduce races with
12292 // it, we will check whether the process still exists. Note that this doesn't
12293 // completely get rid of races with LMK killing the process, but should make
12294 // them much smaller.
12295 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
12298 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
12299 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
12300 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
12301 // NOTE: there is still a race here where a signal could be
12302 // pending on the process even though we managed to update its
12303 // adj level. Not sure what to do about this, but at least
12304 // the race is now smaller.
12306 // Uh oh... it looks like the provider's process
12307 // has been killed on us. We need to wait for a new
12308 // process to be started, and make sure its death
12309 // doesn't kill our process.
12310 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
12311 + " is crashing; detaching " + r);
12312 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
12313 checkTime(startTime, "getContentProviderImpl: before appDied");
12314 appDiedLocked(cpr.proc);
12315 checkTime(startTime, "getContentProviderImpl: after appDied");
12317 // This wasn't the last ref our process had on
12318 // the provider... we have now been killed, bail.
12321 providerRunning = false;
12324 cpr.proc.verifiedAdj = cpr.proc.setAdj;
12327 Binder.restoreCallingIdentity(origId);
12330 if (!providerRunning) {
12332 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
12333 cpi = AppGlobals.getPackageManager().
12334 resolveContentProvider(name,
12335 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
12336 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
12337 } catch (RemoteException ex) {
12342 // If the provider is a singleton AND
12343 // (it's a call within the same user || the provider is a
12345 // Then allow connecting to the singleton provider
12346 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
12347 cpi.name, cpi.flags)
12348 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
12350 userId = UserHandle.USER_SYSTEM;
12352 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
12353 checkTime(startTime, "getContentProviderImpl: got app info for user");
12356 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12357 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
12359 throw new SecurityException(msg);
12361 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12363 if (!mProcessesReady
12364 && !cpi.processName.equals("system")) {
12365 // If this content provider does not run in the system
12366 // process, and the system is not yet ready to run other
12367 // processes, then fail fast instead of hanging.
12368 throw new IllegalArgumentException(
12369 "Attempt to launch content provider before system ready");
12372 // If system providers are not installed yet we aggressively crash to avoid
12373 // creating multiple instance of these providers and then bad things happen!
12374 if (!mSystemProvidersInstalled && cpi.applicationInfo.isSystemApp()
12375 && "system".equals(cpi.processName)) {
12376 throw new IllegalStateException("Cannot access system provider: '"
12377 + cpi.authority + "' before system providers are installed!");
12380 // Make sure that the user who owns this provider is running. If not,
12381 // we don't want to allow it to run.
12382 if (!mUserController.isUserRunning(userId, 0)) {
12383 Slog.w(TAG, "Unable to launch app "
12384 + cpi.applicationInfo.packageName + "/"
12385 + cpi.applicationInfo.uid + " for provider "
12386 + name + ": user " + userId + " is stopped");
12390 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
12391 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
12392 cpr = mProviderMap.getProviderByClass(comp, userId);
12393 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
12394 final boolean firstClass = cpr == null;
12396 final long ident = Binder.clearCallingIdentity();
12398 // If permissions need a review before any of the app components can run,
12399 // we return no provider and launch a review activity if the calling app
12400 // is in the foreground.
12401 if (mPermissionReviewRequired) {
12402 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
12408 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
12409 ApplicationInfo ai =
12410 AppGlobals.getPackageManager().
12411 getApplicationInfo(
12412 cpi.applicationInfo.packageName,
12413 STOCK_PM_FLAGS, userId);
12414 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
12416 Slog.w(TAG, "No package info for content provider "
12420 ai = getAppInfoForUser(ai, userId);
12421 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
12422 } catch (RemoteException ex) {
12423 // pm is in same process, this will never happen.
12425 Binder.restoreCallingIdentity(ident);
12429 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
12431 if (r != null && cpr.canRunHere(r)) {
12432 // If this is a multiprocess provider, then just return its
12433 // info and allow the caller to instantiate it. Only do
12434 // this if the provider is the same user as the caller's
12435 // process, or can run as root (so can be in any process).
12436 return cpr.newHolder(null);
12439 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
12440 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
12441 + cpr.info.name + " callers=" + Debug.getCallers(6));
12443 // This is single process, and our app is now connecting to it.
12444 // See if we are already in the process of launching this
12446 final int N = mLaunchingProviders.size();
12448 for (i = 0; i < N; i++) {
12449 if (mLaunchingProviders.get(i) == cpr) {
12454 // If the provider is not already being launched, then get it
12457 final long origId = Binder.clearCallingIdentity();
12460 // Content provider is now in use, its package can't be stopped.
12462 checkTime(startTime, "getContentProviderImpl: before set stopped state");
12463 AppGlobals.getPackageManager().setPackageStoppedState(
12464 cpr.appInfo.packageName, false, userId);
12465 checkTime(startTime, "getContentProviderImpl: after set stopped state");
12466 } catch (RemoteException e) {
12467 } catch (IllegalArgumentException e) {
12468 Slog.w(TAG, "Failed trying to unstop package "
12469 + cpr.appInfo.packageName + ": " + e);
12472 // Use existing process if already started
12473 checkTime(startTime, "getContentProviderImpl: looking for process record");
12474 ProcessRecord proc = getProcessRecordLocked(
12475 cpi.processName, cpr.appInfo.uid, false);
12476 if (proc != null && proc.thread != null && !proc.killed) {
12477 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
12478 "Installing in existing process " + proc);
12479 if (!proc.pubProviders.containsKey(cpi.name)) {
12480 checkTime(startTime, "getContentProviderImpl: scheduling install");
12481 proc.pubProviders.put(cpi.name, cpr);
12483 proc.thread.scheduleInstallProvider(cpi);
12484 } catch (RemoteException e) {
12488 checkTime(startTime, "getContentProviderImpl: before start process");
12489 proc = startProcessLocked(cpi.processName,
12490 cpr.appInfo, false, 0, "content provider",
12491 new ComponentName(cpi.applicationInfo.packageName,
12492 cpi.name), false, false, false);
12493 checkTime(startTime, "getContentProviderImpl: after start process");
12494 if (proc == null) {
12495 Slog.w(TAG, "Unable to launch app "
12496 + cpi.applicationInfo.packageName + "/"
12497 + cpi.applicationInfo.uid + " for provider "
12498 + name + ": process is bad");
12502 cpr.launchingApp = proc;
12503 mLaunchingProviders.add(cpr);
12505 Binder.restoreCallingIdentity(origId);
12509 checkTime(startTime, "getContentProviderImpl: updating data structures");
12511 // Make sure the provider is published (the same provider class
12512 // may be published under multiple names).
12514 mProviderMap.putProviderByClass(comp, cpr);
12517 mProviderMap.putProviderByName(name, cpr);
12518 conn = incProviderCountLocked(r, cpr, token, stable);
12519 if (conn != null) {
12520 conn.waiting = true;
12523 checkTime(startTime, "getContentProviderImpl: done!");
12525 grantEphemeralAccessLocked(userId, null /*intent*/,
12526 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12529 // Wait for the provider to be published...
12530 final long timeout = SystemClock.uptimeMillis() + CONTENT_PROVIDER_WAIT_TIMEOUT;
12531 synchronized (cpr) {
12532 while (cpr.provider == null) {
12533 if (cpr.launchingApp == null) {
12534 Slog.w(TAG, "Unable to launch app "
12535 + cpi.applicationInfo.packageName + "/"
12536 + cpi.applicationInfo.uid + " for provider "
12537 + name + ": launching app became null");
12538 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12539 UserHandle.getUserId(cpi.applicationInfo.uid),
12540 cpi.applicationInfo.packageName,
12541 cpi.applicationInfo.uid, name);
12545 final long wait = Math.max(0L, timeout - SystemClock.uptimeMillis());
12546 if (DEBUG_MU) Slog.v(TAG_MU,
12547 "Waiting to start provider " + cpr
12548 + " launchingApp=" + cpr.launchingApp + " for " + wait + " ms");
12549 if (conn != null) {
12550 conn.waiting = true;
12553 if (cpr.provider == null) {
12554 Slog.wtf(TAG, "Timeout waiting for provider "
12555 + cpi.applicationInfo.packageName + "/"
12556 + cpi.applicationInfo.uid + " for provider "
12558 + " providerRunning=" + providerRunning);
12561 } catch (InterruptedException ex) {
12563 if (conn != null) {
12564 conn.waiting = false;
12569 return cpr != null ? cpr.newHolder(conn) : null;
12572 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12573 ProcessRecord r, final int userId) {
12574 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12575 cpi.packageName, userId)) {
12577 final boolean callerForeground = r == null || r.setSchedGroup
12578 != ProcessList.SCHED_GROUP_BACKGROUND;
12580 // Show a permission review UI only for starting from a foreground app
12581 if (!callerForeground) {
12582 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12583 + cpi.packageName + " requires a permissions review");
12587 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12588 intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12589 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12590 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12592 if (DEBUG_PERMISSIONS_REVIEW) {
12593 Slog.i(TAG, "u" + userId + " Launching permission review "
12594 + "for package " + cpi.packageName);
12597 final UserHandle userHandle = new UserHandle(userId);
12598 mHandler.post(new Runnable() {
12600 public void run() {
12601 mContext.startActivityAsUser(intent, userHandle);
12612 * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12613 * PackageManager could be unavailable at construction time and therefore needs to be accessed
12616 IPackageManager getPackageManager() {
12617 return AppGlobals.getPackageManager();
12620 ActivityStartController getActivityStartController() {
12621 return mActivityStartController;
12624 LockTaskController getLockTaskController() {
12625 return mLockTaskController;
12628 ClientLifecycleManager getLifecycleManager() {
12629 return mLifecycleManager;
12632 PackageManagerInternal getPackageManagerInternalLocked() {
12633 if (mPackageManagerInt == null) {
12634 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12636 return mPackageManagerInt;
12640 public final ContentProviderHolder getContentProvider(
12641 IApplicationThread caller, String name, int userId, boolean stable) {
12642 enforceNotIsolatedCaller("getContentProvider");
12643 if (caller == null) {
12644 String msg = "null IApplicationThread when getting content provider "
12647 throw new SecurityException(msg);
12649 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12650 // with cross-user grant.
12651 return getContentProviderImpl(caller, name, null, stable, userId);
12654 public ContentProviderHolder getContentProviderExternal(
12655 String name, int userId, IBinder token) {
12656 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12657 "Do not have permission in call getContentProviderExternal()");
12658 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12659 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12660 return getContentProviderExternalUnchecked(name, token, userId);
12663 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12664 IBinder token, int userId) {
12665 return getContentProviderImpl(null, name, token, true, userId);
12669 * Drop a content provider from a ProcessRecord's bookkeeping
12671 public void removeContentProvider(IBinder connection, boolean stable) {
12672 enforceNotIsolatedCaller("removeContentProvider");
12673 long ident = Binder.clearCallingIdentity();
12675 synchronized (this) {
12676 ContentProviderConnection conn;
12678 conn = (ContentProviderConnection)connection;
12679 } catch (ClassCastException e) {
12680 String msg ="removeContentProvider: " + connection
12681 + " not a ContentProviderConnection";
12683 throw new IllegalArgumentException(msg);
12685 if (conn == null) {
12686 throw new NullPointerException("connection is null");
12688 if (decProviderCountLocked(conn, null, null, stable)) {
12689 updateOomAdjLocked();
12693 Binder.restoreCallingIdentity(ident);
12697 public void removeContentProviderExternal(String name, IBinder token) {
12698 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12699 "Do not have permission in call removeContentProviderExternal()");
12700 int userId = UserHandle.getCallingUserId();
12701 long ident = Binder.clearCallingIdentity();
12703 removeContentProviderExternalUnchecked(name, token, userId);
12705 Binder.restoreCallingIdentity(ident);
12709 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12710 synchronized (this) {
12711 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12713 //remove from mProvidersByClass
12714 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12718 //update content provider record entry info
12719 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12720 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12721 if (localCpr.hasExternalProcessHandles()) {
12722 if (localCpr.removeExternalProcessHandleLocked(token)) {
12723 updateOomAdjLocked();
12725 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12726 + " with no external reference for token: "
12730 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12731 + " with no external references.");
12736 public final void publishContentProviders(IApplicationThread caller,
12737 List<ContentProviderHolder> providers) {
12738 if (providers == null) {
12742 enforceNotIsolatedCaller("publishContentProviders");
12743 synchronized (this) {
12744 final ProcessRecord r = getRecordForAppLocked(caller);
12745 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12747 throw new SecurityException(
12748 "Unable to find app for caller " + caller
12749 + " (pid=" + Binder.getCallingPid()
12750 + ") when publishing content providers");
12753 final long origId = Binder.clearCallingIdentity();
12755 final int N = providers.size();
12756 for (int i = 0; i < N; i++) {
12757 ContentProviderHolder src = providers.get(i);
12758 if (src == null || src.info == null || src.provider == null) {
12761 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12762 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12764 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12765 mProviderMap.putProviderByClass(comp, dst);
12766 String names[] = dst.info.authority.split(";");
12767 for (int j = 0; j < names.length; j++) {
12768 mProviderMap.putProviderByName(names[j], dst);
12771 int launchingCount = mLaunchingProviders.size();
12773 boolean wasInLaunchingProviders = false;
12774 for (j = 0; j < launchingCount; j++) {
12775 if (mLaunchingProviders.get(j) == dst) {
12776 mLaunchingProviders.remove(j);
12777 wasInLaunchingProviders = true;
12782 if (wasInLaunchingProviders) {
12783 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12785 synchronized (dst) {
12786 dst.provider = src.provider;
12790 updateOomAdjLocked(r, true);
12791 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12792 src.info.authority);
12796 Binder.restoreCallingIdentity(origId);
12800 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12801 ContentProviderConnection conn;
12803 conn = (ContentProviderConnection)connection;
12804 } catch (ClassCastException e) {
12805 String msg ="refContentProvider: " + connection
12806 + " not a ContentProviderConnection";
12808 throw new IllegalArgumentException(msg);
12810 if (conn == null) {
12811 throw new NullPointerException("connection is null");
12814 synchronized (this) {
12816 conn.numStableIncs += stable;
12818 stable = conn.stableCount + stable;
12820 throw new IllegalStateException("stableCount < 0: " + stable);
12823 if (unstable > 0) {
12824 conn.numUnstableIncs += unstable;
12826 unstable = conn.unstableCount + unstable;
12827 if (unstable < 0) {
12828 throw new IllegalStateException("unstableCount < 0: " + unstable);
12831 if ((stable+unstable) <= 0) {
12832 throw new IllegalStateException("ref counts can't go to zero here: stable="
12833 + stable + " unstable=" + unstable);
12835 conn.stableCount = stable;
12836 conn.unstableCount = unstable;
12841 public void unstableProviderDied(IBinder connection) {
12842 ContentProviderConnection conn;
12844 conn = (ContentProviderConnection)connection;
12845 } catch (ClassCastException e) {
12846 String msg ="refContentProvider: " + connection
12847 + " not a ContentProviderConnection";
12849 throw new IllegalArgumentException(msg);
12851 if (conn == null) {
12852 throw new NullPointerException("connection is null");
12855 // Safely retrieve the content provider associated with the connection.
12856 IContentProvider provider;
12857 synchronized (this) {
12858 provider = conn.provider.provider;
12861 if (provider == null) {
12862 // Um, yeah, we're way ahead of you.
12866 // Make sure the caller is being honest with us.
12867 if (provider.asBinder().pingBinder()) {
12868 // Er, no, still looks good to us.
12869 synchronized (this) {
12870 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12871 + " says " + conn + " died, but we don't agree");
12876 // Well look at that! It's dead!
12877 synchronized (this) {
12878 if (conn.provider.provider != provider) {
12879 // But something changed... good enough.
12883 ProcessRecord proc = conn.provider.proc;
12884 if (proc == null || proc.thread == null) {
12885 // Seems like the process is already cleaned up.
12889 // As far as we're concerned, this is just like receiving a
12890 // death notification... just a bit prematurely.
12891 reportUidInfoMessageLocked(TAG,
12892 "Process " + proc.processName + " (pid " + proc.pid
12893 + ") early provider death",
12895 final long ident = Binder.clearCallingIdentity();
12897 appDiedLocked(proc);
12899 Binder.restoreCallingIdentity(ident);
12905 public void appNotRespondingViaProvider(IBinder connection) {
12906 enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12908 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12909 if (conn == null) {
12910 Slog.w(TAG, "ContentProviderConnection is null");
12914 final ProcessRecord host = conn.provider.proc;
12915 if (host == null) {
12916 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12920 mHandler.post(new Runnable() {
12922 public void run() {
12923 mAppErrors.appNotResponding(host, null, null, false,
12924 "ContentProvider not responding");
12929 public final void installSystemProviders() {
12930 List<ProviderInfo> providers;
12931 synchronized (this) {
12932 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12933 providers = generateApplicationProvidersLocked(app);
12934 if (providers != null) {
12935 for (int i=providers.size()-1; i>=0; i--) {
12936 ProviderInfo pi = (ProviderInfo)providers.get(i);
12937 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12938 Slog.w(TAG, "Not installing system proc provider " + pi.name
12939 + ": not system .apk");
12940 providers.remove(i);
12945 if (providers != null) {
12946 mSystemThread.installSystemProviders(providers);
12949 synchronized (this) {
12950 mSystemProvidersInstalled = true;
12953 mConstants.start(mContext.getContentResolver());
12954 mCoreSettingsObserver = new CoreSettingsObserver(this);
12955 mFontScaleSettingObserver = new FontScaleSettingObserver();
12956 mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12957 GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12959 // Now that the settings provider is published we can consider sending
12960 // in a rescue party.
12961 RescueParty.onSettingsProviderPublished(mContext);
12963 //mUsageStatsService.monitorPackages();
12966 void startPersistentApps(int matchFlags) {
12967 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12969 synchronized (this) {
12971 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12972 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12973 for (ApplicationInfo app : apps) {
12974 if (!"android".equals(app.packageName)) {
12975 addAppLocked(app, null, false, null /* ABI override */);
12978 } catch (RemoteException ex) {
12984 * When a user is unlocked, we need to install encryption-unaware providers
12985 * belonging to any running apps.
12987 void installEncryptionUnawareProviders(int userId) {
12988 // We're only interested in providers that are encryption unaware, and
12989 // we don't care about uninstalled apps, since there's no way they're
12990 // running at this point.
12991 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12993 synchronized (this) {
12994 final int NP = mProcessNames.getMap().size();
12995 for (int ip = 0; ip < NP; ip++) {
12996 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12997 final int NA = apps.size();
12998 for (int ia = 0; ia < NA; ia++) {
12999 final ProcessRecord app = apps.valueAt(ia);
13000 if (app.userId != userId || app.thread == null || app.unlocked) continue;
13002 final int NG = app.pkgList.size();
13003 for (int ig = 0; ig < NG; ig++) {
13005 final String pkgName = app.pkgList.keyAt(ig);
13006 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
13007 .getPackageInfo(pkgName, matchFlags, userId);
13008 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
13009 for (ProviderInfo pi : pkgInfo.providers) {
13010 // TODO: keep in sync with generateApplicationProvidersLocked
13011 final boolean processMatch = Objects.equals(pi.processName,
13012 app.processName) || pi.multiprocess;
13013 final boolean userMatch = isSingleton(pi.processName,
13014 pi.applicationInfo, pi.name, pi.flags)
13015 ? (app.userId == UserHandle.USER_SYSTEM) : true;
13016 if (processMatch && userMatch) {
13017 Log.v(TAG, "Installing " + pi);
13018 app.thread.scheduleInstallProvider(pi);
13020 Log.v(TAG, "Skipping " + pi);
13024 } catch (RemoteException ignored) {
13033 * Allows apps to retrieve the MIME type of a URI.
13034 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
13035 * users, then it does not need permission to access the ContentProvider.
13036 * Either, it needs cross-user uri grants.
13038 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
13040 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
13041 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
13043 public String getProviderMimeType(Uri uri, int userId) {
13044 enforceNotIsolatedCaller("getProviderMimeType");
13045 final String name = uri.getAuthority();
13046 int callingUid = Binder.getCallingUid();
13047 int callingPid = Binder.getCallingPid();
13049 boolean clearedIdentity = false;
13050 userId = mUserController.unsafeConvertIncomingUser(userId);
13051 if (canClearIdentity(callingPid, callingUid, userId)) {
13052 clearedIdentity = true;
13053 ident = Binder.clearCallingIdentity();
13055 ContentProviderHolder holder = null;
13057 holder = getContentProviderExternalUnchecked(name, null, userId);
13058 if (holder != null) {
13059 return holder.provider.getType(uri);
13061 } catch (RemoteException e) {
13062 Log.w(TAG, "Content provider dead retrieving " + uri, e);
13064 } catch (Exception e) {
13065 Log.w(TAG, "Exception while determining type of " + uri, e);
13068 // We need to clear the identity to call removeContentProviderExternalUnchecked
13069 if (!clearedIdentity) {
13070 ident = Binder.clearCallingIdentity();
13073 if (holder != null) {
13074 removeContentProviderExternalUnchecked(name, null, userId);
13077 Binder.restoreCallingIdentity(ident);
13084 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
13085 if (UserHandle.getUserId(callingUid) == userId) {
13088 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13089 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
13090 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13091 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13097 // =========================================================
13098 // GLOBAL MANAGEMENT
13099 // =========================================================
13102 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
13103 boolean isolated, int isolatedUid) {
13104 String proc = customProcess != null ? customProcess : info.processName;
13105 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13106 final int userId = UserHandle.getUserId(info.uid);
13107 int uid = info.uid;
13109 if (isolatedUid == 0) {
13110 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
13112 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
13113 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
13114 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
13116 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
13117 mNextIsolatedProcessUid++;
13118 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
13119 // No process for this uid, use it.
13123 if (stepsLeft <= 0) {
13128 // Special case for startIsolatedProcess (internal only), where
13129 // the uid of the isolated process is specified by the caller.
13132 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
13134 // Register the isolated UID with this application so BatteryStats knows to
13135 // attribute resource usage to the application.
13137 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
13138 // about the process state of the isolated UID *before* it is registered with the
13139 // owning application.
13140 mBatteryStatsService.addIsolatedUid(uid, info.uid);
13142 final ProcessRecord r = new ProcessRecord(this, stats, info, proc, uid);
13143 if (!mBooted && !mBooting
13144 && userId == UserHandle.USER_SYSTEM
13145 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13146 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
13147 r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
13148 r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
13149 r.persistent = true;
13150 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13152 if (isolated && isolatedUid != 0) {
13153 // Special case for startIsolatedProcess (internal only) - assume the process
13154 // is required by the system server to prevent it being killed.
13155 r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
13157 addProcessNameLocked(r);
13161 private boolean uidOnBackgroundWhitelist(final int uid) {
13162 final int appId = UserHandle.getAppId(uid);
13163 final int[] whitelist = mBackgroundAppIdWhitelist;
13164 final int N = whitelist.length;
13165 for (int i = 0; i < N; i++) {
13166 if (appId == whitelist[i]) {
13174 public boolean isBackgroundRestricted(String packageName) {
13175 final int callingUid = Binder.getCallingUid();
13176 final IPackageManager pm = AppGlobals.getPackageManager();
13178 final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
13179 UserHandle.getUserId(callingUid));
13180 if (packageUid != callingUid) {
13181 throw new IllegalArgumentException("Uid " + callingUid
13182 + " cannot query restriction state for package " + packageName);
13184 } catch (RemoteException exc) {
13187 return isBackgroundRestrictedNoCheck(callingUid, packageName);
13190 boolean isBackgroundRestrictedNoCheck(final int uid, final String packageName) {
13191 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
13193 return mode != AppOpsManager.MODE_ALLOWED;
13197 public void backgroundWhitelistUid(final int uid) {
13198 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13199 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
13202 if (DEBUG_BACKGROUND_CHECK) {
13203 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
13205 synchronized (this) {
13206 final int N = mBackgroundAppIdWhitelist.length;
13207 int[] newList = new int[N+1];
13208 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
13209 newList[N] = UserHandle.getAppId(uid);
13210 mBackgroundAppIdWhitelist = newList;
13215 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13216 String abiOverride) {
13217 return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
13221 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13222 boolean disableHiddenApiChecks, String abiOverride) {
13225 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
13232 app = newProcessRecordLocked(info, customProcess, isolated, 0);
13233 updateLruProcessLocked(app, false, null);
13234 updateOomAdjLocked();
13237 // This package really, really can not be stopped.
13239 AppGlobals.getPackageManager().setPackageStoppedState(
13240 info.packageName, false, UserHandle.getUserId(app.uid));
13241 } catch (RemoteException e) {
13242 } catch (IllegalArgumentException e) {
13243 Slog.w(TAG, "Failed trying to unstop package "
13244 + info.packageName + ": " + e);
13247 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13248 app.persistent = true;
13249 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13251 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
13252 mPersistentStartingProcesses.add(app);
13253 startProcessLocked(app, "added application",
13254 customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
13261 public void unhandledBack() {
13262 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
13263 "unhandledBack()");
13265 synchronized(this) {
13266 final long origId = Binder.clearCallingIdentity();
13268 getFocusedStack().unhandledBackLocked();
13270 Binder.restoreCallingIdentity(origId);
13275 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
13276 enforceNotIsolatedCaller("openContentUri");
13277 final int userId = UserHandle.getCallingUserId();
13278 final Uri uri = Uri.parse(uriString);
13279 String name = uri.getAuthority();
13280 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
13281 ParcelFileDescriptor pfd = null;
13283 // We record the binder invoker's uid in thread-local storage before
13284 // going to the content provider to open the file. Later, in the code
13285 // that handles all permissions checks, we look for this uid and use
13286 // that rather than the Activity Manager's own uid. The effect is that
13287 // we do the check against the caller's permissions even though it looks
13288 // to the content provider like the Activity Manager itself is making
13290 Binder token = new Binder();
13291 sCallerIdentity.set(new Identity(
13292 token, Binder.getCallingPid(), Binder.getCallingUid()));
13294 pfd = cph.provider.openFile(null, uri, "r", null, token);
13295 } catch (FileNotFoundException e) {
13296 // do nothing; pfd will be returned null
13298 // Ensure that whatever happens, we clean up the identity state
13299 sCallerIdentity.remove();
13300 // Ensure we're done with the provider.
13301 removeContentProviderExternalUnchecked(name, null, userId);
13304 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
13309 // Actually is sleeping or shutting down or whatever else in the future
13310 // is an inactive state.
13311 boolean isSleepingOrShuttingDownLocked() {
13312 return isSleepingLocked() || mShuttingDown;
13315 boolean isShuttingDownLocked() {
13316 return mShuttingDown;
13319 boolean isSleepingLocked() {
13323 void reportGlobalUsageEventLocked(int event) {
13324 mUsageStatsService.reportEvent("android", mUserController.getCurrentUserId(), event);
13325 int[] profiles = mUserController.getCurrentProfileIds();
13326 if (profiles != null) {
13327 for (int i = profiles.length - 1; i >= 0; i--) {
13328 mUsageStatsService.reportEvent((String)null, profiles[i], event);
13333 void reportCurWakefulnessUsageEventLocked() {
13334 reportGlobalUsageEventLocked(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
13335 ? UsageEvents.Event.SCREEN_INTERACTIVE
13336 : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
13339 void reportCurKeyguardUsageEventLocked() {
13340 reportGlobalUsageEventLocked(mKeyguardShown
13341 ? UsageEvents.Event.KEYGUARD_SHOWN
13342 : UsageEvents.Event.KEYGUARD_HIDDEN);
13345 void onWakefulnessChanged(int wakefulness) {
13346 synchronized(this) {
13347 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13348 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13349 mWakefulness = wakefulness;
13351 if (wasAwake != isAwake) {
13352 // Also update state in a special way for running foreground services UI.
13353 mServices.updateScreenStateLocked(isAwake);
13354 reportCurWakefulnessUsageEventLocked();
13355 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
13358 updateOomAdjLocked();
13363 void finishRunningVoiceLocked() {
13364 if (mRunningVoice != null) {
13365 mRunningVoice = null;
13366 mVoiceWakeLock.release();
13367 updateSleepIfNeededLocked();
13371 void startTimeTrackingFocusedActivityLocked() {
13372 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
13373 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
13374 mCurAppTimeTracker.start(resumedActivity.packageName);
13379 void updateSleepIfNeededLocked() {
13380 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
13381 final boolean wasSleeping = mSleeping;
13383 if (!shouldSleep) {
13384 // If wasSleeping is true, we need to wake up activity manager state from when
13385 // we started sleeping. In either case, we need to apply the sleep tokens, which
13386 // will wake up stacks or put them to sleep as appropriate.
13389 startTimeTrackingFocusedActivityLocked();
13390 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
13391 mStackSupervisor.comeOutOfSleepIfNeededLocked();
13393 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
13395 updateOomAdjLocked();
13397 } else if (!mSleeping && shouldSleep) {
13399 if (mCurAppTimeTracker != null) {
13400 mCurAppTimeTracker.stop();
13402 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
13403 mStackSupervisor.goingToSleepLocked();
13404 updateResumedAppTrace(null /* resumed */);
13405 updateOomAdjLocked();
13409 /** Pokes the task persister. */
13410 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
13411 mRecentTasks.notifyTaskPersisterLocked(task, flush);
13415 * Notifies all listeners when the pinned stack animation starts.
13418 public void notifyPinnedStackAnimationStarted() {
13419 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
13423 * Notifies all listeners when the pinned stack animation ends.
13426 public void notifyPinnedStackAnimationEnded() {
13427 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
13431 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
13432 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
13436 public boolean shutdown(int timeout) {
13437 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
13438 != PackageManager.PERMISSION_GRANTED) {
13439 throw new SecurityException("Requires permission "
13440 + android.Manifest.permission.SHUTDOWN);
13443 boolean timedout = false;
13445 synchronized(this) {
13446 mShuttingDown = true;
13447 mStackSupervisor.prepareForShutdownLocked();
13448 updateEventDispatchingLocked();
13449 timedout = mStackSupervisor.shutdownLocked(timeout);
13452 mAppOpsService.shutdown();
13453 if (mUsageStatsService != null) {
13454 mUsageStatsService.prepareShutdown();
13456 mBatteryStatsService.shutdown();
13457 synchronized (this) {
13458 mProcessStats.shutdownLocked();
13459 notifyTaskPersisterLocked(null, true);
13465 public final void activitySlept(IBinder token) {
13466 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
13468 final long origId = Binder.clearCallingIdentity();
13470 synchronized (this) {
13471 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13473 mStackSupervisor.activitySleptLocked(r);
13477 Binder.restoreCallingIdentity(origId);
13481 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
13482 Slog.d(TAG, "<<< startRunningVoiceLocked()");
13483 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
13484 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
13485 boolean wasRunningVoice = mRunningVoice != null;
13486 mRunningVoice = session;
13487 if (!wasRunningVoice) {
13488 mVoiceWakeLock.acquire();
13489 updateSleepIfNeededLocked();
13494 private void updateEventDispatchingLocked() {
13495 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
13499 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
13500 int secondaryDisplayShowing) {
13501 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
13502 != PackageManager.PERMISSION_GRANTED) {
13503 throw new SecurityException("Requires permission "
13504 + android.Manifest.permission.DEVICE_POWER);
13507 synchronized(this) {
13508 long ident = Binder.clearCallingIdentity();
13509 if (mKeyguardShown != keyguardShowing) {
13510 mKeyguardShown = keyguardShowing;
13511 reportCurKeyguardUsageEventLocked();
13514 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
13515 secondaryDisplayShowing);
13517 Binder.restoreCallingIdentity(ident);
13521 mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
13526 public void notifyLockedProfile(@UserIdInt int userId) {
13528 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
13529 throw new SecurityException("Only privileged app can call notifyLockedProfile");
13531 } catch (RemoteException ex) {
13532 throw new SecurityException("Fail to check is caller a privileged app", ex);
13535 synchronized (this) {
13536 final long ident = Binder.clearCallingIdentity();
13538 if (mUserController.shouldConfirmCredentials(userId)) {
13539 if (mKeyguardController.isKeyguardLocked()) {
13540 // Showing launcher to avoid user entering credential twice.
13541 final int currentUserId = mUserController.getCurrentUserId();
13542 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
13544 mStackSupervisor.lockAllProfileTasks(userId);
13547 Binder.restoreCallingIdentity(ident);
13553 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
13554 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
13555 synchronized (this) {
13556 final long ident = Binder.clearCallingIdentity();
13558 intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
13559 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
13560 FLAG_ACTIVITY_TASK_ON_HOME);
13561 ActivityOptions activityOptions = options != null
13562 ? new ActivityOptions(options)
13563 : ActivityOptions.makeBasic();
13564 activityOptions.setLaunchTaskId(
13565 mStackSupervisor.getHomeActivity().getTask().taskId);
13566 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
13567 UserHandle.CURRENT);
13569 Binder.restoreCallingIdentity(ident);
13575 public void stopAppSwitches() {
13576 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
13577 synchronized(this) {
13578 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
13579 + APP_SWITCH_DELAY_TIME;
13580 mDidAppSwitch = false;
13581 mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
13585 public void resumeAppSwitches() {
13586 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
13587 synchronized(this) {
13588 // Note that we don't execute any pending app switches... we will
13589 // let those wait until either the timeout, or the next start
13590 // activity request.
13591 mAppSwitchesAllowedTime = 0;
13595 boolean checkAllowAppSwitchUid(int uid) {
13596 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13597 if (types != null) {
13598 for (int i = types.size() - 1; i >= 0; i--) {
13599 if (types.valueAt(i).intValue() == uid) {
13607 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13608 int callingPid, int callingUid, String name) {
13609 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13613 if (mRecentTasks.isCallerRecents(sourceUid)) {
13617 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
13618 if (perm == PackageManager.PERMISSION_GRANTED) {
13621 if (checkAllowAppSwitchUid(sourceUid)) {
13625 // If the actual IPC caller is different from the logical source, then
13626 // also see if they are allowed to control app switches.
13627 if (callingUid != -1 && callingUid != sourceUid) {
13628 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
13629 if (perm == PackageManager.PERMISSION_GRANTED) {
13632 if (checkAllowAppSwitchUid(callingUid)) {
13637 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13641 public void setDebugApp(String packageName, boolean waitForDebugger,
13642 boolean persistent) {
13643 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13646 long ident = Binder.clearCallingIdentity();
13648 // Note that this is not really thread safe if there are multiple
13649 // callers into it at the same time, but that's not a situation we
13652 final ContentResolver resolver = mContext.getContentResolver();
13653 Settings.Global.putString(
13654 resolver, Settings.Global.DEBUG_APP,
13656 Settings.Global.putInt(
13657 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13658 waitForDebugger ? 1 : 0);
13661 synchronized (this) {
13663 mOrigDebugApp = mDebugApp;
13664 mOrigWaitForDebugger = mWaitForDebugger;
13666 mDebugApp = packageName;
13667 mWaitForDebugger = waitForDebugger;
13668 mDebugTransient = !persistent;
13669 if (packageName != null) {
13670 forceStopPackageLocked(packageName, -1, false, false, true, true,
13671 false, UserHandle.USER_ALL, "set debug app");
13675 Binder.restoreCallingIdentity(ident);
13680 * Set or remove an agent to be run whenever an app with the given process name starts.
13682 * This method will not check whether the given process name matches a debuggable app. That
13683 * would require scanning all current packages, and a rescan when new packages are installed
13686 * Instead, do the check when an application is started and matched to a stored agent.
13688 * @param packageName the process name of the app.
13689 * @param agent the agent string to be used, or null to remove any previously set agent.
13692 public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13693 synchronized (this) {
13694 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13695 // its own permission.
13696 if (checkCallingPermission(
13697 android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13698 PackageManager.PERMISSION_GRANTED) {
13699 throw new SecurityException(
13700 "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13703 if (agent == null) {
13704 if (mAppAgentMap != null) {
13705 mAppAgentMap.remove(packageName);
13706 if (mAppAgentMap.isEmpty()) {
13707 mAppAgentMap = null;
13711 if (mAppAgentMap == null) {
13712 mAppAgentMap = new HashMap<>();
13714 if (mAppAgentMap.size() >= 100) {
13715 // Limit the size of the map, to avoid OOMEs.
13716 Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13720 mAppAgentMap.put(packageName, agent);
13725 void setTrackAllocationApp(ApplicationInfo app, String processName) {
13726 synchronized (this) {
13727 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13728 if (!isDebuggable) {
13729 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13730 throw new SecurityException("Process not debuggable: " + app.packageName);
13734 mTrackAllocationApp = processName;
13738 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13739 synchronized (this) {
13740 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13741 if (!isDebuggable) {
13742 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13743 throw new SecurityException("Process not debuggable: " + app.packageName);
13746 mProfileApp = processName;
13748 if (mProfilerInfo != null) {
13749 if (mProfilerInfo.profileFd != null) {
13751 mProfilerInfo.profileFd.close();
13752 } catch (IOException e) {
13756 mProfilerInfo = new ProfilerInfo(profilerInfo);
13761 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13762 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13763 if (!isDebuggable) {
13764 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13765 throw new SecurityException("Process not debuggable: " + app.packageName);
13768 mNativeDebuggingApp = processName;
13772 public void setAlwaysFinish(boolean enabled) {
13773 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13774 "setAlwaysFinish()");
13776 long ident = Binder.clearCallingIdentity();
13778 Settings.Global.putInt(
13779 mContext.getContentResolver(),
13780 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13782 synchronized (this) {
13783 mAlwaysFinishActivities = enabled;
13786 Binder.restoreCallingIdentity(ident);
13791 public void setActivityController(IActivityController controller, boolean imAMonkey) {
13792 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13793 "setActivityController()");
13794 synchronized (this) {
13795 mController = controller;
13796 mControllerIsAMonkey = imAMonkey;
13797 Watchdog.getInstance().setActivityController(controller);
13802 public void setUserIsMonkey(boolean userIsMonkey) {
13803 synchronized (this) {
13804 synchronized (mPidsSelfLocked) {
13805 final int callingPid = Binder.getCallingPid();
13806 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13807 if (proc == null) {
13808 throw new SecurityException("Unknown process: " + callingPid);
13810 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13811 throw new SecurityException("Only an instrumentation process "
13812 + "with a UiAutomation can call setUserIsMonkey");
13815 mUserIsMonkey = userIsMonkey;
13820 public boolean isUserAMonkey() {
13821 synchronized (this) {
13822 // If there is a controller also implies the user is a monkey.
13823 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13828 * @deprecated This method is only used by a few internal components and it will soon be
13829 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13830 * No new code should be calling it.
13834 public void requestBugReport(int bugreportType) {
13835 String extraOptions = null;
13836 switch (bugreportType) {
13837 case ActivityManager.BUGREPORT_OPTION_FULL:
13838 // Default options.
13840 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13841 extraOptions = "bugreportplus";
13843 case ActivityManager.BUGREPORT_OPTION_REMOTE:
13844 extraOptions = "bugreportremote";
13846 case ActivityManager.BUGREPORT_OPTION_WEAR:
13847 extraOptions = "bugreportwear";
13849 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13850 extraOptions = "bugreporttelephony";
13852 case ActivityManager.BUGREPORT_OPTION_WIFI:
13853 extraOptions = "bugreportwifi";
13856 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13859 // Always log caller, even if it does not have permission to dump.
13860 String type = extraOptions == null ? "bugreport" : extraOptions;
13861 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13863 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13864 if (extraOptions != null) {
13865 SystemProperties.set("dumpstate.options", extraOptions);
13867 SystemProperties.set("ctl.start", "bugreport");
13871 * @deprecated This method is only used by a few internal components and it will soon be
13872 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13873 * No new code should be calling it.
13876 private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13877 int bugreportType) {
13878 if (!TextUtils.isEmpty(shareTitle)) {
13879 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13880 String errorStr = "shareTitle should be less than " +
13881 MAX_BUGREPORT_TITLE_SIZE + " characters";
13882 throw new IllegalArgumentException(errorStr);
13884 if (!TextUtils.isEmpty(shareDescription)) {
13887 length = shareDescription.getBytes("UTF-8").length;
13888 } catch (UnsupportedEncodingException e) {
13889 String errorStr = "shareDescription: UnsupportedEncodingException";
13890 throw new IllegalArgumentException(errorStr);
13892 if (length > SystemProperties.PROP_VALUE_MAX) {
13893 String errorStr = "shareTitle should be less than " +
13894 SystemProperties.PROP_VALUE_MAX + " bytes";
13895 throw new IllegalArgumentException(errorStr);
13897 SystemProperties.set("dumpstate.options.description", shareDescription);
13900 SystemProperties.set("dumpstate.options.title", shareTitle);
13904 Slog.d(TAG, "Bugreport notification title " + shareTitle
13905 + " description " + shareDescription);
13906 requestBugReport(bugreportType);
13910 * @deprecated This method is only used by a few internal components and it will soon be
13911 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13912 * No new code should be calling it.
13916 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13917 requestBugReportWithDescription(shareTitle, shareDescription,
13918 ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13922 * @deprecated This method is only used by a few internal components and it will soon be
13923 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13924 * No new code should be calling it.
13928 public void requestWifiBugReport(String shareTitle, String shareDescription) {
13929 requestBugReportWithDescription(shareTitle, shareDescription,
13930 ActivityManager.BUGREPORT_OPTION_WIFI);
13934 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13935 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13938 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13939 if (r != null && (r.instr != null || r.usingWrapper)) {
13940 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13942 return KEY_DISPATCHING_TIMEOUT;
13946 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13947 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13948 != PackageManager.PERMISSION_GRANTED) {
13949 throw new SecurityException("Requires permission "
13950 + android.Manifest.permission.FILTER_EVENTS);
13952 ProcessRecord proc;
13954 synchronized (this) {
13955 synchronized (mPidsSelfLocked) {
13956 proc = mPidsSelfLocked.get(pid);
13958 timeout = getInputDispatchingTimeoutLocked(proc);
13961 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13969 * Handle input dispatching timeouts.
13970 * Returns whether input dispatching should be aborted or not.
13972 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13973 final ActivityRecord activity, final ActivityRecord parent,
13974 final boolean aboveSystem, String reason) {
13975 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13976 != PackageManager.PERMISSION_GRANTED) {
13977 throw new SecurityException("Requires permission "
13978 + android.Manifest.permission.FILTER_EVENTS);
13981 final String annotation;
13982 if (reason == null) {
13983 annotation = "Input dispatching timed out";
13985 annotation = "Input dispatching timed out (" + reason + ")";
13988 if (proc != null) {
13989 synchronized (this) {
13990 if (proc.debugging) {
13994 if (proc.instr != null) {
13995 Bundle info = new Bundle();
13996 info.putString("shortMsg", "keyDispatchingTimedOut");
13997 info.putString("longMsg", annotation);
13998 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
14002 mHandler.post(new Runnable() {
14004 public void run() {
14005 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
14014 public Bundle getAssistContextExtras(int requestType) {
14015 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
14016 null, null, true /* focused */, true /* newSessionId */,
14017 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
14021 synchronized (pae) {
14022 while (!pae.haveResult) {
14025 } catch (InterruptedException e) {
14029 synchronized (this) {
14030 buildAssistBundleLocked(pae, pae.result);
14031 mPendingAssistExtras.remove(pae);
14032 mUiHandler.removeCallbacks(pae);
14038 public boolean isAssistDataAllowedOnCurrentActivity() {
14040 synchronized (this) {
14041 final ActivityStack focusedStack = getFocusedStack();
14042 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
14046 final ActivityRecord activity = focusedStack.getTopActivity();
14047 if (activity == null) {
14050 userId = activity.userId;
14052 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
14056 public boolean showAssistFromActivity(IBinder token, Bundle args) {
14057 long ident = Binder.clearCallingIdentity();
14059 synchronized (this) {
14060 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
14061 ActivityRecord top = getFocusedStack().getTopActivity();
14062 if (top != caller) {
14063 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
14064 + " is not current top " + top);
14067 if (!top.nowVisible) {
14068 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
14069 + " is not visible");
14073 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
14076 Binder.restoreCallingIdentity(ident);
14081 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
14082 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
14083 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
14084 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
14085 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
14089 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
14090 IBinder activityToken, int flags) {
14091 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
14092 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
14093 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
14096 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
14097 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
14098 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
14100 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
14101 "enqueueAssistContext()");
14103 synchronized (this) {
14104 ActivityRecord activity = getFocusedStack().getTopActivity();
14105 if (activity == null) {
14106 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
14109 if (activity.app == null || activity.app.thread == null) {
14110 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
14114 if (activityToken != null) {
14115 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
14116 if (activity != caller) {
14117 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
14118 + " is not current top " + activity);
14123 activity = ActivityRecord.forTokenLocked(activityToken);
14124 if (activity == null) {
14125 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
14126 + " couldn't be found");
14129 if (activity.app == null || activity.app.thread == null) {
14130 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
14135 PendingAssistExtras pae;
14136 Bundle extras = new Bundle();
14137 if (args != null) {
14138 extras.putAll(args);
14140 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
14141 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
14143 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
14145 pae.isHome = activity.isActivityTypeHome();
14147 // Increment the sessionId if necessary
14148 if (newSessionId) {
14152 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
14153 mViSessionId, flags);
14154 mPendingAssistExtras.add(pae);
14155 mUiHandler.postDelayed(pae, timeout);
14156 } catch (RemoteException e) {
14157 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
14164 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
14165 IAssistDataReceiver receiver;
14166 synchronized (this) {
14167 mPendingAssistExtras.remove(pae);
14168 receiver = pae.receiver;
14170 if (receiver != null) {
14171 // Caller wants result sent back to them.
14172 Bundle sendBundle = new Bundle();
14173 // At least return the receiver extras
14174 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14176 pae.receiver.onHandleAssistData(sendBundle);
14177 } catch (RemoteException e) {
14182 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
14183 if (result != null) {
14184 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
14186 if (pae.hint != null) {
14187 pae.extras.putBoolean(pae.hint, true);
14191 /** Called from an app when assist data is ready. */
14193 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
14194 AssistContent content, Uri referrer) {
14195 PendingAssistExtras pae = (PendingAssistExtras)token;
14196 synchronized (pae) {
14197 pae.result = extras;
14198 pae.structure = structure;
14199 pae.content = content;
14200 if (referrer != null) {
14201 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
14203 if (structure != null) {
14204 structure.setHomeActivity(pae.isHome);
14206 pae.haveResult = true;
14208 if (pae.intent == null && pae.receiver == null) {
14209 // Caller is just waiting for the result.
14213 // We are now ready to launch the assist activity.
14214 IAssistDataReceiver sendReceiver = null;
14215 Bundle sendBundle = null;
14216 synchronized (this) {
14217 buildAssistBundleLocked(pae, extras);
14218 boolean exists = mPendingAssistExtras.remove(pae);
14219 mUiHandler.removeCallbacks(pae);
14225 if ((sendReceiver=pae.receiver) != null) {
14226 // Caller wants result sent back to them.
14227 sendBundle = new Bundle();
14228 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
14229 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
14230 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
14231 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14234 if (sendReceiver != null) {
14236 sendReceiver.onHandleAssistData(sendBundle);
14237 } catch (RemoteException e) {
14242 final long ident = Binder.clearCallingIdentity();
14244 if (TextUtils.equals(pae.intent.getAction(),
14245 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
14246 pae.intent.putExtras(pae.extras);
14247 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
14249 pae.intent.replaceExtras(pae.extras);
14250 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
14251 | Intent.FLAG_ACTIVITY_SINGLE_TOP
14252 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
14253 closeSystemDialogs("assist");
14256 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
14257 } catch (ActivityNotFoundException e) {
14258 Slog.w(TAG, "No activity to handle assist action.", e);
14262 Binder.restoreCallingIdentity(ident);
14266 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
14268 return enqueueAssistContext(requestType, intent, hint, null, null, null,
14269 true /* focused */, true /* newSessionId */, userHandle, args,
14270 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
14273 public void registerProcessObserver(IProcessObserver observer) {
14274 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
14275 "registerProcessObserver()");
14276 synchronized (this) {
14277 mProcessObservers.register(observer);
14282 public void unregisterProcessObserver(IProcessObserver observer) {
14283 synchronized (this) {
14284 mProcessObservers.unregister(observer);
14289 public int getUidProcessState(int uid, String callingPackage) {
14290 if (!hasUsageStatsPermission(callingPackage)) {
14291 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14292 "getUidProcessState");
14295 synchronized (this) {
14296 UidRecord uidRec = mActiveUids.get(uid);
14297 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
14302 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
14303 String callingPackage) {
14304 if (!hasUsageStatsPermission(callingPackage)) {
14305 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14306 "registerUidObserver");
14308 synchronized (this) {
14309 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
14310 callingPackage, which, cutpoint));
14315 public void unregisterUidObserver(IUidObserver observer) {
14316 synchronized (this) {
14317 mUidObservers.unregister(observer);
14322 public boolean isUidActive(int uid, String callingPackage) {
14323 if (!hasUsageStatsPermission(callingPackage)) {
14324 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14327 synchronized (this) {
14328 return isUidActiveLocked(uid);
14332 boolean isUidActiveLocked(int uid) {
14333 final UidRecord uidRecord = mActiveUids.get(uid);
14334 return uidRecord != null && !uidRecord.setIdle;
14338 public boolean convertFromTranslucent(IBinder token) {
14339 final long origId = Binder.clearCallingIdentity();
14341 synchronized (this) {
14342 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14346 final boolean translucentChanged = r.changeWindowTranslucency(true);
14347 if (translucentChanged) {
14348 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14350 mWindowManager.setAppFullscreen(token, true);
14351 return translucentChanged;
14354 Binder.restoreCallingIdentity(origId);
14359 public boolean convertToTranslucent(IBinder token, Bundle options) {
14360 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
14361 final long origId = Binder.clearCallingIdentity();
14363 synchronized (this) {
14364 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14368 final TaskRecord task = r.getTask();
14369 int index = task.mActivities.lastIndexOf(r);
14371 ActivityRecord under = task.mActivities.get(index - 1);
14372 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
14374 final boolean translucentChanged = r.changeWindowTranslucency(false);
14375 if (translucentChanged) {
14376 r.getStack().convertActivityToTranslucent(r);
14378 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14379 mWindowManager.setAppFullscreen(token, false);
14380 return translucentChanged;
14383 Binder.restoreCallingIdentity(origId);
14388 public Bundle getActivityOptions(IBinder token) {
14389 final long origId = Binder.clearCallingIdentity();
14391 synchronized (this) {
14392 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14394 final ActivityOptions activityOptions = r.takeOptionsLocked();
14395 return activityOptions == null ? null : activityOptions.toBundle();
14400 Binder.restoreCallingIdentity(origId);
14405 public void setImmersive(IBinder token, boolean immersive) {
14406 synchronized(this) {
14407 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14409 throw new IllegalArgumentException();
14411 r.immersive = immersive;
14413 // update associated state if we're frontmost
14414 if (r == mStackSupervisor.getResumedActivityLocked()) {
14415 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
14416 applyUpdateLockStateLocked(r);
14422 public boolean isImmersive(IBinder token) {
14423 synchronized (this) {
14424 ActivityRecord r = ActivityRecord.isInStackLocked(token);
14426 throw new IllegalArgumentException();
14428 return r.immersive;
14433 public void setVrThread(int tid) {
14434 enforceSystemHasVrFeature();
14435 synchronized (this) {
14436 synchronized (mPidsSelfLocked) {
14437 final int pid = Binder.getCallingPid();
14438 final ProcessRecord proc = mPidsSelfLocked.get(pid);
14439 mVrController.setVrThreadLocked(tid, pid, proc);
14445 public void setPersistentVrThread(int tid) {
14446 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
14447 final String msg = "Permission Denial: setPersistentVrThread() from pid="
14448 + Binder.getCallingPid()
14449 + ", uid=" + Binder.getCallingUid()
14450 + " requires " + permission.RESTRICTED_VR_ACCESS;
14452 throw new SecurityException(msg);
14454 enforceSystemHasVrFeature();
14455 synchronized (this) {
14456 synchronized (mPidsSelfLocked) {
14457 final int pid = Binder.getCallingPid();
14458 final ProcessRecord proc = mPidsSelfLocked.get(pid);
14459 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
14465 * Schedule the given thread a normal scheduling priority.
14467 * @param tid the tid of the thread to adjust the scheduling of.
14468 * @param suppressLogs {@code true} if any error logging should be disabled.
14470 * @return {@code true} if this succeeded.
14472 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
14474 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
14476 } catch (IllegalArgumentException e) {
14477 if (!suppressLogs) {
14478 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14480 } catch (SecurityException e) {
14481 if (!suppressLogs) {
14482 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14489 * Schedule the given thread an FIFO scheduling priority.
14491 * @param tid the tid of the thread to adjust the scheduling of.
14492 * @param suppressLogs {@code true} if any error logging should be disabled.
14494 * @return {@code true} if this succeeded.
14496 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
14498 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
14500 } catch (IllegalArgumentException e) {
14501 if (!suppressLogs) {
14502 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14504 } catch (SecurityException e) {
14505 if (!suppressLogs) {
14506 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14513 * Check that we have the features required for VR-related API calls, and throw an exception if
14516 private void enforceSystemHasVrFeature() {
14517 if (!mContext.getPackageManager().hasSystemFeature(
14518 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
14519 throw new UnsupportedOperationException("VR mode not supported on this device!");
14524 public void setRenderThread(int tid) {
14525 synchronized (this) {
14526 ProcessRecord proc;
14527 int pid = Binder.getCallingPid();
14528 if (pid == Process.myPid()) {
14529 demoteSystemServerRenderThread(tid);
14532 synchronized (mPidsSelfLocked) {
14533 proc = mPidsSelfLocked.get(pid);
14534 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
14535 // ensure the tid belongs to the process
14536 if (!isThreadInProcess(pid, tid)) {
14537 throw new IllegalArgumentException(
14538 "Render thread does not belong to process");
14540 proc.renderThreadTid = tid;
14541 if (DEBUG_OOM_ADJ) {
14542 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
14544 // promote to FIFO now
14545 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
14546 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
14547 if (mUseFifoUiScheduling) {
14548 setThreadScheduler(proc.renderThreadTid,
14549 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
14551 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
14555 if (DEBUG_OOM_ADJ) {
14556 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
14557 "PID: " + pid + ", TID: " + tid + " FIFO: " +
14558 mUseFifoUiScheduling);
14566 * We only use RenderThread in system_server to store task snapshots to the disk, which should
14567 * happen in the background. Thus, demote render thread from system_server to a lower priority.
14569 * @param tid the tid of the RenderThread
14571 private void demoteSystemServerRenderThread(int tid) {
14572 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14576 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14577 enforceSystemHasVrFeature();
14579 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14582 synchronized (this) {
14583 r = ActivityRecord.isInStackLocked(token);
14587 throw new IllegalArgumentException();
14591 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14592 VrManagerInternal.NO_ERROR) {
14596 // Clear the binder calling uid since this path may call moveToTask().
14597 final long callingId = Binder.clearCallingIdentity();
14599 synchronized(this) {
14600 r.requestedVrComponent = (enabled) ? packageName : null;
14602 // Update associated state if this activity is currently focused
14603 if (r == mStackSupervisor.getResumedActivityLocked()) {
14604 applyUpdateVrModeLocked(r);
14609 Binder.restoreCallingIdentity(callingId);
14614 public boolean isVrModePackageEnabled(ComponentName packageName) {
14615 enforceSystemHasVrFeature();
14617 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14619 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14620 VrManagerInternal.NO_ERROR;
14623 public boolean isTopActivityImmersive() {
14624 enforceNotIsolatedCaller("startActivity");
14625 synchronized (this) {
14626 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14627 return (r != null) ? r.immersive : false;
14632 * @return whether the system should disable UI modes incompatible with VR mode.
14634 boolean shouldDisableNonVrUiLocked() {
14635 return mVrController.shouldDisableNonVrUiLocked();
14639 public boolean isTopOfTask(IBinder token) {
14640 synchronized (this) {
14641 ActivityRecord r = ActivityRecord.isInStackLocked(token);
14643 throw new IllegalArgumentException();
14645 return r.getTask().getTopActivity() == r;
14650 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14651 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14652 String msg = "Permission Denial: setHasTopUi() from pid="
14653 + Binder.getCallingPid()
14654 + ", uid=" + Binder.getCallingUid()
14655 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14657 throw new SecurityException(msg);
14659 final int pid = Binder.getCallingPid();
14660 final long origId = Binder.clearCallingIdentity();
14662 synchronized (this) {
14663 boolean changed = false;
14665 synchronized (mPidsSelfLocked) {
14666 pr = mPidsSelfLocked.get(pid);
14668 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14671 if (pr.hasTopUi != hasTopUi) {
14672 if (DEBUG_OOM_ADJ) {
14673 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14675 pr.hasTopUi = hasTopUi;
14680 updateOomAdjLocked(pr, true);
14684 Binder.restoreCallingIdentity(origId);
14688 void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
14689 if (pid == Process.myPid()) {
14690 Slog.wtf(TAG, "system can't run remote animation");
14693 synchronized (ActivityManagerService.this) {
14694 final ProcessRecord pr;
14695 synchronized (mPidsSelfLocked) {
14696 pr = mPidsSelfLocked.get(pid);
14698 Slog.w(TAG, "setRunningRemoteAnimation called on unknown pid: " + pid);
14702 if (pr.runningRemoteAnimation == runningRemoteAnimation) {
14705 pr.runningRemoteAnimation = runningRemoteAnimation;
14706 if (DEBUG_OOM_ADJ) {
14707 Slog.i(TAG, "Setting runningRemoteAnimation=" + pr.runningRemoteAnimation
14708 + " for pid=" + pid);
14710 updateOomAdjLocked(pr, true);
14714 public final void enterSafeMode() {
14715 synchronized(this) {
14716 // It only makes sense to do this before the system is ready
14717 // and started launching other packages.
14718 if (!mSystemReady) {
14720 AppGlobals.getPackageManager().enterSafeMode();
14721 } catch (RemoteException e) {
14729 public final void showSafeModeOverlay() {
14730 View v = LayoutInflater.from(mContext).inflate(
14731 com.android.internal.R.layout.safe_mode, null);
14732 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14733 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14734 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14735 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14736 lp.gravity = Gravity.BOTTOM | Gravity.START;
14737 lp.format = v.getBackground().getOpacity();
14738 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14739 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14740 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14741 ((WindowManager)mContext.getSystemService(
14742 Context.WINDOW_SERVICE)).addView(v, lp);
14746 public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14747 String sourcePkg, String tag) {
14748 if (workSource != null && workSource.isEmpty()) {
14752 if (sourceUid <= 0 && workSource == null) {
14753 // Try and derive a UID to attribute things to based on the caller.
14754 if (sender != null) {
14755 if (!(sender instanceof PendingIntentRecord)) {
14759 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14760 final int callerUid = Binder.getCallingUid();
14761 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14763 // TODO(narayan): Should we throw an exception in this case ? It means that we
14764 // haven't been able to derive a UID to attribute things to.
14770 Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14771 + ", workSource=" + workSource + ", tag=" + tag + "]");
14774 mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14778 public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14780 if (workSource != null && workSource.isEmpty()) {
14784 if (sourceUid <= 0 && workSource == null) {
14785 // Try and derive a UID to attribute things to based on the caller.
14786 if (sender != null) {
14787 if (!(sender instanceof PendingIntentRecord)) {
14791 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14792 final int callerUid = Binder.getCallingUid();
14793 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14795 // TODO(narayan): Should we throw an exception in this case ? It means that we
14796 // haven't been able to derive a UID to attribute things to.
14802 Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14803 ", tag=" + tag + "]");
14806 mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14810 public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14812 if (workSource != null && workSource.isEmpty()) {
14816 if (sourceUid <= 0 && workSource == null) {
14817 // Try and derive a UID to attribute things to based on the caller.
14818 if (sender != null) {
14819 if (!(sender instanceof PendingIntentRecord)) {
14823 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14824 final int callerUid = Binder.getCallingUid();
14825 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14827 // TODO(narayan): Should we throw an exception in this case ? It means that we
14828 // haven't been able to derive a UID to attribute things to.
14834 Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14835 ", tag=" + tag + "]");
14838 mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14841 public boolean killPids(int[] pids, String pReason, boolean secure) {
14842 if (Binder.getCallingUid() != SYSTEM_UID) {
14843 throw new SecurityException("killPids only available to the system");
14845 String reason = (pReason == null) ? "Unknown" : pReason;
14846 // XXX Note: don't acquire main activity lock here, because the window
14847 // manager calls in with its locks held.
14849 boolean killed = false;
14850 synchronized (mPidsSelfLocked) {
14852 for (int i=0; i<pids.length; i++) {
14853 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14854 if (proc != null) {
14855 int type = proc.setAdj;
14856 if (type > worstType) {
14862 // If the worst oom_adj is somewhere in the cached proc LRU range,
14863 // then constrain it so we will kill all cached procs.
14864 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14865 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14866 worstType = ProcessList.CACHED_APP_MIN_ADJ;
14869 // If this is not a secure call, don't let it kill processes that
14871 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14872 worstType = ProcessList.SERVICE_ADJ;
14875 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14876 for (int i=0; i<pids.length; i++) {
14877 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14878 if (proc == null) {
14881 int adj = proc.setAdj;
14882 if (adj >= worstType && !proc.killedByAm) {
14883 proc.kill(reason, true);
14892 public void killUid(int appId, int userId, String reason) {
14893 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14894 synchronized (this) {
14895 final long identity = Binder.clearCallingIdentity();
14897 killPackageProcessesLocked(null, appId, userId,
14898 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14899 reason != null ? reason : "kill uid");
14901 Binder.restoreCallingIdentity(identity);
14907 public boolean killProcessesBelowForeground(String reason) {
14908 if (Binder.getCallingUid() != SYSTEM_UID) {
14909 throw new SecurityException("killProcessesBelowForeground() only available to system");
14912 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14915 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14916 if (Binder.getCallingUid() != SYSTEM_UID) {
14917 throw new SecurityException("killProcessesBelowAdj() only available to system");
14920 boolean killed = false;
14921 synchronized (mPidsSelfLocked) {
14922 final int size = mPidsSelfLocked.size();
14923 for (int i = 0; i < size; i++) {
14924 final int pid = mPidsSelfLocked.keyAt(i);
14925 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14926 if (proc == null) continue;
14928 final int adj = proc.setAdj;
14929 if (adj > belowAdj && !proc.killedByAm) {
14930 proc.kill(reason, true);
14939 public void hang(final IBinder who, boolean allowRestart) {
14940 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14941 != PackageManager.PERMISSION_GRANTED) {
14942 throw new SecurityException("Requires permission "
14943 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14946 final IBinder.DeathRecipient death = new DeathRecipient() {
14948 public void binderDied() {
14949 synchronized (this) {
14956 who.linkToDeath(death, 0);
14957 } catch (RemoteException e) {
14958 Slog.w(TAG, "hang: given caller IBinder is already dead.");
14962 synchronized (this) {
14963 Watchdog.getInstance().setAllowRestart(allowRestart);
14964 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14965 synchronized (death) {
14966 while (who.isBinderAlive()) {
14969 } catch (InterruptedException e) {
14973 Watchdog.getInstance().setAllowRestart(true);
14978 public void restart() {
14979 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14980 != PackageManager.PERMISSION_GRANTED) {
14981 throw new SecurityException("Requires permission "
14982 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14985 Log.i(TAG, "Sending shutdown broadcast...");
14987 BroadcastReceiver br = new BroadcastReceiver() {
14988 @Override public void onReceive(Context context, Intent intent) {
14989 // Now the broadcast is done, finish up the low-level shutdown.
14990 Log.i(TAG, "Shutting down activity manager...");
14992 Log.i(TAG, "Shutdown complete, restarting!");
14993 killProcess(myPid());
14998 // First send the high-level shut down broadcast.
14999 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
15000 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15001 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
15002 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
15003 mContext.sendOrderedBroadcastAsUser(intent,
15004 UserHandle.ALL, null, br, mHandler, 0, null, null);
15006 br.onReceive(mContext, intent);
15009 private long getLowRamTimeSinceIdle(long now) {
15010 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
15014 public void performIdleMaintenance() {
15015 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15016 != PackageManager.PERMISSION_GRANTED) {
15017 throw new SecurityException("Requires permission "
15018 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15021 synchronized (this) {
15022 final long now = SystemClock.uptimeMillis();
15023 final long timeSinceLastIdle = now - mLastIdleTime;
15024 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
15025 mLastIdleTime = now;
15026 mLowRamTimeSinceLastIdle = 0;
15027 if (mLowRamStartTime != 0) {
15028 mLowRamStartTime = now;
15031 StringBuilder sb = new StringBuilder(128);
15032 sb.append("Idle maintenance over ");
15033 TimeUtils.formatDuration(timeSinceLastIdle, sb);
15034 sb.append(" low RAM for ");
15035 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
15036 Slog.i(TAG, sb.toString());
15038 // If at least 1/3 of our time since the last idle period has been spent
15039 // with RAM low, then we want to kill processes.
15040 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
15042 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15043 ProcessRecord proc = mLruProcesses.get(i);
15044 if (proc.notCachedSinceIdle) {
15045 if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
15046 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
15047 if (doKilling && proc.initialIdlePss != 0
15048 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
15049 sb = new StringBuilder(128);
15051 sb.append(proc.processName);
15052 sb.append(" in idle maint: pss=");
15053 sb.append(proc.lastPss);
15054 sb.append(", swapPss=");
15055 sb.append(proc.lastSwapPss);
15056 sb.append(", initialPss=");
15057 sb.append(proc.initialIdlePss);
15058 sb.append(", period=");
15059 TimeUtils.formatDuration(timeSinceLastIdle, sb);
15060 sb.append(", lowRamPeriod=");
15061 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
15062 Slog.wtfQuiet(TAG, sb.toString());
15063 proc.kill("idle maint (pss " + proc.lastPss
15064 + " from " + proc.initialIdlePss + ")", true);
15067 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
15068 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
15069 proc.notCachedSinceIdle = true;
15070 proc.initialIdlePss = 0;
15071 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
15072 mTestPssMode, isSleepingLocked(), now);
15079 public void sendIdleJobTrigger() {
15080 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15081 != PackageManager.PERMISSION_GRANTED) {
15082 throw new SecurityException("Requires permission "
15083 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15086 final long ident = Binder.clearCallingIdentity();
15088 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
15089 .setPackage("android")
15090 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15091 broadcastIntent(null, intent, null, null, 0, null, null, null,
15092 OP_NONE, null, false, false, UserHandle.USER_ALL);
15094 Binder.restoreCallingIdentity(ident);
15098 private void retrieveSettings() {
15099 final ContentResolver resolver = mContext.getContentResolver();
15100 final boolean freeformWindowManagement =
15101 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
15102 || Settings.Global.getInt(
15103 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
15105 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
15106 final boolean supportsPictureInPicture = supportsMultiWindow &&
15107 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
15108 final boolean supportsSplitScreenMultiWindow =
15109 ActivityManager.supportsSplitScreenMultiWindow(mContext);
15110 final boolean supportsMultiDisplay = mContext.getPackageManager()
15111 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
15112 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
15113 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
15114 final boolean alwaysFinishActivities =
15115 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
15116 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
15117 final boolean forceResizable = Settings.Global.getInt(
15118 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
15119 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
15120 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
15121 final boolean supportsLeanbackOnly =
15122 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
15123 mHiddenApiBlacklist.registerObserver();
15125 // Transfer any global setting for forcing RTL layout, into a System Property
15126 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
15128 final Configuration configuration = new Configuration();
15129 Settings.System.getConfiguration(resolver, configuration);
15131 // This will take care of setting the correct layout direction flags
15132 configuration.setLayoutDirection(configuration.locale);
15135 synchronized (this) {
15136 mDebugApp = mOrigDebugApp = debugApp;
15137 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
15138 mAlwaysFinishActivities = alwaysFinishActivities;
15139 mSupportsLeanbackOnly = supportsLeanbackOnly;
15140 mForceResizableActivities = forceResizable;
15141 final boolean multiWindowFormEnabled = freeformWindowManagement
15142 || supportsSplitScreenMultiWindow
15143 || supportsPictureInPicture
15144 || supportsMultiDisplay;
15145 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
15146 mSupportsMultiWindow = true;
15147 mSupportsFreeformWindowManagement = freeformWindowManagement;
15148 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
15149 mSupportsPictureInPicture = supportsPictureInPicture;
15150 mSupportsMultiDisplay = supportsMultiDisplay;
15152 mSupportsMultiWindow = false;
15153 mSupportsFreeformWindowManagement = false;
15154 mSupportsSplitScreenMultiWindow = false;
15155 mSupportsPictureInPicture = false;
15156 mSupportsMultiDisplay = false;
15158 mWindowManager.setForceResizableTasks(mForceResizableActivities);
15159 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
15160 // This happens before any activities are started, so we can change global configuration
15162 updateConfigurationLocked(configuration, null, true);
15163 final Configuration globalConfig = getGlobalConfiguration();
15164 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
15166 // Load resources only after the current configuration has been set.
15167 final Resources res = mContext.getResources();
15168 mThumbnailWidth = res.getDimensionPixelSize(
15169 com.android.internal.R.dimen.thumbnail_width);
15170 mThumbnailHeight = res.getDimensionPixelSize(
15171 com.android.internal.R.dimen.thumbnail_height);
15172 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
15173 com.android.internal.R.string.config_appsNotReportingCrashes));
15174 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
15175 com.android.internal.R.bool.config_customUserSwitchUi);
15176 mUserController.mMaxRunningUsers = res.getInteger(
15177 com.android.internal.R.integer.config_multiuserMaxRunningUsers);
15179 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
15180 mFullscreenThumbnailScale = (float) res
15181 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
15182 (float) globalConfig.screenWidthDp;
15184 mFullscreenThumbnailScale = res.getFraction(
15185 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
15187 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
15191 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
15192 traceLog.traceBegin("PhaseActivityManagerReady");
15193 synchronized(this) {
15194 if (mSystemReady) {
15195 // If we're done calling all the receivers, run the next "boot phase" passed in
15196 // by the SystemServer
15197 if (goingCallback != null) {
15198 goingCallback.run();
15203 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
15204 PackageManager.FEATURE_CANT_SAVE_STATE);
15205 mLocalDeviceIdleController
15206 = LocalServices.getService(DeviceIdleController.LocalService.class);
15207 mAssistUtils = new AssistUtils(mContext);
15208 mVrController.onSystemReady();
15209 // Make sure we have the current profile info, since it is needed for security checks.
15210 mUserController.onSystemReady();
15211 mRecentTasks.onSystemReadyLocked();
15212 mAppOpsService.systemReady();
15213 mSystemReady = true;
15217 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
15218 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
15220 } catch (RemoteException e) {}
15222 ArrayList<ProcessRecord> procsToKill = null;
15223 synchronized(mPidsSelfLocked) {
15224 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
15225 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
15226 if (!isAllowedWhileBooting(proc.info)){
15227 if (procsToKill == null) {
15228 procsToKill = new ArrayList<ProcessRecord>();
15230 procsToKill.add(proc);
15235 synchronized(this) {
15236 if (procsToKill != null) {
15237 for (int i=procsToKill.size()-1; i>=0; i--) {
15238 ProcessRecord proc = procsToKill.get(i);
15239 Slog.i(TAG, "Removing system update proc: " + proc);
15240 removeProcessLocked(proc, true, false, "system update done");
15244 // Now that we have cleaned up any update processes, we
15245 // are ready to start launching real processes and know that
15246 // we won't trample on them any more.
15247 mProcessesReady = true;
15250 Slog.i(TAG, "System now ready");
15251 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
15252 SystemClock.uptimeMillis());
15254 synchronized(this) {
15255 // Make sure we have no pre-ready processes sitting around.
15257 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
15258 ResolveInfo ri = mContext.getPackageManager()
15259 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
15261 CharSequence errorMsg = null;
15263 ActivityInfo ai = ri.activityInfo;
15264 ApplicationInfo app = ai.applicationInfo;
15265 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
15266 mTopAction = Intent.ACTION_FACTORY_TEST;
15268 mTopComponent = new ComponentName(app.packageName,
15271 errorMsg = mContext.getResources().getText(
15272 com.android.internal.R.string.factorytest_not_system);
15275 errorMsg = mContext.getResources().getText(
15276 com.android.internal.R.string.factorytest_no_action);
15278 if (errorMsg != null) {
15281 mTopComponent = null;
15282 Message msg = Message.obtain();
15283 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
15284 msg.getData().putCharSequence("msg", errorMsg);
15285 mUiHandler.sendMessage(msg);
15290 retrieveSettings();
15291 final int currentUserId = mUserController.getCurrentUserId();
15292 synchronized (this) {
15293 readGrantedUriPermissionsLocked();
15296 final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
15298 pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
15299 state -> updateForceBackgroundCheck(state.batterySaverEnabled));
15300 updateForceBackgroundCheck(
15301 pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
15303 Slog.wtf(TAG, "PowerManagerInternal not found.");
15306 if (goingCallback != null) goingCallback.run();
15307 traceLog.traceBegin("ActivityManagerStartApps");
15308 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
15309 Integer.toString(currentUserId), currentUserId);
15310 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
15311 Integer.toString(currentUserId), currentUserId);
15312 mSystemServiceManager.startUser(currentUserId);
15314 synchronized (this) {
15315 // Only start up encryption-aware persistent apps; once user is
15316 // unlocked we'll come back around and start unaware apps
15317 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
15319 // Start up initial activity.
15321 // Enable home activity for system user, so that the system can always boot. We don't
15322 // do this when the system user is not setup since the setup wizard should be the one
15323 // to handle home activity in this case.
15324 if (UserManager.isSplitSystemUser() &&
15325 Settings.Secure.getInt(mContext.getContentResolver(),
15326 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
15327 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
15329 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
15330 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
15331 UserHandle.USER_SYSTEM);
15332 } catch (RemoteException e) {
15333 throw e.rethrowAsRuntimeException();
15336 startHomeActivityLocked(currentUserId, "systemReady");
15339 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
15340 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
15341 + " data partition or your device will be unstable.");
15342 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
15344 } catch (RemoteException e) {
15347 if (!Build.isBuildConsistent()) {
15348 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
15349 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
15352 long ident = Binder.clearCallingIdentity();
15354 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15355 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15356 | Intent.FLAG_RECEIVER_FOREGROUND);
15357 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15358 broadcastIntentLocked(null, null, intent,
15359 null, null, 0, null, null, null, OP_NONE,
15360 null, false, false, MY_PID, SYSTEM_UID,
15362 intent = new Intent(Intent.ACTION_USER_STARTING);
15363 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15364 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15365 broadcastIntentLocked(null, null, intent,
15366 null, new IIntentReceiver.Stub() {
15368 public void performReceive(Intent intent, int resultCode, String data,
15369 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
15370 throws RemoteException {
15373 new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
15374 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
15375 } catch (Throwable t) {
15376 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
15378 Binder.restoreCallingIdentity(ident);
15380 mStackSupervisor.resumeFocusedStackTopActivityLocked();
15381 mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
15383 BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
15384 BinderInternal.nSetBinderProxyCountEnabled(true);
15385 BinderInternal.setBinderProxyCountCallback(
15386 new BinderInternal.BinderProxyLimitListener() {
15388 public void onLimitReached(int uid) {
15389 Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
15390 + Process.myUid());
15391 if (uid == Process.SYSTEM_UID) {
15392 Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
15394 killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
15395 "Too many Binders sent to SYSTEM");
15400 traceLog.traceEnd(); // ActivityManagerStartApps
15401 traceLog.traceEnd(); // PhaseActivityManagerReady
15405 private void updateForceBackgroundCheck(boolean enabled) {
15406 synchronized (this) {
15407 if (mForceBackgroundCheck != enabled) {
15408 mForceBackgroundCheck = enabled;
15410 if (DEBUG_BACKGROUND_CHECK) {
15411 Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
15414 if (mForceBackgroundCheck) {
15415 // Stop background services for idle UIDs.
15416 doStopUidForIdleUidsLocked();
15422 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
15423 synchronized (this) {
15424 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
15428 void skipCurrentReceiverLocked(ProcessRecord app) {
15429 for (BroadcastQueue queue : mBroadcastQueues) {
15430 queue.skipCurrentReceiverLocked(app);
15435 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
15436 * The application process will exit immediately after this call returns.
15437 * @param app object of the crashing app, null for the system server
15438 * @param crashInfo describing the exception
15440 public void handleApplicationCrash(IBinder app,
15441 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15442 ProcessRecord r = findAppProcess(app, "Crash");
15443 final String processName = app == null ? "system_server"
15444 : (r == null ? "unknown" : r.processName);
15446 handleApplicationCrashInner("crash", r, processName, crashInfo);
15449 /* Native crash reporting uses this inner version because it needs to be somewhat
15450 * decoupled from the AM-managed cleanup lifecycle
15452 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
15453 ApplicationErrorReport.CrashInfo crashInfo) {
15454 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
15455 UserHandle.getUserId(Binder.getCallingUid()), processName,
15456 r == null ? -1 : r.info.flags,
15457 crashInfo.exceptionClassName,
15458 crashInfo.exceptionMessage,
15459 crashInfo.throwFileName,
15460 crashInfo.throwLineNumber);
15462 StatsLog.write(StatsLog.APP_CRASH_OCCURRED,
15463 Binder.getCallingUid(),
15466 Binder.getCallingPid(),
15467 (r != null && r.info != null) ? r.info.packageName : "",
15468 (r != null && r.info != null) ? (r.info.isInstantApp()
15469 ? StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__TRUE
15470 : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__FALSE)
15471 : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__UNAVAILABLE,
15472 r != null ? (r.isInterestingToUserLocked()
15473 ? StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__FOREGROUND
15474 : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__BACKGROUND)
15475 : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN
15478 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
15480 mAppErrors.crashApplication(r, crashInfo);
15483 public void handleApplicationStrictModeViolation(
15486 StrictMode.ViolationInfo info) {
15487 // We're okay if the ProcessRecord is missing; it probably means that
15488 // we're reporting a violation from the system process itself.
15489 final ProcessRecord r = findAppProcess(app, "StrictMode");
15491 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
15492 Integer stackFingerprint = info.hashCode();
15493 boolean logIt = true;
15494 synchronized (mAlreadyLoggedViolatedStacks) {
15495 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
15497 // TODO: sub-sample into EventLog for these, with
15498 // the info.durationMillis? Then we'd get
15499 // the relative pain numbers, without logging all
15500 // the stack traces repeatedly. We'd want to do
15501 // likewise in the client code, which also does
15502 // dup suppression, before the Binder call.
15504 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
15505 mAlreadyLoggedViolatedStacks.clear();
15507 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
15511 logStrictModeViolationToDropBox(r, info);
15515 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
15516 AppErrorResult result = new AppErrorResult();
15517 synchronized (this) {
15518 final long origId = Binder.clearCallingIdentity();
15520 Message msg = Message.obtain();
15521 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
15522 HashMap<String, Object> data = new HashMap<String, Object>();
15523 data.put("result", result);
15524 data.put("app", r);
15525 data.put("violationMask", violationMask);
15526 data.put("info", info);
15528 mUiHandler.sendMessage(msg);
15530 Binder.restoreCallingIdentity(origId);
15532 int res = result.get();
15533 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
15537 // Depending on the policy in effect, there could be a bunch of
15538 // these in quick succession so we try to batch these together to
15539 // minimize disk writes, number of dropbox entries, and maximize
15540 // compression, by having more fewer, larger records.
15541 private void logStrictModeViolationToDropBox(
15542 ProcessRecord process,
15543 StrictMode.ViolationInfo info) {
15544 if (info == null) {
15547 final boolean isSystemApp = process == null ||
15548 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
15549 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
15550 final String processName = process == null ? "unknown" : process.processName;
15551 final DropBoxManager dbox = (DropBoxManager)
15552 mContext.getSystemService(Context.DROPBOX_SERVICE);
15554 // Exit early if the dropbox isn't configured to accept this report type.
15555 final String dropboxTag = processClass(process) + "_strictmode";
15556 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15558 final StringBuilder sb = new StringBuilder(1024);
15559 synchronized (sb) {
15560 appendDropBoxProcessHeaders(process, processName, sb);
15561 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15562 sb.append("System-App: ").append(isSystemApp).append("\n");
15563 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
15564 if (info.violationNumThisLoop != 0) {
15565 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
15567 if (info.numAnimationsRunning != 0) {
15568 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
15570 if (info.broadcastIntentAction != null) {
15571 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
15573 if (info.durationMillis != -1) {
15574 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
15576 if (info.numInstances != -1) {
15577 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
15579 if (info.tags != null) {
15580 for (String tag : info.tags) {
15581 sb.append("Span-Tag: ").append(tag).append("\n");
15585 sb.append(info.getStackTrace());
15587 if (info.getViolationDetails() != null) {
15588 sb.append(info.getViolationDetails());
15593 final String res = sb.toString();
15594 IoThread.getHandler().post(() -> {
15595 dbox.addText(dropboxTag, res);
15600 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
15601 * @param app object of the crashing app, null for the system server
15602 * @param tag reported by the caller
15603 * @param system whether this wtf is coming from the system
15604 * @param crashInfo describing the context of the error
15605 * @return true if the process should exit immediately (WTF is fatal)
15607 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
15608 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15609 final int callingUid = Binder.getCallingUid();
15610 final int callingPid = Binder.getCallingPid();
15613 // If this is coming from the system, we could very well have low-level
15614 // system locks held, so we want to do this all asynchronously. And we
15615 // never want this to become fatal, so there is that too.
15616 mHandler.post(new Runnable() {
15617 @Override public void run() {
15618 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
15624 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
15627 final boolean isFatal = Build.IS_ENG || Settings.Global
15628 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
15629 final boolean isSystem = (r == null) || r.persistent;
15631 if (isFatal && !isSystem) {
15632 mAppErrors.crashApplication(r, crashInfo);
15639 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
15640 final ApplicationErrorReport.CrashInfo crashInfo) {
15641 final ProcessRecord r = findAppProcess(app, "WTF");
15642 final String processName = app == null ? "system_server"
15643 : (r == null ? "unknown" : r.processName);
15645 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15646 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15648 StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
15651 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15657 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15658 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15660 private ProcessRecord findAppProcess(IBinder app, String reason) {
15665 synchronized (this) {
15666 final int NP = mProcessNames.getMap().size();
15667 for (int ip=0; ip<NP; ip++) {
15668 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15669 final int NA = apps.size();
15670 for (int ia=0; ia<NA; ia++) {
15671 ProcessRecord p = apps.valueAt(ia);
15672 if (p.thread != null && p.thread.asBinder() == app) {
15678 Slog.w(TAG, "Can't find mystery application for " + reason
15679 + " from pid=" + Binder.getCallingPid()
15680 + " uid=" + Binder.getCallingUid() + ": " + app);
15686 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15687 * to append various headers to the dropbox log text.
15689 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15690 StringBuilder sb) {
15691 // Watchdog thread ends up invoking this function (with
15692 // a null ProcessRecord) to add the stack file to dropbox.
15693 // Do not acquire a lock on this (am) in such cases, as it
15694 // could cause a potential deadlock, if and when watchdog
15695 // is invoked due to unavailability of lock on am and it
15696 // would prevent watchdog from killing system_server.
15697 if (process == null) {
15698 sb.append("Process: ").append(processName).append("\n");
15701 // Note: ProcessRecord 'process' is guarded by the service
15702 // instance. (notably process.pkgList, which could otherwise change
15703 // concurrently during execution of this method)
15704 synchronized (this) {
15705 sb.append("Process: ").append(processName).append("\n");
15706 sb.append("PID: ").append(process.pid).append("\n");
15707 int flags = process.info.flags;
15708 IPackageManager pm = AppGlobals.getPackageManager();
15709 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15710 for (int ip=0; ip<process.pkgList.size(); ip++) {
15711 String pkg = process.pkgList.keyAt(ip);
15712 sb.append("Package: ").append(pkg);
15714 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15716 sb.append(" v").append(pi.getLongVersionCode());
15717 if (pi.versionName != null) {
15718 sb.append(" (").append(pi.versionName).append(")");
15721 } catch (RemoteException e) {
15722 Slog.e(TAG, "Error getting package info: " + pkg, e);
15726 if (process.info.isInstantApp()) {
15727 sb.append("Instant-App: true\n");
15732 private static String processClass(ProcessRecord process) {
15733 if (process == null || process.pid == MY_PID) {
15734 return "system_server";
15735 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15736 return "system_app";
15742 private volatile long mWtfClusterStart;
15743 private volatile int mWtfClusterCount;
15746 * Write a description of an error (crash, WTF, ANR) to the drop box.
15747 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15748 * @param process which caused the error, null means the system server
15749 * @param activity which triggered the error, null if unknown
15750 * @param parent activity related to the error, null if unknown
15751 * @param subject line related to the error, null if absent
15752 * @param report in long form describing the error, null if absent
15753 * @param dataFile text file to include in the report, null if none
15754 * @param crashInfo giving an application stack trace, null if absent
15756 public void addErrorToDropBox(String eventType,
15757 ProcessRecord process, String processName, ActivityRecord activity,
15758 ActivityRecord parent, String subject,
15759 final String report, final File dataFile,
15760 final ApplicationErrorReport.CrashInfo crashInfo) {
15761 // NOTE -- this must never acquire the ActivityManagerService lock,
15762 // otherwise the watchdog may be prevented from resetting the system.
15764 // Bail early if not published yet
15765 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15766 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15768 // Exit early if the dropbox isn't configured to accept this report type.
15769 final String dropboxTag = processClass(process) + "_" + eventType;
15770 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15772 // Rate-limit how often we're willing to do the heavy lifting below to
15773 // collect and record logs; currently 5 logs per 10 second period.
15774 final long now = SystemClock.elapsedRealtime();
15775 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15776 mWtfClusterStart = now;
15777 mWtfClusterCount = 1;
15779 if (mWtfClusterCount++ >= 5) return;
15782 final StringBuilder sb = new StringBuilder(1024);
15783 appendDropBoxProcessHeaders(process, processName, sb);
15784 if (process != null) {
15785 sb.append("Foreground: ")
15786 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15789 if (activity != null) {
15790 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15792 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15793 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15795 if (parent != null && parent != activity) {
15796 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15798 if (subject != null) {
15799 sb.append("Subject: ").append(subject).append("\n");
15801 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15802 if (Debug.isDebuggerConnected()) {
15803 sb.append("Debugger: Connected\n");
15807 // Do the rest in a worker thread to avoid blocking the caller on I/O
15808 // (After this point, we shouldn't access AMS internal data structures.)
15809 Thread worker = new Thread("Error dump: " + dropboxTag) {
15811 public void run() {
15812 if (report != null) {
15816 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15817 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15818 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15819 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15821 if (dataFile != null && maxDataFileSize > 0) {
15823 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15824 "\n\n[[TRUNCATED]]"));
15825 } catch (IOException e) {
15826 Slog.e(TAG, "Error reading " + dataFile, e);
15829 if (crashInfo != null && crashInfo.stackTrace != null) {
15830 sb.append(crashInfo.stackTrace);
15836 // Merge several logcat streams, and take the last N lines
15837 InputStreamReader input = null;
15839 java.lang.Process logcat = new ProcessBuilder(
15840 "/system/bin/timeout", "-k", "15s", "10s",
15841 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15842 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15843 .redirectErrorStream(true).start();
15845 try { logcat.getOutputStream().close(); } catch (IOException e) {}
15846 try { logcat.getErrorStream().close(); } catch (IOException e) {}
15847 input = new InputStreamReader(logcat.getInputStream());
15850 char[] buf = new char[8192];
15851 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15852 } catch (IOException e) {
15853 Slog.e(TAG, "Error running logcat", e);
15855 if (input != null) try { input.close(); } catch (IOException e) {}
15859 dbox.addText(dropboxTag, sb.toString());
15863 if (process == null) {
15864 // If process is null, we are being called from some internal code
15865 // and may be about to die -- run this synchronously.
15866 final int oldMask = StrictMode.allowThreadDiskWritesMask();
15870 StrictMode.setThreadPolicyMask(oldMask);
15878 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15879 enforceNotIsolatedCaller("getProcessesInErrorState");
15880 // assume our apps are happy - lazy create the list
15881 List<ActivityManager.ProcessErrorStateInfo> errList = null;
15883 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15884 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15885 int userId = UserHandle.getUserId(Binder.getCallingUid());
15887 synchronized (this) {
15889 // iterate across all processes
15890 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15891 ProcessRecord app = mLruProcesses.get(i);
15892 if (!allUsers && app.userId != userId) {
15895 if ((app.thread != null) && (app.crashing || app.notResponding)) {
15896 // This one's in trouble, so we'll generate a report for it
15897 // crashes are higher priority (in case there's a crash *and* an anr)
15898 ActivityManager.ProcessErrorStateInfo report = null;
15899 if (app.crashing) {
15900 report = app.crashingReport;
15901 } else if (app.notResponding) {
15902 report = app.notRespondingReport;
15905 if (report != null) {
15906 if (errList == null) {
15907 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15909 errList.add(report);
15911 Slog.w(TAG, "Missing app error report, app = " + app.processName +
15912 " crashing = " + app.crashing +
15913 " notResponding = " + app.notResponding);
15922 static int procStateToImportance(int procState, int memAdj,
15923 ActivityManager.RunningAppProcessInfo currApp,
15924 int clientTargetSdk) {
15925 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15926 procState, clientTargetSdk);
15927 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15928 currApp.lru = memAdj;
15935 private void fillInProcMemInfo(ProcessRecord app,
15936 ActivityManager.RunningAppProcessInfo outInfo,
15937 int clientTargetSdk) {
15938 outInfo.pid = app.pid;
15939 outInfo.uid = app.info.uid;
15940 if (mHeavyWeightProcess == app) {
15941 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15943 if (app.persistent) {
15944 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15946 if (app.activities.size() > 0) {
15947 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15949 outInfo.lastTrimLevel = app.trimMemoryLevel;
15950 int adj = app.curAdj;
15951 int procState = app.curProcState;
15952 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15953 outInfo.importanceReasonCode = app.adjTypeCode;
15954 outInfo.processState = app.curProcState;
15958 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15959 enforceNotIsolatedCaller("getRunningAppProcesses");
15961 final int callingUid = Binder.getCallingUid();
15962 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15964 // Lazy instantiation of list
15965 List<ActivityManager.RunningAppProcessInfo> runList = null;
15966 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15967 callingUid) == PackageManager.PERMISSION_GRANTED;
15968 final int userId = UserHandle.getUserId(callingUid);
15969 final boolean allUids = isGetTasksAllowed(
15970 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15972 synchronized (this) {
15973 // Iterate across all processes
15974 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15975 ProcessRecord app = mLruProcesses.get(i);
15976 if ((!allUsers && app.userId != userId)
15977 || (!allUids && app.uid != callingUid)) {
15980 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15981 // Generate process state info for running application
15982 ActivityManager.RunningAppProcessInfo currApp =
15983 new ActivityManager.RunningAppProcessInfo(app.processName,
15984 app.pid, app.getPackageList());
15985 fillInProcMemInfo(app, currApp, clientTargetSdk);
15986 if (app.adjSource instanceof ProcessRecord) {
15987 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15988 currApp.importanceReasonImportance =
15989 ActivityManager.RunningAppProcessInfo.procStateToImportance(
15990 app.adjSourceProcState);
15991 } else if (app.adjSource instanceof ActivityRecord) {
15992 ActivityRecord r = (ActivityRecord)app.adjSource;
15993 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15995 if (app.adjTarget instanceof ComponentName) {
15996 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15998 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15999 // + " lru=" + currApp.lru);
16000 if (runList == null) {
16001 runList = new ArrayList<>();
16003 runList.add(currApp);
16011 public List<ApplicationInfo> getRunningExternalApplications() {
16012 enforceNotIsolatedCaller("getRunningExternalApplications");
16013 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
16014 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
16015 if (runningApps != null && runningApps.size() > 0) {
16016 Set<String> extList = new HashSet<String>();
16017 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
16018 if (app.pkgList != null) {
16019 for (String pkg : app.pkgList) {
16024 IPackageManager pm = AppGlobals.getPackageManager();
16025 for (String pkg : extList) {
16027 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
16028 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
16031 } catch (RemoteException e) {
16039 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outState) {
16040 if (outState == null) {
16041 throw new IllegalArgumentException("outState is null");
16043 enforceNotIsolatedCaller("getMyMemoryState");
16045 final int callingUid = Binder.getCallingUid();
16046 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
16048 synchronized (this) {
16049 ProcessRecord proc;
16050 synchronized (mPidsSelfLocked) {
16051 proc = mPidsSelfLocked.get(Binder.getCallingPid());
16053 if (proc != null) {
16054 fillInProcMemInfo(proc, outState, clientTargetSdk);
16060 public int getMemoryTrimLevel() {
16061 enforceNotIsolatedCaller("getMyMemoryState");
16062 synchronized (this) {
16063 return mLastMemoryLevel;
16068 public void onShellCommand(FileDescriptor in, FileDescriptor out,
16069 FileDescriptor err, String[] args, ShellCallback callback,
16070 ResultReceiver resultReceiver) {
16071 (new ActivityManagerShellCommand(this, false)).exec(
16072 this, in, out, err, args, callback, resultReceiver);
16075 SleepToken acquireSleepToken(String tag, int displayId) {
16076 synchronized (this) {
16077 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
16078 updateSleepIfNeededLocked();
16084 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
16085 PriorityDump.dump(mPriorityDumper, fd, pw, args);
16089 * Wrapper function to print out debug data filtered by specified arguments.
16091 private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
16092 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
16094 boolean dumpAll = false;
16095 boolean dumpClient = false;
16096 boolean dumpCheckin = false;
16097 boolean dumpCheckinFormat = false;
16098 boolean dumpNormalPriority = false;
16099 boolean dumpVisibleStacksOnly = false;
16100 boolean dumpFocusedStackOnly = false;
16101 String dumpPackage = null;
16104 while (opti < args.length) {
16105 String opt = args[opti];
16106 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16110 if ("-a".equals(opt)) {
16112 } else if ("-c".equals(opt)) {
16114 } else if ("-v".equals(opt)) {
16115 dumpVisibleStacksOnly = true;
16116 } else if ("-f".equals(opt)) {
16117 dumpFocusedStackOnly = true;
16118 } else if ("-p".equals(opt)) {
16119 if (opti < args.length) {
16120 dumpPackage = args[opti];
16123 pw.println("Error: -p option requires package argument");
16127 } else if ("--checkin".equals(opt)) {
16128 dumpCheckin = dumpCheckinFormat = true;
16129 } else if ("-C".equals(opt)) {
16130 dumpCheckinFormat = true;
16131 } else if ("--normal-priority".equals(opt)) {
16132 dumpNormalPriority = true;
16133 } else if ("-h".equals(opt)) {
16134 ActivityManagerShellCommand.dumpHelp(pw, true);
16137 pw.println("Unknown argument: " + opt + "; use -h for help");
16141 long origId = Binder.clearCallingIdentity();
16144 final ProtoOutputStream proto = new ProtoOutputStream(fd);
16145 String cmd = opti < args.length ? args[opti] : "";
16148 if ("activities".equals(cmd) || "a".equals(cmd)) {
16149 // output proto is ActivityManagerServiceDumpActivitiesProto
16150 synchronized (this) {
16151 writeActivitiesToProtoLocked(proto);
16153 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16154 // output proto is ActivityManagerServiceDumpBroadcastsProto
16155 synchronized (this) {
16156 writeBroadcastsToProtoLocked(proto);
16158 } else if ("provider".equals(cmd)) {
16161 if (opti >= args.length) {
16163 newArgs = EMPTY_STRING_ARRAY;
16167 newArgs = new String[args.length - opti];
16168 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16169 args.length - opti);
16171 if (!dumpProviderProto(fd, pw, name, newArgs)) {
16172 pw.println("No providers match: " + name);
16173 pw.println("Use -h for help.");
16175 } else if ("service".equals(cmd)) {
16176 // output proto is ActivityManagerServiceDumpServicesProto
16177 mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16178 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16179 if (opti < args.length) {
16180 dumpPackage = args[opti];
16183 // output proto is ProcessProto
16184 synchronized (this) {
16185 writeProcessesToProtoLocked(proto, dumpPackage);
16188 // default option, dump everything, output is ActivityManagerServiceProto
16189 synchronized (this) {
16190 long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
16191 writeActivitiesToProtoLocked(proto);
16192 proto.end(activityToken);
16194 long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
16195 writeBroadcastsToProtoLocked(proto);
16196 proto.end(broadcastToken);
16198 long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
16199 mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16200 proto.end(serviceToken);
16202 long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
16203 writeProcessesToProtoLocked(proto, dumpPackage);
16204 proto.end(processToken);
16208 Binder.restoreCallingIdentity(origId);
16212 int dumpAppId = getAppId(dumpPackage);
16213 boolean more = false;
16214 // Is the caller requesting to dump a particular piece of data?
16215 if (opti < args.length) {
16216 String cmd = args[opti];
16218 if ("activities".equals(cmd) || "a".equals(cmd)) {
16219 synchronized (this) {
16220 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16222 } else if ("lastanr".equals(cmd)) {
16223 synchronized (this) {
16224 dumpLastANRLocked(pw);
16226 } else if ("starter".equals(cmd)) {
16227 synchronized (this) {
16228 dumpActivityStarterLocked(pw, dumpPackage);
16230 } else if ("containers".equals(cmd)) {
16231 synchronized (this) {
16232 dumpActivityContainersLocked(pw);
16234 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
16235 synchronized (this) {
16236 if (mRecentTasks != null) {
16237 mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
16240 } else if ("binder-proxies".equals(cmd)) {
16241 if (opti >= args.length) {
16242 dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
16243 "Counts of Binder Proxies held by SYSTEM");
16245 String uid = args[opti];
16247 // Ensure Binder Proxy Count is as up to date as possible
16249 System.runFinalization();
16251 pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
16253 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16254 if (opti < args.length) {
16255 dumpPackage = args[opti];
16258 synchronized (this) {
16259 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
16261 } else if ("broadcast-stats".equals(cmd)) {
16262 if (opti < args.length) {
16263 dumpPackage = args[opti];
16266 synchronized (this) {
16267 if (dumpCheckinFormat) {
16268 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
16271 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
16274 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
16275 if (opti < args.length) {
16276 dumpPackage = args[opti];
16279 synchronized (this) {
16280 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
16282 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16283 if (opti < args.length) {
16284 dumpPackage = args[opti];
16287 synchronized (this) {
16288 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
16290 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
16291 synchronized (this) {
16292 dumpOomLocked(fd, pw, args, opti, true);
16294 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
16295 synchronized (this) {
16296 dumpPermissionsLocked(fd, pw, args, opti, true, null);
16298 } else if ("provider".equals(cmd)) {
16301 if (opti >= args.length) {
16303 newArgs = EMPTY_STRING_ARRAY;
16307 newArgs = new String[args.length - opti];
16308 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16310 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
16311 pw.println("No providers match: " + name);
16312 pw.println("Use -h for help.");
16314 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
16315 synchronized (this) {
16316 dumpProvidersLocked(fd, pw, args, opti, true, null);
16318 } else if ("service".equals(cmd)) {
16321 if (opti >= args.length) {
16323 newArgs = EMPTY_STRING_ARRAY;
16327 newArgs = new String[args.length - opti];
16328 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16329 args.length - opti);
16331 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
16332 pw.println("No services match: " + name);
16333 pw.println("Use -h for help.");
16335 } else if ("package".equals(cmd)) {
16337 if (opti >= args.length) {
16338 pw.println("package: no package name specified");
16339 pw.println("Use -h for help.");
16341 dumpPackage = args[opti];
16343 newArgs = new String[args.length - opti];
16344 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16345 args.length - opti);
16350 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
16351 synchronized (this) {
16352 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16354 } else if ("settings".equals(cmd)) {
16355 synchronized (this) {
16356 mConstants.dump(pw);
16358 } else if ("services".equals(cmd) || "s".equals(cmd)) {
16360 ActiveServices.ServiceDumper dumper;
16361 synchronized (this) {
16362 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16365 dumper.dumpWithClient();
16367 synchronized (this) {
16368 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16369 dumpPackage).dumpLocked();
16372 } else if ("locks".equals(cmd)) {
16373 LockGuard.dump(fd, pw, args);
16375 // Dumping a single activity?
16376 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
16377 dumpFocusedStackOnly)) {
16378 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
16379 int res = shell.exec(this, null, fd, null, args, null,
16380 new ResultReceiver(null));
16382 pw.println("Bad activity command, or no activities match: " + cmd);
16383 pw.println("Use -h for help.");
16388 Binder.restoreCallingIdentity(origId);
16393 // No piece of data specified, dump everything.
16394 if (dumpCheckinFormat) {
16395 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
16396 } else if (dumpClient) {
16397 ActiveServices.ServiceDumper sdumper;
16398 synchronized (this) {
16399 mConstants.dump(pw);
16402 pw.println("-------------------------------------------------------------------------------");
16404 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16407 pw.println("-------------------------------------------------------------------------------");
16409 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16412 pw.println("-------------------------------------------------------------------------------");
16414 if (dumpAll || dumpPackage != null) {
16415 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16418 pw.println("-------------------------------------------------------------------------------");
16421 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16424 pw.println("-------------------------------------------------------------------------------");
16426 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16429 pw.println("-------------------------------------------------------------------------------");
16431 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
16434 sdumper.dumpWithClient();
16436 synchronized (this) {
16438 pw.println("-------------------------------------------------------------------------------");
16440 if (mRecentTasks != null) {
16441 mRecentTasks.dump(pw, dumpAll, dumpPackage);
16445 pw.println("-------------------------------------------------------------------------------");
16447 dumpLastANRLocked(pw);
16450 pw.println("-------------------------------------------------------------------------------");
16452 dumpActivityStarterLocked(pw, dumpPackage);
16455 pw.println("-------------------------------------------------------------------------------");
16457 dumpActivityContainersLocked(pw);
16460 pw.println("-------------------------------------------------------------------------------");
16462 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16463 if (mAssociations.size() > 0) {
16466 pw.println("-------------------------------------------------------------------------------");
16468 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16472 pw.println("-------------------------------------------------------------------------------");
16474 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16478 synchronized (this) {
16479 mConstants.dump(pw);
16482 pw.println("-------------------------------------------------------------------------------");
16484 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16487 pw.println("-------------------------------------------------------------------------------");
16489 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16492 pw.println("-------------------------------------------------------------------------------");
16494 if (dumpAll || dumpPackage != null) {
16495 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16498 pw.println("-------------------------------------------------------------------------------");
16501 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16504 pw.println("-------------------------------------------------------------------------------");
16506 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16509 pw.println("-------------------------------------------------------------------------------");
16511 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
16515 pw.println("-------------------------------------------------------------------------------");
16517 if (mRecentTasks != null) {
16518 mRecentTasks.dump(pw, dumpAll, dumpPackage);
16522 pw.println("-------------------------------------------------------------------------------");
16524 dumpLastANRLocked(pw);
16527 pw.println("-------------------------------------------------------------------------------");
16529 dumpActivityStarterLocked(pw, dumpPackage);
16532 pw.println("-------------------------------------------------------------------------------");
16534 dumpActivityContainersLocked(pw);
16535 // Activities section is dumped as part of the Critical priority dump. Exclude the
16536 // section if priority is Normal.
16537 if (!dumpNormalPriority){
16540 pw.println("-------------------------------------------------------------------------------");
16542 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16544 if (mAssociations.size() > 0) {
16547 pw.println("-------------------------------------------------------------------------------");
16549 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16553 pw.println("-------------------------------------------------------------------------------");
16555 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16558 Binder.restoreCallingIdentity(origId);
16561 private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
16562 // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
16563 mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
16566 private void dumpLastANRLocked(PrintWriter pw) {
16567 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
16568 if (mLastANRState == null) {
16569 pw.println(" <no ANR has occurred since boot>");
16571 pw.println(mLastANRState);
16575 private void dumpActivityContainersLocked(PrintWriter pw) {
16576 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
16577 mStackSupervisor.dumpChildrenNames(pw, " ");
16581 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
16582 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
16583 mActivityStartController.dump(pw, "", dumpPackage);
16586 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16587 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16588 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
16589 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
16592 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16593 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
16594 pw.println(header);
16596 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
16598 boolean needSep = printedAnything;
16600 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
16601 mStackSupervisor.getResumedActivityLocked(),
16602 dumpPackage, needSep, " ResumedActivity: ");
16604 printedAnything = true;
16608 if (dumpPackage == null) {
16612 printedAnything = true;
16613 mStackSupervisor.dump(pw, " ");
16616 if (!printedAnything) {
16617 pw.println(" (nothing)");
16621 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16622 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16623 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
16626 if (dumpPackage != null) {
16627 IPackageManager pm = AppGlobals.getPackageManager();
16629 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16630 } catch (RemoteException e) {
16634 boolean printedAnything = false;
16636 final long now = SystemClock.uptimeMillis();
16638 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
16639 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
16640 = mAssociations.valueAt(i1);
16641 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
16642 SparseArray<ArrayMap<String, Association>> sourceUids
16643 = targetComponents.valueAt(i2);
16644 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
16645 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
16646 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
16647 Association ass = sourceProcesses.valueAt(i4);
16648 if (dumpPackage != null) {
16649 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16650 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16654 printedAnything = true;
16656 pw.print(ass.mTargetProcess);
16658 UserHandle.formatUid(pw, ass.mTargetUid);
16660 pw.print(ass.mSourceProcess);
16662 UserHandle.formatUid(pw, ass.mSourceUid);
16665 pw.print(ass.mTargetComponent.flattenToShortString());
16668 long dur = ass.mTime;
16669 if (ass.mNesting > 0) {
16670 dur += now - ass.mStartTime;
16672 TimeUtils.formatDuration(dur, pw);
16674 pw.print(ass.mCount);
16675 pw.print(" times)");
16677 for (int i=0; i<ass.mStateTimes.length; i++) {
16678 long amt = ass.mStateTimes[i];
16679 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16680 amt += now - ass.mLastStateUptime;
16684 pw.print(ProcessList.makeProcStateString(
16685 i + ActivityManager.MIN_PROCESS_STATE));
16687 TimeUtils.formatDuration(amt, pw);
16688 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16694 if (ass.mNesting > 0) {
16695 pw.print(" Currently active: ");
16696 TimeUtils.formatDuration(now - ass.mStartTime, pw);
16705 if (!printedAnything) {
16706 pw.println(" (nothing)");
16710 private int getAppId(String dumpPackage) {
16711 if (dumpPackage != null) {
16713 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16715 return UserHandle.getAppId(info.uid);
16716 } catch (NameNotFoundException e) {
16717 e.printStackTrace();
16723 boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16724 String header, boolean needSep) {
16725 boolean printed = false;
16726 for (int i=0; i<uids.size(); i++) {
16727 UidRecord uidRec = uids.valueAt(i);
16728 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16737 pw.println(header);
16740 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
16741 pw.print(": "); pw.println(uidRec);
16746 boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16747 if(counts != null) {
16748 pw.println(header);
16749 for (int i = 0; i < counts.size(); i++) {
16750 final int uid = counts.keyAt(i);
16751 final int binderCount = counts.valueAt(i);
16754 pw.print(", binder count = ");
16755 pw.print(binderCount);
16756 pw.print(", package(s)= ");
16757 final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16758 if (pkgNames != null) {
16759 for (int j = 0; j < pkgNames.length; j++) {
16760 pw.print(pkgNames[j]);
16764 pw.print("NO PACKAGE NAME FOUND");
16775 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16776 int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16777 boolean needSep = false;
16780 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16783 final int NP = mProcessNames.getMap().size();
16784 for (int ip=0; ip<NP; ip++) {
16785 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16786 final int NA = procs.size();
16787 for (int ia=0; ia<NA; ia++) {
16788 ProcessRecord r = procs.valueAt(ia);
16789 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16793 pw.println(" All known processes:");
16796 pw.print(r.persistent ? " *PERS*" : " *APP*");
16797 pw.print(" UID "); pw.print(procs.keyAt(ia));
16798 pw.print(" "); pw.println(r);
16800 if (r.persistent) {
16807 if (mIsolatedProcesses.size() > 0) {
16808 boolean printed = false;
16809 for (int i=0; i<mIsolatedProcesses.size(); i++) {
16810 ProcessRecord r = mIsolatedProcesses.valueAt(i);
16811 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16818 pw.println(" Isolated process list (sorted by uid):");
16822 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
16827 if (mActiveInstrumentation.size() > 0) {
16828 boolean printed = false;
16829 for (int i=0; i<mActiveInstrumentation.size(); i++) {
16830 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16831 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16832 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16839 pw.println(" Active instrumentation:");
16843 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
16849 if (mActiveUids.size() > 0) {
16850 if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16855 if (mValidateUids.size() > 0) {
16856 if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16863 if (mLruProcesses.size() > 0) {
16867 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16868 pw.print(" total, non-act at ");
16869 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16870 pw.print(", non-svc at ");
16871 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16873 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
16877 if (dumpAll || dumpPackage != null) {
16878 synchronized (mPidsSelfLocked) {
16879 boolean printed = false;
16880 for (int i=0; i<mPidsSelfLocked.size(); i++) {
16881 ProcessRecord r = mPidsSelfLocked.valueAt(i);
16882 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16886 if (needSep) pw.println();
16888 pw.println(" PID mappings:");
16891 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16892 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16897 if (mImportantProcesses.size() > 0) {
16898 synchronized (mPidsSelfLocked) {
16899 boolean printed = false;
16900 for (int i = 0; i< mImportantProcesses.size(); i++) {
16901 ProcessRecord r = mPidsSelfLocked.get(
16902 mImportantProcesses.valueAt(i).pid);
16903 if (dumpPackage != null && (r == null
16904 || !r.pkgList.containsKey(dumpPackage))) {
16908 if (needSep) pw.println();
16910 pw.println(" Foreground Processes:");
16913 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
16914 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16919 if (mPersistentStartingProcesses.size() > 0) {
16920 if (needSep) pw.println();
16922 pw.println(" Persisent processes that are starting:");
16923 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
16924 "Starting Norm", "Restarting PERS", dumpPackage);
16927 if (mRemovedProcesses.size() > 0) {
16928 if (needSep) pw.println();
16930 pw.println(" Processes that are being removed:");
16931 dumpProcessList(pw, this, mRemovedProcesses, " ",
16932 "Removed Norm", "Removed PERS", dumpPackage);
16935 if (mProcessesOnHold.size() > 0) {
16936 if (needSep) pw.println();
16938 pw.println(" Processes that are on old until the system is ready:");
16939 dumpProcessList(pw, this, mProcessesOnHold, " ",
16940 "OnHold Norm", "OnHold PERS", dumpPackage);
16943 needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16945 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16947 if (dumpPackage == null) {
16950 mUserController.dump(pw, dumpAll);
16952 if (mHomeProcess != null && (dumpPackage == null
16953 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16958 pw.println(" mHomeProcess: " + mHomeProcess);
16960 if (mPreviousProcess != null && (dumpPackage == null
16961 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16966 pw.println(" mPreviousProcess: " + mPreviousProcess);
16968 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16969 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16970 StringBuilder sb = new StringBuilder(128);
16971 sb.append(" mPreviousProcessVisibleTime: ");
16972 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16975 if (mHeavyWeightProcess != null && (dumpPackage == null
16976 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16981 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16983 if (dumpAll && mPendingStarts.size() > 0) {
16984 if (needSep) pw.println();
16986 pw.println(" mPendingStarts: ");
16987 for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16988 pw.println(" " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16991 if (dumpPackage == null) {
16992 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
16993 mStackSupervisor.dumpDisplayConfigs(pw, " ");
16996 if (dumpPackage == null) {
16997 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16999 if (mCompatModePackages.getPackages().size() > 0) {
17000 boolean printed = false;
17001 for (Map.Entry<String, Integer> entry
17002 : mCompatModePackages.getPackages().entrySet()) {
17003 String pkg = entry.getKey();
17004 int mode = entry.getValue();
17005 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
17009 pw.println(" mScreenCompatPackages:");
17012 pw.print(" "); pw.print(pkg); pw.print(": ");
17013 pw.print(mode); pw.println();
17016 final int NI = mUidObservers.getRegisteredCallbackCount();
17017 boolean printed = false;
17018 for (int i=0; i<NI; i++) {
17019 final UidObserverRegistration reg = (UidObserverRegistration)
17020 mUidObservers.getRegisteredCallbackCookie(i);
17021 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17023 pw.println(" mUidObservers:");
17026 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
17027 pw.print(" "); pw.print(reg.pkg); pw.print(":");
17028 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
17031 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
17034 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
17037 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
17038 pw.print(" STATE");
17039 pw.print(" (cut="); pw.print(reg.cutpoint);
17043 if (reg.lastProcStates != null) {
17044 final int NJ = reg.lastProcStates.size();
17045 for (int j=0; j<NJ; j++) {
17046 pw.print(" Last ");
17047 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
17048 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
17053 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
17054 pw.println(" mDeviceIdleExceptIdleWhitelist="
17055 + Arrays.toString(mDeviceIdleExceptIdleWhitelist));
17056 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
17057 if (mPendingTempWhitelist.size() > 0) {
17058 pw.println(" mPendingTempWhitelist:");
17059 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
17060 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
17062 UserHandle.formatUid(pw, ptw.targetUid);
17064 TimeUtils.formatDuration(ptw.duration, pw);
17066 pw.println(ptw.tag);
17070 if (dumpPackage == null) {
17071 pw.println(" mWakefulness="
17072 + PowerManagerInternal.wakefulnessToString(mWakefulness));
17073 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
17074 pw.println(" mSleeping=" + mSleeping);
17075 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
17076 if (mRunningVoice != null) {
17077 pw.println(" mRunningVoice=" + mRunningVoice);
17078 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
17080 pw.println(" mVrController=" + mVrController);
17082 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17083 || mOrigWaitForDebugger) {
17084 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17085 || dumpPackage.equals(mOrigDebugApp)) {
17090 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
17091 + " mDebugTransient=" + mDebugTransient
17092 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
17095 if (mCurAppTimeTracker != null) {
17096 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
17098 if (mMemWatchProcesses.getMap().size() > 0) {
17099 pw.println(" Mem watch processes:");
17100 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
17101 = mMemWatchProcesses.getMap();
17102 for (int i=0; i<procs.size(); i++) {
17103 final String proc = procs.keyAt(i);
17104 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17105 for (int j=0; j<uids.size(); j++) {
17110 StringBuilder sb = new StringBuilder();
17111 sb.append(" ").append(proc).append('/');
17112 UserHandle.formatUid(sb, uids.keyAt(j));
17113 Pair<Long, String> val = uids.valueAt(j);
17114 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
17115 if (val.second != null) {
17116 sb.append(", report to ").append(val.second);
17118 pw.println(sb.toString());
17121 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
17122 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
17123 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
17124 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
17126 if (mTrackAllocationApp != null) {
17127 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17132 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
17135 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17136 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17137 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17142 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
17143 if (mProfilerInfo != null) {
17144 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
17145 mProfilerInfo.profileFd);
17146 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
17147 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
17148 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
17149 pw.println(" mProfileType=" + mProfileType);
17153 if (mNativeDebuggingApp != null) {
17154 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17159 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
17162 if (mAllowAppSwitchUids.size() > 0) {
17163 boolean printed = false;
17164 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
17165 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
17166 for (int j = 0; j < types.size(); j++) {
17167 if (dumpPackage == null ||
17168 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
17174 pw.println(" mAllowAppSwitchUids:");
17177 pw.print(" User ");
17178 pw.print(mAllowAppSwitchUids.keyAt(i));
17179 pw.print(": Type ");
17180 pw.print(types.keyAt(j));
17182 UserHandle.formatUid(pw, types.valueAt(j).intValue());
17188 if (dumpPackage == null) {
17189 if (mAlwaysFinishActivities) {
17190 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
17192 if (mController != null) {
17193 pw.println(" mController=" + mController
17194 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
17197 pw.println(" Total persistent processes: " + numPers);
17198 pw.println(" mProcessesReady=" + mProcessesReady
17199 + " mSystemReady=" + mSystemReady
17200 + " mBooted=" + mBooted
17201 + " mFactoryTest=" + mFactoryTest);
17202 pw.println(" mBooting=" + mBooting
17203 + " mCallFinishBooting=" + mCallFinishBooting
17204 + " mBootAnimationComplete=" + mBootAnimationComplete);
17205 pw.print(" mLastPowerCheckUptime=");
17206 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
17208 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
17209 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
17210 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
17211 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
17212 + " (" + mLruProcesses.size() + " total)"
17213 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
17214 + " mNumServiceProcs=" + mNumServiceProcs
17215 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
17216 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
17217 + " mLastMemoryLevel=" + mLastMemoryLevel
17218 + " mLastNumProcesses=" + mLastNumProcesses);
17219 long now = SystemClock.uptimeMillis();
17220 pw.print(" mLastIdleTime=");
17221 TimeUtils.formatDuration(now, mLastIdleTime, pw);
17222 pw.print(" mLowRamSinceLastIdle=");
17223 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
17226 pw.print(" mUidChangeDispatchCount=");
17227 pw.print(mUidChangeDispatchCount);
17230 pw.println(" Slow UID dispatches:");
17231 final int N = mUidObservers.beginBroadcast();
17232 for (int i = 0; i < N; i++) {
17233 UidObserverRegistration r =
17234 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
17236 pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
17238 pw.print(r.mSlowDispatchCount);
17239 pw.print(" / Max ");
17240 pw.print(r.mMaxDispatchTime);
17243 mUidObservers.finishBroadcast();
17246 pw.println(" ServiceManager statistics:");
17247 ServiceManager.sStatLogger.dump(pw, " ");
17251 pw.println(" mForceBackgroundCheck=" + mForceBackgroundCheck);
17255 void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
17258 final int NP = mProcessNames.getMap().size();
17259 for (int ip=0; ip<NP; ip++) {
17260 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
17261 final int NA = procs.size();
17262 for (int ia = 0; ia<NA; ia++) {
17263 ProcessRecord r = procs.valueAt(ia);
17264 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17267 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
17268 if (r.persistent) {
17274 for (int i=0; i<mIsolatedProcesses.size(); i++) {
17275 ProcessRecord r = mIsolatedProcesses.valueAt(i);
17276 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17279 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
17282 for (int i=0; i<mActiveInstrumentation.size(); i++) {
17283 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
17284 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
17285 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
17288 ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
17291 int whichAppId = getAppId(dumpPackage);
17292 for (int i=0; i<mActiveUids.size(); i++) {
17293 UidRecord uidRec = mActiveUids.valueAt(i);
17294 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17297 uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
17300 for (int i=0; i<mValidateUids.size(); i++) {
17301 UidRecord uidRec = mValidateUids.valueAt(i);
17302 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17305 uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
17308 if (mLruProcesses.size() > 0) {
17309 long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
17310 int total = mLruProcesses.size();
17311 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
17312 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
17313 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
17314 writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
17315 mLruProcesses,false, dumpPackage);
17316 proto.end(lruToken);
17319 if (dumpPackage != null) {
17320 synchronized (mPidsSelfLocked) {
17321 for (int i=0; i<mPidsSelfLocked.size(); i++) {
17322 ProcessRecord r = mPidsSelfLocked.valueAt(i);
17323 if (!r.pkgList.containsKey(dumpPackage)) {
17326 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
17331 if (mImportantProcesses.size() > 0) {
17332 synchronized (mPidsSelfLocked) {
17333 for (int i=0; i<mImportantProcesses.size(); i++) {
17334 ImportanceToken it = mImportantProcesses.valueAt(i);
17335 ProcessRecord r = mPidsSelfLocked.get(it.pid);
17336 if (dumpPackage != null && (r == null
17337 || !r.pkgList.containsKey(dumpPackage))) {
17340 it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
17345 for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
17346 ProcessRecord r = mPersistentStartingProcesses.get(i);
17347 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17350 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
17353 for (int i=0; i<mRemovedProcesses.size(); i++) {
17354 ProcessRecord r = mRemovedProcesses.get(i);
17355 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17358 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
17361 for (int i=0; i<mProcessesOnHold.size(); i++) {
17362 ProcessRecord r = mProcessesOnHold.get(i);
17363 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17366 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
17369 writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
17370 mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
17372 if (dumpPackage == null) {
17373 mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
17374 getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
17375 proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
17378 if (mHomeProcess != null && (dumpPackage == null
17379 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
17380 mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
17383 if (mPreviousProcess != null && (dumpPackage == null
17384 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17385 mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
17386 proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
17389 if (mHeavyWeightProcess != null && (dumpPackage == null
17390 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17391 mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
17394 for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
17395 String pkg = entry.getKey();
17396 int mode = entry.getValue();
17397 if (dumpPackage == null || dumpPackage.equals(pkg)) {
17398 long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
17399 proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
17400 proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
17401 proto.end(compatToken);
17405 final int NI = mUidObservers.getRegisteredCallbackCount();
17406 for (int i=0; i<NI; i++) {
17407 final UidObserverRegistration reg = (UidObserverRegistration)
17408 mUidObservers.getRegisteredCallbackCookie(i);
17409 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17410 reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
17414 for (int v : mDeviceIdleWhitelist) {
17415 proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
17418 for (int v : mDeviceIdleTempWhitelist) {
17419 proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
17422 if (mPendingTempWhitelist.size() > 0) {
17423 for (int i=0; i < mPendingTempWhitelist.size(); i++) {
17424 mPendingTempWhitelist.valueAt(i).writeToProto(proto,
17425 ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
17429 if (dumpPackage == null) {
17430 final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
17431 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
17432 PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
17433 for (SleepToken st : mStackSupervisor.mSleepTokens) {
17434 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
17436 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
17437 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
17438 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
17439 proto.end(sleepToken);
17441 if (mRunningVoice != null) {
17442 final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
17443 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION, mRunningVoice.toString());
17444 mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
17445 proto.end(vrToken);
17448 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
17451 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17452 || mOrigWaitForDebugger) {
17453 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17454 || dumpPackage.equals(mOrigDebugApp)) {
17455 final long debugAppToken = proto.start(ActivityManagerServiceDumpProcessesProto.DEBUG);
17456 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
17457 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
17458 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
17459 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
17460 proto.end(debugAppToken);
17464 if (mCurAppTimeTracker != null) {
17465 mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
17468 if (mMemWatchProcesses.getMap().size() > 0) {
17469 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
17470 ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
17471 for (int i=0; i<procs.size(); i++) {
17472 final String proc = procs.keyAt(i);
17473 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17474 final long ptoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS);
17475 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, proc);
17476 for (int j=0; j<uids.size(); j++) {
17477 final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MEM_STATS);
17478 Pair<Long, String> val = uids.valueAt(j);
17479 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
17480 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
17481 DebugUtils.sizeValueToString(val.first, new StringBuilder()));
17482 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
17488 final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
17489 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
17490 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
17491 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
17492 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
17498 if (mTrackAllocationApp != null) {
17499 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17500 proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
17504 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17505 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17506 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17507 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
17508 proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, mProfileApp);
17509 mProfileProc.writeToProto(proto,ActivityManagerServiceDumpProcessesProto.Profile.PROC);
17510 if (mProfilerInfo != null) {
17511 mProfilerInfo.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Profile.INFO);
17512 proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, mProfileType);
17518 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17519 proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
17522 if (dumpPackage == null) {
17523 proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
17524 if (mController != null) {
17525 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
17526 proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
17527 proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
17530 proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
17531 proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
17532 proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
17533 proto.write(ActivityManagerServiceDumpProcessesProto.BOOTED, mBooted);
17534 proto.write(ActivityManagerServiceDumpProcessesProto.FACTORY_TEST, mFactoryTest);
17535 proto.write(ActivityManagerServiceDumpProcessesProto.BOOTING, mBooting);
17536 proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
17537 proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
17538 proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
17539 mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
17540 mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
17541 proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
17542 proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
17543 proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
17544 proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
17545 proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
17546 proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
17547 proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
17548 proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
17549 long now = SystemClock.uptimeMillis();
17550 ProtoUtils.toDuration(proto, ActivityManagerServiceDumpProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
17551 proto.write(ActivityManagerServiceDumpProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
17556 void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
17557 if (mProcessesToGc.size() > 0) {
17558 long now = SystemClock.uptimeMillis();
17559 for (int i=0; i<mProcessesToGc.size(); i++) {
17560 ProcessRecord r = mProcessesToGc.get(i);
17561 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17564 final long token = proto.start(fieldId);
17565 r.writeToProto(proto, ProcessToGcProto.PROC);
17566 proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
17567 proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
17568 proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
17569 proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
17575 boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
17576 if (mProcessesToGc.size() > 0) {
17577 boolean printed = false;
17578 long now = SystemClock.uptimeMillis();
17579 for (int i=0; i<mProcessesToGc.size(); i++) {
17580 ProcessRecord proc = mProcessesToGc.get(i);
17581 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
17585 if (needSep) pw.println();
17587 pw.println(" Processes that are waiting to GC:");
17590 pw.print(" Process "); pw.println(proc);
17591 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
17592 pw.print(", last gced=");
17593 pw.print(now-proc.lastRequestedGc);
17594 pw.print(" ms ago, last lowMem=");
17595 pw.print(now-proc.lastLowMemory);
17596 pw.println(" ms ago");
17603 void printOomLevel(PrintWriter pw, String name, int adj) {
17607 if (adj < 10) pw.print(' ');
17609 if (adj > -10) pw.print(' ');
17615 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
17619 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17620 int opti, boolean dumpAll) {
17621 boolean needSep = false;
17623 if (mLruProcesses.size() > 0) {
17624 if (needSep) pw.println();
17626 pw.println(" OOM levels:");
17627 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
17628 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
17629 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
17630 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
17631 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
17632 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
17633 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
17634 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
17635 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
17636 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
17637 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
17638 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
17639 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
17640 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
17642 if (needSep) pw.println();
17643 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
17644 pw.print(" total, non-act at ");
17645 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
17646 pw.print(", non-svc at ");
17647 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
17649 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
17653 dumpProcessesToGc(pw, needSep, null);
17656 pw.println(" mHomeProcess: " + mHomeProcess);
17657 pw.println(" mPreviousProcess: " + mPreviousProcess);
17658 if (mHeavyWeightProcess != null) {
17659 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
17666 * There are three ways to call this:
17667 * - no provider specified: dump all the providers
17668 * - a flattened component name that matched an existing provider was specified as the
17669 * first arg: dump that one provider
17670 * - the first arg isn't the flattened component name of an existing provider:
17671 * dump all providers whose component contains the first arg as a substring
17673 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17674 int opti, boolean dumpAll) {
17675 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
17679 * Similar to the dumpProvider, but only dumps the first matching provider.
17680 * The provider is responsible for dumping as proto.
17682 protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17684 return mProviderMap.dumpProviderProto(fd, pw, name, args);
17687 static class ItemMatcher {
17688 ArrayList<ComponentName> components;
17689 ArrayList<String> strings;
17690 ArrayList<Integer> objects;
17697 void build(String name) {
17698 ComponentName componentName = ComponentName.unflattenFromString(name);
17699 if (componentName != null) {
17700 if (components == null) {
17701 components = new ArrayList<ComponentName>();
17703 components.add(componentName);
17707 // Not a '/' separated full component name; maybe an object ID?
17709 objectId = Integer.parseInt(name, 16);
17710 if (objects == null) {
17711 objects = new ArrayList<Integer>();
17713 objects.add(objectId);
17715 } catch (RuntimeException e) {
17716 // Not an integer; just do string match.
17717 if (strings == null) {
17718 strings = new ArrayList<String>();
17726 int build(String[] args, int opti) {
17727 for (; opti<args.length; opti++) {
17728 String name = args[opti];
17729 if ("--".equals(name)) {
17737 boolean match(Object object, ComponentName comp) {
17741 if (components != null) {
17742 for (int i=0; i<components.size(); i++) {
17743 if (components.get(i).equals(comp)) {
17748 if (objects != null) {
17749 for (int i=0; i<objects.size(); i++) {
17750 if (System.identityHashCode(object) == objects.get(i)) {
17755 if (strings != null) {
17756 String flat = comp.flattenToString();
17757 for (int i=0; i<strings.size(); i++) {
17758 if (flat.contains(strings.get(i))) {
17768 * There are three things that cmd can be:
17769 * - a flattened component name that matches an existing activity
17770 * - the cmd arg isn't the flattened component name of an existing activity:
17771 * dump all activity whose component contains the cmd as a substring
17772 * - A hex number of the ActivityRecord object instance.
17774 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17775 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17777 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17778 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17779 ArrayList<ActivityRecord> activities;
17781 synchronized (this) {
17782 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17783 dumpFocusedStackOnly);
17786 if (activities.size() <= 0) {
17790 String[] newArgs = new String[args.length - opti];
17791 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17793 TaskRecord lastTask = null;
17794 boolean needSep = false;
17795 for (int i=activities.size()-1; i>=0; i--) {
17796 ActivityRecord r = activities.get(i);
17801 synchronized (this) {
17802 final TaskRecord task = r.getTask();
17803 if (lastTask != task) {
17805 pw.print("TASK "); pw.print(lastTask.affinity);
17806 pw.print(" id="); pw.print(lastTask.taskId);
17807 pw.print(" userId="); pw.println(lastTask.userId);
17809 lastTask.dump(pw, " ");
17813 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
17819 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17820 * there is a thread associated with the activity.
17822 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17823 final ActivityRecord r, String[] args, boolean dumpAll) {
17824 String innerPrefix = prefix + " ";
17825 synchronized (this) {
17826 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17827 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17829 if (r.app != null) pw.println(r.app.pid);
17830 else pw.println("(not running)");
17832 r.dump(pw, innerPrefix);
17835 if (r.app != null && r.app.thread != null) {
17836 // flush anything that is already in the PrintWriter since the thread is going
17837 // to write to the file descriptor directly
17840 TransferPipe tp = new TransferPipe();
17842 r.app.thread.dumpActivity(tp.getWriteFd(),
17843 r.appToken, innerPrefix, args);
17848 } catch (IOException e) {
17849 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17850 } catch (RemoteException e) {
17851 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17856 void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17857 if (mRegisteredReceivers.size() > 0) {
17858 Iterator it = mRegisteredReceivers.values().iterator();
17859 while (it.hasNext()) {
17860 ReceiverList r = (ReceiverList)it.next();
17861 r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
17864 mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
17865 for (BroadcastQueue q : mBroadcastQueues) {
17866 q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
17868 for (int user=0; user<mStickyBroadcasts.size(); user++) {
17869 long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
17870 proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17871 for (Map.Entry<String, ArrayList<Intent>> ent
17872 : mStickyBroadcasts.valueAt(user).entrySet()) {
17873 long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17874 proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17875 for (Intent intent : ent.getValue()) {
17876 intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17877 false, true, true, false);
17879 proto.end(actionToken);
17884 long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
17885 proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
17886 mHandler.getLooper().writeToProto(proto,
17887 ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
17888 proto.end(handlerToken);
17891 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17892 int opti, boolean dumpAll, String dumpPackage) {
17893 boolean needSep = false;
17894 boolean onlyHistory = false;
17895 boolean printedAnything = false;
17897 if ("history".equals(dumpPackage)) {
17898 if (opti < args.length && "-s".equals(args[opti])) {
17901 onlyHistory = true;
17902 dumpPackage = null;
17905 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17906 if (!onlyHistory && dumpAll) {
17907 if (mRegisteredReceivers.size() > 0) {
17908 boolean printed = false;
17909 Iterator it = mRegisteredReceivers.values().iterator();
17910 while (it.hasNext()) {
17911 ReceiverList r = (ReceiverList)it.next();
17912 if (dumpPackage != null && (r.app == null ||
17913 !dumpPackage.equals(r.app.info.packageName))) {
17917 pw.println(" Registered Receivers:");
17920 printedAnything = true;
17922 pw.print(" * "); pw.println(r);
17927 if (mReceiverResolver.dump(pw, needSep ?
17928 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
17929 " ", dumpPackage, false, false)) {
17931 printedAnything = true;
17935 for (BroadcastQueue q : mBroadcastQueues) {
17936 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17937 printedAnything |= needSep;
17942 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17943 for (int user=0; user<mStickyBroadcasts.size(); user++) {
17948 printedAnything = true;
17949 pw.print(" Sticky broadcasts for user ");
17950 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17951 StringBuilder sb = new StringBuilder(128);
17952 for (Map.Entry<String, ArrayList<Intent>> ent
17953 : mStickyBroadcasts.valueAt(user).entrySet()) {
17954 pw.print(" * Sticky action "); pw.print(ent.getKey());
17957 ArrayList<Intent> intents = ent.getValue();
17958 final int N = intents.size();
17959 for (int i=0; i<N; i++) {
17961 sb.append(" Intent: ");
17962 intents.get(i).toShortString(sb, false, true, false, false);
17963 pw.println(sb.toString());
17964 Bundle bundle = intents.get(i).getExtras();
17965 if (bundle != null) {
17967 pw.println(bundle.toString());
17977 if (!onlyHistory && dumpAll) {
17979 for (BroadcastQueue queue : mBroadcastQueues) {
17980 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
17981 + queue.mBroadcastsScheduled);
17983 pw.println(" mHandler:");
17984 mHandler.dump(new PrintWriterPrinter(pw), " ");
17986 printedAnything = true;
17989 if (!printedAnything) {
17990 pw.println(" (nothing)");
17994 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17995 int opti, boolean dumpAll, String dumpPackage) {
17996 if (mCurBroadcastStats == null) {
18000 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
18001 final long now = SystemClock.elapsedRealtime();
18002 if (mLastBroadcastStats != null) {
18003 pw.print(" Last stats (from ");
18004 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
18006 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
18008 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
18009 - mLastBroadcastStats.mStartUptime, pw);
18010 pw.println(" uptime):");
18011 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
18012 pw.println(" (nothing)");
18016 pw.print(" Current stats (from ");
18017 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
18018 pw.print(" to now, ");
18019 TimeUtils.formatDuration(SystemClock.uptimeMillis()
18020 - mCurBroadcastStats.mStartUptime, pw);
18021 pw.println(" uptime):");
18022 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
18023 pw.println(" (nothing)");
18027 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18028 int opti, boolean fullCheckin, String dumpPackage) {
18029 if (mCurBroadcastStats == null) {
18033 if (mLastBroadcastStats != null) {
18034 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
18036 mLastBroadcastStats = null;
18040 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
18042 mCurBroadcastStats = null;
18046 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18047 int opti, boolean dumpAll, String dumpPackage) {
18049 boolean printedAnything = false;
18051 ItemMatcher matcher = new ItemMatcher();
18052 matcher.build(args, opti);
18054 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
18056 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
18057 printedAnything |= needSep;
18059 if (mLaunchingProviders.size() > 0) {
18060 boolean printed = false;
18061 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
18062 ContentProviderRecord r = mLaunchingProviders.get(i);
18063 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
18067 if (needSep) pw.println();
18069 pw.println(" Launching content providers:");
18071 printedAnything = true;
18073 pw.print(" Launching #"); pw.print(i); pw.print(": ");
18078 if (!printedAnything) {
18079 pw.println(" (nothing)");
18084 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18085 int opti, boolean dumpAll, String dumpPackage) {
18086 boolean needSep = false;
18087 boolean printedAnything = false;
18089 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
18091 if (mGrantedUriPermissions.size() > 0) {
18092 boolean printed = false;
18094 if (dumpPackage != null) {
18096 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
18097 MATCH_ANY_USER, 0);
18098 } catch (NameNotFoundException e) {
18102 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
18103 int uid = mGrantedUriPermissions.keyAt(i);
18104 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
18107 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
18109 if (needSep) pw.println();
18111 pw.println(" Granted Uri Permissions:");
18113 printedAnything = true;
18115 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
18116 for (UriPermission perm : perms.values()) {
18117 pw.print(" "); pw.println(perm);
18119 perm.dump(pw, " ");
18125 if (!printedAnything) {
18126 pw.println(" (nothing)");
18130 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18131 int opti, boolean dumpAll, String dumpPackage) {
18132 boolean printed = false;
18134 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
18136 if (mIntentSenderRecords.size() > 0) {
18137 // Organize these by package name, so they are easier to read.
18138 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
18139 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
18140 final Iterator<WeakReference<PendingIntentRecord>> it
18141 = mIntentSenderRecords.values().iterator();
18142 while (it.hasNext()) {
18143 WeakReference<PendingIntentRecord> ref = it.next();
18144 PendingIntentRecord rec = ref != null ? ref.get() : null;
18149 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
18152 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
18153 if (list == null) {
18154 list = new ArrayList<>();
18155 byPackage.put(rec.key.packageName, list);
18159 for (int i = 0; i < byPackage.size(); i++) {
18160 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
18162 pw.print(" * "); pw.print(byPackage.keyAt(i));
18163 pw.print(": "); pw.print(intents.size()); pw.println(" items");
18164 for (int j = 0; j < intents.size(); j++) {
18165 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
18167 intents.get(j).dump(pw, " ");
18171 if (weakRefs.size() > 0) {
18173 pw.println(" * WEAK REFS:");
18174 for (int i = 0; i < weakRefs.size(); i++) {
18175 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
18181 pw.println(" (nothing)");
18185 private static final int dumpProcessList(PrintWriter pw,
18186 ActivityManagerService service, List list,
18187 String prefix, String normalLabel, String persistentLabel,
18188 String dumpPackage) {
18190 final int N = list.size()-1;
18191 for (int i=N; i>=0; i--) {
18192 ProcessRecord r = (ProcessRecord)list.get(i);
18193 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
18196 pw.println(String.format("%s%s #%2d: %s",
18197 prefix, (r.persistent ? persistentLabel : normalLabel),
18199 if (r.persistent) {
18206 private static final ArrayList<Pair<ProcessRecord, Integer>>
18207 sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
18208 ArrayList<Pair<ProcessRecord, Integer>> list
18209 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
18210 for (int i=0; i<origList.size(); i++) {
18211 ProcessRecord r = origList.get(i);
18212 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
18215 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
18218 Comparator<Pair<ProcessRecord, Integer>> comparator
18219 = new Comparator<Pair<ProcessRecord, Integer>>() {
18221 public int compare(Pair<ProcessRecord, Integer> object1,
18222 Pair<ProcessRecord, Integer> object2) {
18223 if (object1.first.setAdj != object2.first.setAdj) {
18224 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
18226 if (object1.first.setProcState != object2.first.setProcState) {
18227 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
18229 if (object1.second.intValue() != object2.second.intValue()) {
18230 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
18236 Collections.sort(list, comparator);
18240 private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
18241 ActivityManagerService service, List<ProcessRecord> origList,
18242 boolean inclDetails, String dumpPackage) {
18243 ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18244 if (list.isEmpty()) return false;
18246 final long curUptime = SystemClock.uptimeMillis();
18248 for (int i = list.size() - 1; i >= 0; i--) {
18249 ProcessRecord r = list.get(i).first;
18250 long token = proto.start(fieldId);
18251 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18252 proto.write(ProcessOomProto.PERSISTENT, r.persistent);
18253 proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
18254 proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
18255 int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
18256 switch (r.setSchedGroup) {
18257 case ProcessList.SCHED_GROUP_BACKGROUND:
18258 schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
18260 case ProcessList.SCHED_GROUP_DEFAULT:
18261 schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
18263 case ProcessList.SCHED_GROUP_TOP_APP:
18264 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
18266 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
18267 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
18270 if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
18271 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
18273 if (r.foregroundActivities) {
18274 proto.write(ProcessOomProto.ACTIVITIES, true);
18275 } else if (r.foregroundServices) {
18276 proto.write(ProcessOomProto.SERVICES, true);
18278 proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
18279 proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
18280 r.writeToProto(proto, ProcessOomProto.PROC);
18281 proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
18282 if (r.adjSource != null || r.adjTarget != null) {
18283 if (r.adjTarget instanceof ComponentName) {
18284 ComponentName cn = (ComponentName) r.adjTarget;
18285 cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
18286 } else if (r.adjTarget != null) {
18287 proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
18289 if (r.adjSource instanceof ProcessRecord) {
18290 ProcessRecord p = (ProcessRecord) r.adjSource;
18291 p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
18292 } else if (r.adjSource != null) {
18293 proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
18297 long detailToken = proto.start(ProcessOomProto.DETAIL);
18298 proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
18299 proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
18300 proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
18301 proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
18302 proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
18303 proto.write(ProcessOomProto.Detail.CURRENT_STATE,
18304 ProcessList.makeProcStateProtoEnum(r.curProcState));
18305 proto.write(ProcessOomProto.Detail.SET_STATE,
18306 ProcessList.makeProcStateProtoEnum(r.setProcState));
18307 proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
18308 r.lastPss*1024, new StringBuilder()));
18309 proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
18310 r.lastSwapPss*1024, new StringBuilder()));
18311 proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
18312 r.lastCachedPss*1024, new StringBuilder()));
18313 proto.write(ProcessOomProto.Detail.CACHED, r.cached);
18314 proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
18315 proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
18317 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18318 if (r.lastCpuTime != 0) {
18319 long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18320 long timeUsed = r.curCpuTime - r.lastCpuTime;
18321 long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
18322 proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
18323 proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
18324 proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
18325 (100.0*timeUsed)/uptimeSince);
18326 proto.end(cpuTimeToken);
18329 proto.end(detailToken);
18337 private static final boolean dumpProcessOomList(PrintWriter pw,
18338 ActivityManagerService service, List<ProcessRecord> origList,
18339 String prefix, String normalLabel, String persistentLabel,
18340 boolean inclDetails, String dumpPackage) {
18342 ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18343 if (list.isEmpty()) return false;
18345 final long curUptime = SystemClock.uptimeMillis();
18346 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18348 for (int i=list.size()-1; i>=0; i--) {
18349 ProcessRecord r = list.get(i).first;
18350 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18352 switch (r.setSchedGroup) {
18353 case ProcessList.SCHED_GROUP_BACKGROUND:
18356 case ProcessList.SCHED_GROUP_DEFAULT:
18359 case ProcessList.SCHED_GROUP_TOP_APP:
18362 case ProcessList.SCHED_GROUP_RESTRICTED:
18370 if (r.foregroundActivities) {
18372 } else if (r.foregroundServices) {
18377 String procState = ProcessList.makeProcStateString(r.curProcState);
18379 pw.print(r.persistent ? persistentLabel : normalLabel);
18381 int num = (origList.size()-1)-list.get(i).second;
18382 if (num < 10) pw.print(' ');
18387 pw.print(schedGroup);
18389 pw.print(foreground);
18391 pw.print(procState);
18393 if (r.trimMemoryLevel < 10) pw.print(' ');
18394 pw.print(r.trimMemoryLevel);
18396 pw.print(r.toShortString());
18398 pw.print(r.adjType);
18400 if (r.adjSource != null || r.adjTarget != null) {
18403 if (r.adjTarget instanceof ComponentName) {
18404 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
18405 } else if (r.adjTarget != null) {
18406 pw.print(r.adjTarget.toString());
18408 pw.print("{null}");
18411 if (r.adjSource instanceof ProcessRecord) {
18413 pw.print(((ProcessRecord)r.adjSource).toShortString());
18415 } else if (r.adjSource != null) {
18416 pw.println(r.adjSource.toString());
18418 pw.println("{null}");
18424 pw.print("oom: max="); pw.print(r.maxAdj);
18425 pw.print(" curRaw="); pw.print(r.curRawAdj);
18426 pw.print(" setRaw="); pw.print(r.setRawAdj);
18427 pw.print(" cur="); pw.print(r.curAdj);
18428 pw.print(" set="); pw.println(r.setAdj);
18431 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
18432 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
18433 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
18434 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
18435 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
18439 pw.print("cached="); pw.print(r.cached);
18440 pw.print(" empty="); pw.print(r.empty);
18441 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
18443 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18444 if (r.lastCpuTime != 0) {
18445 long timeUsed = r.curCpuTime - r.lastCpuTime;
18448 pw.print("run cpu over ");
18449 TimeUtils.formatDuration(uptimeSince, pw);
18450 pw.print(" used ");
18451 TimeUtils.formatDuration(timeUsed, pw);
18453 pw.print((timeUsed*100)/uptimeSince);
18462 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
18464 ArrayList<ProcessRecord> procs;
18465 synchronized (this) {
18466 if (args != null && args.length > start
18467 && args[start].charAt(0) != '-') {
18468 procs = new ArrayList<ProcessRecord>();
18471 pid = Integer.parseInt(args[start]);
18472 } catch (NumberFormatException e) {
18474 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18475 ProcessRecord proc = mLruProcesses.get(i);
18476 if (proc.pid > 0 && proc.pid == pid) {
18478 } else if (allPkgs && proc.pkgList != null
18479 && proc.pkgList.containsKey(args[start])) {
18481 } else if (proc.processName.equals(args[start])) {
18485 if (procs.size() <= 0) {
18489 procs = new ArrayList<ProcessRecord>(mLruProcesses);
18495 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
18496 PrintWriter pw, String[] args) {
18497 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18498 if (procs == null) {
18499 pw.println("No process found for: " + args[0]);
18503 long uptime = SystemClock.uptimeMillis();
18504 long realtime = SystemClock.elapsedRealtime();
18505 pw.println("Applications Graphics Acceleration Info:");
18506 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18508 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18509 ProcessRecord r = procs.get(i);
18510 if (r.thread != null) {
18511 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
18514 TransferPipe tp = new TransferPipe();
18516 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
18521 } catch (IOException e) {
18522 pw.println("Failure while dumping the app: " + r);
18524 } catch (RemoteException e) {
18525 pw.println("Got a RemoteException while dumping the app " + r);
18532 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
18533 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18534 if (procs == null) {
18535 pw.println("No process found for: " + args[0]);
18539 pw.println("Applications Database Info:");
18541 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18542 ProcessRecord r = procs.get(i);
18543 if (r.thread != null) {
18544 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
18547 TransferPipe tp = new TransferPipe();
18549 r.thread.dumpDbInfo(tp.getWriteFd(), args);
18554 } catch (IOException e) {
18555 pw.println("Failure while dumping the app: " + r);
18557 } catch (RemoteException e) {
18558 pw.println("Got a RemoteException while dumping the app " + r);
18565 final static class MemItem {
18566 final boolean isProc;
18567 final String label;
18568 final String shortLabel;
18570 final long swapPss;
18572 final boolean hasActivities;
18573 ArrayList<MemItem> subitems;
18575 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
18576 boolean _hasActivities) {
18579 shortLabel = _shortLabel;
18581 swapPss = _swapPss;
18583 hasActivities = _hasActivities;
18586 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
18589 shortLabel = _shortLabel;
18591 swapPss = _swapPss;
18593 hasActivities = false;
18597 private static void sortMemItems(List<MemItem> items) {
18598 Collections.sort(items, new Comparator<MemItem>() {
18600 public int compare(MemItem lhs, MemItem rhs) {
18601 if (lhs.pss < rhs.pss) {
18603 } else if (lhs.pss > rhs.pss) {
18611 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
18612 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
18613 if (sort && !isCompact) {
18614 sortMemItems(items);
18617 for (int i=0; i<items.size(); i++) {
18618 MemItem mi = items.get(i);
18621 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
18622 mi.label, stringifyKBSize(mi.swapPss));
18624 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
18626 } else if (mi.isProc) {
18627 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
18628 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
18629 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
18630 pw.println(mi.hasActivities ? ",a" : ",e");
18632 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
18633 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
18635 if (mi.subitems != null) {
18636 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
18637 true, isCompact, dumpSwapPss);
18642 static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18643 ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18645 sortMemItems(items);
18648 for (int i=0; i<items.size(); i++) {
18649 MemItem mi = items.get(i);
18650 final long token = proto.start(fieldId);
18652 proto.write(MemInfoDumpProto.MemItem.TAG, tag);
18653 proto.write(MemInfoDumpProto.MemItem.LABEL, mi.shortLabel);
18654 proto.write(MemInfoDumpProto.MemItem.IS_PROC, mi.isProc);
18655 proto.write(MemInfoDumpProto.MemItem.ID, mi.id);
18656 proto.write(MemInfoDumpProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
18657 proto.write(MemInfoDumpProto.MemItem.PSS_KB, mi.pss);
18659 proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18661 if (mi.subitems != null) {
18662 dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18663 true, dumpSwapPss);
18669 // These are in KB.
18670 static final long[] DUMP_MEM_BUCKETS = new long[] {
18671 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
18672 120*1024, 160*1024, 200*1024,
18673 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
18674 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
18677 static final void appendMemBucket(StringBuilder out, long memKB, String label,
18678 boolean stackLike) {
18679 int start = label.lastIndexOf('.');
18680 if (start >= 0) start++;
18682 int end = label.length();
18683 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18684 if (DUMP_MEM_BUCKETS[i] >= memKB) {
18685 long bucket = DUMP_MEM_BUCKETS[i]/1024;
18686 out.append(bucket);
18687 out.append(stackLike ? "MB." : "MB ");
18688 out.append(label, start, end);
18692 out.append(memKB/1024);
18693 out.append(stackLike ? "MB." : "MB ");
18694 out.append(label, start, end);
18697 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18698 ProcessList.NATIVE_ADJ,
18699 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18700 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18701 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18702 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18703 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18704 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18706 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18708 "System", "Persistent", "Persistent Service", "Foreground",
18709 "Visible", "Perceptible",
18710 "Heavy Weight", "Backup",
18711 "A Services", "Home",
18712 "Previous", "B Services", "Cached"
18714 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18716 "sys", "pers", "persvc", "fore",
18719 "servicea", "home",
18720 "prev", "serviceb", "cached"
18723 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18724 long realtime, boolean isCheckinRequest, boolean isCompact) {
18726 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18728 if (isCheckinRequest || isCompact) {
18729 // short checkin version
18730 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18732 pw.println("Applications Memory Usage (in Kilobytes):");
18733 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18737 private static final int KSM_SHARED = 0;
18738 private static final int KSM_SHARING = 1;
18739 private static final int KSM_UNSHARED = 2;
18740 private static final int KSM_VOLATILE = 3;
18742 private final long[] getKsmInfo() {
18743 long[] longOut = new long[4];
18744 final int[] SINGLE_LONG_FORMAT = new int[] {
18745 PROC_SPACE_TERM| PROC_OUT_LONG
18747 long[] longTmp = new long[1];
18748 readProcFile("/sys/kernel/mm/ksm/pages_shared",
18749 SINGLE_LONG_FORMAT, null, longTmp, null);
18750 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18752 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18753 SINGLE_LONG_FORMAT, null, longTmp, null);
18754 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18756 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18757 SINGLE_LONG_FORMAT, null, longTmp, null);
18758 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18760 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18761 SINGLE_LONG_FORMAT, null, longTmp, null);
18762 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18766 private static String stringifySize(long size, int order) {
18767 Locale locale = Locale.US;
18770 return String.format(locale, "%,13d", size);
18772 return String.format(locale, "%,9dK", size / 1024);
18774 return String.format(locale, "%,5dM", size / 1024 / 1024);
18775 case 1024 * 1024 * 1024:
18776 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18778 throw new IllegalArgumentException("Invalid size order");
18782 private static String stringifyKBSize(long size) {
18783 return stringifySize(size * 1024, 1024);
18786 // Update this version number if you change the 'compact' format.
18787 private static final int MEMINFO_COMPACT_VERSION = 1;
18789 private static class MemoryUsageDumpOptions {
18790 boolean dumpDetails;
18791 boolean dumpFullDetails;
18792 boolean dumpDalvik;
18793 boolean dumpSummaryOnly;
18794 boolean dumpUnreachable;
18799 boolean isCheckinRequest;
18800 boolean dumpSwapPss;
18804 final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18805 String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18806 MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18807 opts.dumpDetails = false;
18808 opts.dumpFullDetails = false;
18809 opts.dumpDalvik = false;
18810 opts.dumpSummaryOnly = false;
18811 opts.dumpUnreachable = false;
18812 opts.oomOnly = false;
18813 opts.isCompact = false;
18814 opts.localOnly = false;
18815 opts.packages = false;
18816 opts.isCheckinRequest = false;
18817 opts.dumpSwapPss = false;
18818 opts.dumpProto = asProto;
18821 while (opti < args.length) {
18822 String opt = args[opti];
18823 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18827 if ("-a".equals(opt)) {
18828 opts.dumpDetails = true;
18829 opts.dumpFullDetails = true;
18830 opts.dumpDalvik = true;
18831 opts.dumpSwapPss = true;
18832 } else if ("-d".equals(opt)) {
18833 opts.dumpDalvik = true;
18834 } else if ("-c".equals(opt)) {
18835 opts.isCompact = true;
18836 } else if ("-s".equals(opt)) {
18837 opts.dumpDetails = true;
18838 opts.dumpSummaryOnly = true;
18839 } else if ("-S".equals(opt)) {
18840 opts.dumpSwapPss = true;
18841 } else if ("--unreachable".equals(opt)) {
18842 opts.dumpUnreachable = true;
18843 } else if ("--oom".equals(opt)) {
18844 opts.oomOnly = true;
18845 } else if ("--local".equals(opt)) {
18846 opts.localOnly = true;
18847 } else if ("--package".equals(opt)) {
18848 opts.packages = true;
18849 } else if ("--checkin".equals(opt)) {
18850 opts.isCheckinRequest = true;
18851 } else if ("--proto".equals(opt)) {
18852 opts.dumpProto = true;
18854 } else if ("-h".equals(opt)) {
18855 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18856 pw.println(" -a: include all available information for each process.");
18857 pw.println(" -d: include dalvik details.");
18858 pw.println(" -c: dump in a compact machine-parseable representation.");
18859 pw.println(" -s: dump only summary of application memory usage.");
18860 pw.println(" -S: dump also SwapPss.");
18861 pw.println(" --oom: only show processes organized by oom adj.");
18862 pw.println(" --local: only collect details locally, don't call process.");
18863 pw.println(" --package: interpret process arg as package, dumping all");
18864 pw.println(" processes that have loaded that package.");
18865 pw.println(" --checkin: dump data for a checkin");
18866 pw.println(" --proto: dump data to proto");
18867 pw.println("If [process] is specified it can be the name or ");
18868 pw.println("pid of a specific process to dump.");
18871 pw.println("Unknown argument: " + opt + "; use -h for help");
18875 String[] innerArgs = new String[args.length-opti];
18876 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18878 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18879 if (opts.dumpProto) {
18880 dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18882 dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18886 private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18887 MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18888 ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18889 long uptime = SystemClock.uptimeMillis();
18890 long realtime = SystemClock.elapsedRealtime();
18891 final long[] tmpLong = new long[1];
18893 if (procs == null) {
18894 // No Java processes. Maybe they want to print a native process.
18895 String proc = "N/A";
18896 if (innerArgs.length > 0) {
18897 proc = innerArgs[0];
18898 if (proc.charAt(0) != '-') {
18899 ArrayList<ProcessCpuTracker.Stats> nativeProcs
18900 = new ArrayList<ProcessCpuTracker.Stats>();
18901 updateCpuStatsNow();
18904 findPid = Integer.parseInt(innerArgs[0]);
18905 } catch (NumberFormatException e) {
18907 synchronized (mProcessCpuTracker) {
18908 final int N = mProcessCpuTracker.countStats();
18909 for (int i=0; i<N; i++) {
18910 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18911 if (st.pid == findPid || (st.baseName != null
18912 && st.baseName.equals(innerArgs[0]))) {
18913 nativeProcs.add(st);
18917 if (nativeProcs.size() > 0) {
18918 dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18919 opts.isCheckinRequest, opts.isCompact);
18920 Debug.MemoryInfo mi = null;
18921 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18922 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18923 final int pid = r.pid;
18924 if (!opts.isCheckinRequest && opts.dumpDetails) {
18925 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18928 mi = new Debug.MemoryInfo();
18930 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18931 Debug.getMemoryInfo(pid, mi);
18933 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18934 mi.dalvikPrivateDirty = (int)tmpLong[0];
18936 ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18937 opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18938 pid, r.baseName, 0, 0, 0, 0, 0, 0);
18939 if (opts.isCheckinRequest) {
18947 pw.println("No process found for: " + proc);
18951 if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18952 opts.dumpDetails = true;
18955 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18957 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18958 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18959 long nativePss = 0;
18960 long nativeSwapPss = 0;
18961 long dalvikPss = 0;
18962 long dalvikSwapPss = 0;
18963 long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18965 long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18968 long otherSwapPss = 0;
18969 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18970 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18972 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18973 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18974 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18975 new ArrayList[DUMP_MEM_OOM_LABEL.length];
18978 long totalSwapPss = 0;
18979 long cachedPss = 0;
18980 long cachedSwapPss = 0;
18981 boolean hasSwapPss = false;
18983 Debug.MemoryInfo mi = null;
18984 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18985 final ProcessRecord r = procs.get(i);
18986 final IApplicationThread thread;
18989 final boolean hasActivities;
18990 synchronized (this) {
18993 oomAdj = r.getSetAdjWithServices();
18994 hasActivities = r.activities.size() > 0;
18996 if (thread != null) {
18997 if (!opts.isCheckinRequest && opts.dumpDetails) {
18998 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
19001 mi = new Debug.MemoryInfo();
19003 final int reportType;
19004 final long startTime;
19005 final long endTime;
19006 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19007 reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19008 startTime = SystemClock.currentThreadTimeMillis();
19009 Debug.getMemoryInfo(pid, mi);
19010 endTime = SystemClock.currentThreadTimeMillis();
19011 hasSwapPss = mi.hasSwappedOutPss;
19013 reportType = ProcessStats.ADD_PSS_EXTERNAL;
19014 startTime = SystemClock.currentThreadTimeMillis();
19015 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19016 endTime = SystemClock.currentThreadTimeMillis();
19017 mi.dalvikPrivateDirty = (int)tmpLong[0];
19019 if (opts.dumpDetails) {
19020 if (opts.localOnly) {
19021 ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
19022 opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
19023 if (opts.isCheckinRequest) {
19029 TransferPipe tp = new TransferPipe();
19031 thread.dumpMemInfo(tp.getWriteFd(),
19032 mi, opts.isCheckinRequest, opts.dumpFullDetails,
19033 opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
19034 tp.go(fd, opts.dumpUnreachable ? 30000 : 5000);
19038 } catch (IOException e) {
19039 if (!opts.isCheckinRequest) {
19040 pw.println("Got IoException! " + e);
19043 } catch (RemoteException e) {
19044 if (!opts.isCheckinRequest) {
19045 pw.println("Got RemoteException! " + e);
19052 final long myTotalPss = mi.getTotalPss();
19053 final long myTotalUss = mi.getTotalUss();
19054 final long myTotalRss = mi.getTotalRss();
19055 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19057 synchronized (this) {
19058 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19059 // Record this for posterity if the process has been stable.
19060 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19061 reportType, endTime-startTime, r.pkgList);
19065 if (!opts.isCheckinRequest && mi != null) {
19066 totalPss += myTotalPss;
19067 totalSwapPss += myTotalSwapPss;
19068 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19069 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19070 myTotalSwapPss, pid, hasActivities);
19071 procMems.add(pssItem);
19072 procMemsMap.put(pid, pssItem);
19074 nativePss += mi.nativePss;
19075 nativeSwapPss += mi.nativeSwappedOutPss;
19076 dalvikPss += mi.dalvikPss;
19077 dalvikSwapPss += mi.dalvikSwappedOutPss;
19078 for (int j=0; j<dalvikSubitemPss.length; j++) {
19079 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19080 dalvikSubitemSwapPss[j] +=
19081 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19083 otherPss += mi.otherPss;
19084 otherSwapPss += mi.otherSwappedOutPss;
19085 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19086 long mem = mi.getOtherPss(j);
19089 mem = mi.getOtherSwappedOutPss(j);
19090 miscSwapPss[j] += mem;
19091 otherSwapPss -= mem;
19094 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19095 cachedPss += myTotalPss;
19096 cachedSwapPss += myTotalSwapPss;
19099 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19100 if (oomIndex == (oomPss.length - 1)
19101 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19102 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19103 oomPss[oomIndex] += myTotalPss;
19104 oomSwapPss[oomIndex] += myTotalSwapPss;
19105 if (oomProcs[oomIndex] == null) {
19106 oomProcs[oomIndex] = new ArrayList<MemItem>();
19108 oomProcs[oomIndex].add(pssItem);
19116 long nativeProcTotalPss = 0;
19118 if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
19119 // If we are showing aggregations, also look for native processes to
19120 // include so that our aggregations are more accurate.
19121 updateCpuStatsNow();
19123 synchronized (mProcessCpuTracker) {
19124 final int N = mProcessCpuTracker.countStats();
19125 for (int i=0; i<N; i++) {
19126 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19127 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19129 mi = new Debug.MemoryInfo();
19131 if (!brief && !opts.oomOnly) {
19132 Debug.getMemoryInfo(st.pid, mi);
19134 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19135 mi.nativePrivateDirty = (int)tmpLong[0];
19138 final long myTotalPss = mi.getTotalPss();
19139 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19140 totalPss += myTotalPss;
19141 totalSwapPss += myTotalSwapPss;
19142 nativeProcTotalPss += myTotalPss;
19144 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19145 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19146 procMems.add(pssItem);
19148 nativePss += mi.nativePss;
19149 nativeSwapPss += mi.nativeSwappedOutPss;
19150 dalvikPss += mi.dalvikPss;
19151 dalvikSwapPss += mi.dalvikSwappedOutPss;
19152 for (int j=0; j<dalvikSubitemPss.length; j++) {
19153 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19154 dalvikSubitemSwapPss[j] +=
19155 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19157 otherPss += mi.otherPss;
19158 otherSwapPss += mi.otherSwappedOutPss;
19159 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19160 long mem = mi.getOtherPss(j);
19163 mem = mi.getOtherSwappedOutPss(j);
19164 miscSwapPss[j] += mem;
19165 otherSwapPss -= mem;
19167 oomPss[0] += myTotalPss;
19168 oomSwapPss[0] += myTotalSwapPss;
19169 if (oomProcs[0] == null) {
19170 oomProcs[0] = new ArrayList<MemItem>();
19172 oomProcs[0].add(pssItem);
19177 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19179 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19180 final int dalvikId = -2;
19181 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19182 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19183 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19184 String label = Debug.MemoryInfo.getOtherLabel(j);
19185 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19187 if (dalvikSubitemPss.length > 0) {
19188 // Add dalvik subitems.
19189 for (MemItem memItem : catMems) {
19190 int memItemStart = 0, memItemEnd = 0;
19191 if (memItem.id == dalvikId) {
19192 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19193 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19194 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19195 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19196 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19197 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19198 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19199 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19200 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19201 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19202 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19204 continue; // No subitems, continue.
19206 memItem.subitems = new ArrayList<MemItem>();
19207 for (int j=memItemStart; j<=memItemEnd; j++) {
19208 final String name = Debug.MemoryInfo.getOtherLabel(
19209 Debug.MemoryInfo.NUM_OTHER_STATS + j);
19210 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19211 dalvikSubitemSwapPss[j], j));
19216 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19217 for (int j=0; j<oomPss.length; j++) {
19218 if (oomPss[j] != 0) {
19219 String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19220 : DUMP_MEM_OOM_LABEL[j];
19221 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19222 DUMP_MEM_OOM_ADJ[j]);
19223 item.subitems = oomProcs[j];
19228 opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19229 if (!brief && !opts.oomOnly && !opts.isCompact) {
19231 pw.println("Total PSS by process:");
19232 dumpMemItems(pw, " ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
19235 if (!opts.isCompact) {
19236 pw.println("Total PSS by OOM adjustment:");
19238 dumpMemItems(pw, " ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
19239 if (!brief && !opts.oomOnly) {
19240 PrintWriter out = categoryPw != null ? categoryPw : pw;
19241 if (!opts.isCompact) {
19243 out.println("Total PSS by category:");
19245 dumpMemItems(out, " ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
19247 if (!opts.isCompact) {
19250 MemInfoReader memInfo = new MemInfoReader();
19251 memInfo.readMemInfo();
19252 if (nativeProcTotalPss > 0) {
19253 synchronized (this) {
19254 final long cachedKb = memInfo.getCachedSizeKb();
19255 final long freeKb = memInfo.getFreeSizeKb();
19256 final long zramKb = memInfo.getZramTotalSizeKb();
19257 final long kernelKb = memInfo.getKernelUsedSizeKb();
19258 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19259 kernelKb*1024, nativeProcTotalPss*1024);
19260 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19261 nativeProcTotalPss);
19265 if (!opts.isCompact) {
19266 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
19267 pw.print(" (status ");
19268 switch (mLastMemoryLevel) {
19269 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
19270 pw.println("normal)");
19272 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
19273 pw.println("moderate)");
19275 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19276 pw.println("low)");
19278 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19279 pw.println("critical)");
19282 pw.print(mLastMemoryLevel);
19286 pw.print(" Free RAM: ");
19287 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19288 + memInfo.getFreeSizeKb()));
19290 pw.print(stringifyKBSize(cachedPss));
19291 pw.print(" cached pss + ");
19292 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
19293 pw.print(" cached kernel + ");
19294 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
19295 pw.println(" free)");
19297 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
19298 pw.print(cachedPss + memInfo.getCachedSizeKb()
19299 + memInfo.getFreeSizeKb()); pw.print(",");
19300 pw.println(totalPss - cachedPss);
19303 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19304 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19305 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19306 if (!opts.isCompact) {
19307 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
19308 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
19309 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
19310 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
19311 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
19313 pw.print("lostram,"); pw.println(lostRAM);
19316 if (memInfo.getZramTotalSizeKb() != 0) {
19317 if (!opts.isCompact) {
19318 pw.print(" ZRAM: ");
19319 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
19320 pw.print(" physical used for ");
19321 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
19322 - memInfo.getSwapFreeSizeKb()));
19323 pw.print(" in swap (");
19324 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
19325 pw.println(" total swap)");
19327 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
19328 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
19329 pw.println(memInfo.getSwapFreeSizeKb());
19332 final long[] ksm = getKsmInfo();
19333 if (!opts.isCompact) {
19334 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19335 || ksm[KSM_VOLATILE] != 0) {
19336 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
19337 pw.print(" saved from shared ");
19338 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
19339 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
19340 pw.print(" unshared; ");
19341 pw.print(stringifyKBSize(
19342 ksm[KSM_VOLATILE])); pw.println(" volatile");
19344 pw.print(" Tuning: ");
19345 pw.print(ActivityManager.staticGetMemoryClass());
19346 pw.print(" (large ");
19347 pw.print(ActivityManager.staticGetLargeMemoryClass());
19348 pw.print("), oom ");
19349 pw.print(stringifySize(
19350 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
19351 pw.print(", restore limit ");
19352 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
19353 if (ActivityManager.isLowRamDeviceStatic()) {
19354 pw.print(" (low-ram)");
19356 if (ActivityManager.isHighEndGfx()) {
19357 pw.print(" (high-end-gfx)");
19361 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
19362 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
19363 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
19364 pw.print("tuning,");
19365 pw.print(ActivityManager.staticGetMemoryClass());
19367 pw.print(ActivityManager.staticGetLargeMemoryClass());
19369 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
19370 if (ActivityManager.isLowRamDeviceStatic()) {
19371 pw.print(",low-ram");
19373 if (ActivityManager.isHighEndGfx()) {
19374 pw.print(",high-end-gfx");
19382 private final void dumpApplicationMemoryUsage(FileDescriptor fd,
19383 MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
19384 ArrayList<ProcessRecord> procs) {
19385 final long uptimeMs = SystemClock.uptimeMillis();
19386 final long realtimeMs = SystemClock.elapsedRealtime();
19387 final long[] tmpLong = new long[1];
19389 if (procs == null) {
19390 // No Java processes. Maybe they want to print a native process.
19391 String proc = "N/A";
19392 if (innerArgs.length > 0) {
19393 proc = innerArgs[0];
19394 if (proc.charAt(0) != '-') {
19395 ArrayList<ProcessCpuTracker.Stats> nativeProcs
19396 = new ArrayList<ProcessCpuTracker.Stats>();
19397 updateCpuStatsNow();
19400 findPid = Integer.parseInt(innerArgs[0]);
19401 } catch (NumberFormatException e) {
19403 synchronized (mProcessCpuTracker) {
19404 final int N = mProcessCpuTracker.countStats();
19405 for (int i=0; i<N; i++) {
19406 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19407 if (st.pid == findPid || (st.baseName != null
19408 && st.baseName.equals(innerArgs[0]))) {
19409 nativeProcs.add(st);
19413 if (nativeProcs.size() > 0) {
19414 ProtoOutputStream proto = new ProtoOutputStream(fd);
19416 proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19417 proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19418 Debug.MemoryInfo mi = null;
19419 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
19420 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
19421 final int pid = r.pid;
19422 final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES);
19424 proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19425 proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
19428 mi = new Debug.MemoryInfo();
19430 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19431 Debug.getMemoryInfo(pid, mi);
19433 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19434 mi.dalvikPrivateDirty = (int)tmpLong[0];
19436 ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19437 opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19447 Log.d(TAG, "No process found for: " + innerArgs[0]);
19451 if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
19452 opts.dumpDetails = true;
19455 ProtoOutputStream proto = new ProtoOutputStream(fd);
19457 proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19458 proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19460 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
19461 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
19462 long nativePss = 0;
19463 long nativeSwapPss = 0;
19464 long dalvikPss = 0;
19465 long dalvikSwapPss = 0;
19466 long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19468 long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19471 long otherSwapPss = 0;
19472 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19473 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19475 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19476 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19477 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
19478 new ArrayList[DUMP_MEM_OOM_LABEL.length];
19481 long totalSwapPss = 0;
19482 long cachedPss = 0;
19483 long cachedSwapPss = 0;
19484 boolean hasSwapPss = false;
19486 Debug.MemoryInfo mi = null;
19487 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
19488 final ProcessRecord r = procs.get(i);
19489 final IApplicationThread thread;
19492 final boolean hasActivities;
19493 synchronized (this) {
19496 oomAdj = r.getSetAdjWithServices();
19497 hasActivities = r.activities.size() > 0;
19499 if (thread == null) {
19503 mi = new Debug.MemoryInfo();
19505 final int reportType;
19506 final long startTime;
19507 final long endTime;
19508 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19509 reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19510 startTime = SystemClock.currentThreadTimeMillis();
19511 Debug.getMemoryInfo(pid, mi);
19512 endTime = SystemClock.currentThreadTimeMillis();
19513 hasSwapPss = mi.hasSwappedOutPss;
19515 reportType = ProcessStats.ADD_PSS_EXTERNAL;
19516 startTime = SystemClock.currentThreadTimeMillis();
19517 mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
19518 endTime = SystemClock.currentThreadTimeMillis();
19519 mi.dalvikPrivateDirty = (int) tmpLong[0];
19521 if (opts.dumpDetails) {
19522 if (opts.localOnly) {
19523 final long aToken = proto.start(MemInfoDumpProto.APP_PROCESSES);
19524 final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
19525 proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19526 proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.processName);
19527 ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19528 opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19533 ByteTransferPipe tp = new ByteTransferPipe();
19535 thread.dumpMemInfoProto(tp.getWriteFd(),
19536 mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
19537 opts.dumpUnreachable, innerArgs);
19538 proto.write(MemInfoDumpProto.APP_PROCESSES, tp.get());
19542 } catch (IOException e) {
19543 Log.e(TAG, "Got IOException!", e);
19544 } catch (RemoteException e) {
19545 Log.e(TAG, "Got RemoteException!", e);
19550 final long myTotalPss = mi.getTotalPss();
19551 final long myTotalUss = mi.getTotalUss();
19552 final long myTotalRss = mi.getTotalRss();
19553 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19555 synchronized (this) {
19556 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19557 // Record this for posterity if the process has been stable.
19558 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19559 reportType, endTime-startTime, r.pkgList);
19563 if (!opts.isCheckinRequest && mi != null) {
19564 totalPss += myTotalPss;
19565 totalSwapPss += myTotalSwapPss;
19566 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19567 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19568 myTotalSwapPss, pid, hasActivities);
19569 procMems.add(pssItem);
19570 procMemsMap.put(pid, pssItem);
19572 nativePss += mi.nativePss;
19573 nativeSwapPss += mi.nativeSwappedOutPss;
19574 dalvikPss += mi.dalvikPss;
19575 dalvikSwapPss += mi.dalvikSwappedOutPss;
19576 for (int j=0; j<dalvikSubitemPss.length; j++) {
19577 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19578 dalvikSubitemSwapPss[j] +=
19579 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19581 otherPss += mi.otherPss;
19582 otherSwapPss += mi.otherSwappedOutPss;
19583 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19584 long mem = mi.getOtherPss(j);
19587 mem = mi.getOtherSwappedOutPss(j);
19588 miscSwapPss[j] += mem;
19589 otherSwapPss -= mem;
19592 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19593 cachedPss += myTotalPss;
19594 cachedSwapPss += myTotalSwapPss;
19597 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19598 if (oomIndex == (oomPss.length - 1)
19599 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19600 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19601 oomPss[oomIndex] += myTotalPss;
19602 oomSwapPss[oomIndex] += myTotalSwapPss;
19603 if (oomProcs[oomIndex] == null) {
19604 oomProcs[oomIndex] = new ArrayList<MemItem>();
19606 oomProcs[oomIndex].add(pssItem);
19613 long nativeProcTotalPss = 0;
19615 if (procs.size() > 1 && !opts.packages) {
19616 // If we are showing aggregations, also look for native processes to
19617 // include so that our aggregations are more accurate.
19618 updateCpuStatsNow();
19620 synchronized (mProcessCpuTracker) {
19621 final int N = mProcessCpuTracker.countStats();
19622 for (int i=0; i<N; i++) {
19623 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19624 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19626 mi = new Debug.MemoryInfo();
19628 if (!brief && !opts.oomOnly) {
19629 Debug.getMemoryInfo(st.pid, mi);
19631 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19632 mi.nativePrivateDirty = (int)tmpLong[0];
19635 final long myTotalPss = mi.getTotalPss();
19636 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19637 totalPss += myTotalPss;
19638 nativeProcTotalPss += myTotalPss;
19640 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19641 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19642 procMems.add(pssItem);
19644 nativePss += mi.nativePss;
19645 nativeSwapPss += mi.nativeSwappedOutPss;
19646 dalvikPss += mi.dalvikPss;
19647 dalvikSwapPss += mi.dalvikSwappedOutPss;
19648 for (int j=0; j<dalvikSubitemPss.length; j++) {
19649 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19650 dalvikSubitemSwapPss[j] +=
19651 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19653 otherPss += mi.otherPss;
19654 otherSwapPss += mi.otherSwappedOutPss;
19655 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19656 long mem = mi.getOtherPss(j);
19659 mem = mi.getOtherSwappedOutPss(j);
19660 miscSwapPss[j] += mem;
19661 otherSwapPss -= mem;
19663 oomPss[0] += myTotalPss;
19664 oomSwapPss[0] += myTotalSwapPss;
19665 if (oomProcs[0] == null) {
19666 oomProcs[0] = new ArrayList<MemItem>();
19668 oomProcs[0].add(pssItem);
19673 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19675 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19676 final int dalvikId = -2;
19677 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19678 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19679 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19680 String label = Debug.MemoryInfo.getOtherLabel(j);
19681 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19683 if (dalvikSubitemPss.length > 0) {
19684 // Add dalvik subitems.
19685 for (MemItem memItem : catMems) {
19686 int memItemStart = 0, memItemEnd = 0;
19687 if (memItem.id == dalvikId) {
19688 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19689 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19690 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19691 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19692 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19693 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19694 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19695 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19696 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19697 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19698 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19700 continue; // No subitems, continue.
19702 memItem.subitems = new ArrayList<MemItem>();
19703 for (int j=memItemStart; j<=memItemEnd; j++) {
19704 final String name = Debug.MemoryInfo.getOtherLabel(
19705 Debug.MemoryInfo.NUM_OTHER_STATS + j);
19706 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19707 dalvikSubitemSwapPss[j], j));
19712 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19713 for (int j=0; j<oomPss.length; j++) {
19714 if (oomPss[j] != 0) {
19715 String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19716 : DUMP_MEM_OOM_LABEL[j];
19717 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19718 DUMP_MEM_OOM_ADJ[j]);
19719 item.subitems = oomProcs[j];
19724 opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19725 if (!opts.oomOnly) {
19726 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_PROCESS, "proc",
19727 procMems, true, opts.dumpSwapPss);
19729 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19730 oomMems, false, opts.dumpSwapPss);
19731 if (!brief && !opts.oomOnly) {
19732 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_CATEGORY, "cat",
19733 catMems, true, opts.dumpSwapPss);
19735 MemInfoReader memInfo = new MemInfoReader();
19736 memInfo.readMemInfo();
19737 if (nativeProcTotalPss > 0) {
19738 synchronized (this) {
19739 final long cachedKb = memInfo.getCachedSizeKb();
19740 final long freeKb = memInfo.getFreeSizeKb();
19741 final long zramKb = memInfo.getZramTotalSizeKb();
19742 final long kernelKb = memInfo.getKernelUsedSizeKb();
19743 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19744 kernelKb*1024, nativeProcTotalPss*1024);
19745 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19746 nativeProcTotalPss);
19750 proto.write(MemInfoDumpProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19751 proto.write(MemInfoDumpProto.STATUS, mLastMemoryLevel);
19752 proto.write(MemInfoDumpProto.CACHED_PSS_KB, cachedPss);
19753 proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19754 proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
19756 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19757 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19758 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19759 proto.write(MemInfoDumpProto.USED_PSS_KB, totalPss - cachedPss);
19760 proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19761 proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
19763 if (memInfo.getZramTotalSizeKb() != 0) {
19764 proto.write(MemInfoDumpProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19765 proto.write(MemInfoDumpProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19766 memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19767 proto.write(MemInfoDumpProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19769 final long[] ksm = getKsmInfo();
19770 proto.write(MemInfoDumpProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19771 proto.write(MemInfoDumpProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19772 proto.write(MemInfoDumpProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19773 proto.write(MemInfoDumpProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19775 proto.write(MemInfoDumpProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19776 proto.write(MemInfoDumpProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19777 proto.write(MemInfoDumpProto.OOM_KB,
19778 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19779 proto.write(MemInfoDumpProto.RESTORE_LIMIT_KB,
19780 mProcessList.getCachedRestoreThresholdKb());
19782 proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19783 proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19790 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19791 long memtrack, String name) {
19793 sb.append(ProcessList.makeOomAdjString(oomAdj));
19795 sb.append(ProcessList.makeProcStateString(procState));
19797 ProcessList.appendRamKb(sb, pss);
19800 if (memtrack > 0) {
19802 sb.append(stringifyKBSize(memtrack));
19803 sb.append(" memtrack)");
19807 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19808 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19809 sb.append(" (pid ");
19812 sb.append(mi.adjType);
19814 if (mi.adjReason != null) {
19816 sb.append(mi.adjReason);
19821 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19822 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19823 for (int i=0, N=memInfos.size(); i<N; i++) {
19824 ProcessMemInfo mi = memInfos.get(i);
19825 infoMap.put(mi.pid, mi);
19827 updateCpuStatsNow();
19828 long[] memtrackTmp = new long[1];
19829 final List<ProcessCpuTracker.Stats> stats;
19830 // Get a list of Stats that have vsize > 0
19831 synchronized (mProcessCpuTracker) {
19832 stats = mProcessCpuTracker.getStats((st) -> {
19833 return st.vsize > 0;
19836 final int statsCount = stats.size();
19837 for (int i = 0; i < statsCount; i++) {
19838 ProcessCpuTracker.Stats st = stats.get(i);
19839 long pss = Debug.getPss(st.pid, null, memtrackTmp);
19841 if (infoMap.indexOfKey(st.pid) < 0) {
19842 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19843 ProcessList.NATIVE_ADJ, -1, "native", null);
19845 mi.memtrack = memtrackTmp[0];
19852 long totalMemtrack = 0;
19853 for (int i=0, N=memInfos.size(); i<N; i++) {
19854 ProcessMemInfo mi = memInfos.get(i);
19856 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19857 mi.memtrack = memtrackTmp[0];
19859 totalPss += mi.pss;
19860 totalMemtrack += mi.memtrack;
19862 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19863 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19864 if (lhs.oomAdj != rhs.oomAdj) {
19865 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19867 if (lhs.pss != rhs.pss) {
19868 return lhs.pss < rhs.pss ? 1 : -1;
19874 StringBuilder tag = new StringBuilder(128);
19875 StringBuilder stack = new StringBuilder(128);
19876 tag.append("Low on memory -- ");
19877 appendMemBucket(tag, totalPss, "total", false);
19878 appendMemBucket(stack, totalPss, "total", true);
19880 StringBuilder fullNativeBuilder = new StringBuilder(1024);
19881 StringBuilder shortNativeBuilder = new StringBuilder(1024);
19882 StringBuilder fullJavaBuilder = new StringBuilder(1024);
19884 boolean firstLine = true;
19885 int lastOomAdj = Integer.MIN_VALUE;
19886 long extraNativeRam = 0;
19887 long extraNativeMemtrack = 0;
19888 long cachedPss = 0;
19889 for (int i=0, N=memInfos.size(); i<N; i++) {
19890 ProcessMemInfo mi = memInfos.get(i);
19892 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19893 cachedPss += mi.pss;
19896 if (mi.oomAdj != ProcessList.NATIVE_ADJ
19897 && (mi.oomAdj < ProcessList.SERVICE_ADJ
19898 || mi.oomAdj == ProcessList.HOME_APP_ADJ
19899 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19900 if (lastOomAdj != mi.oomAdj) {
19901 lastOomAdj = mi.oomAdj;
19902 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19905 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19910 stack.append("\n\t at ");
19918 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19919 appendMemBucket(tag, mi.pss, mi.name, false);
19921 appendMemBucket(stack, mi.pss, mi.name, true);
19922 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19923 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19925 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19926 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19927 stack.append(DUMP_MEM_OOM_LABEL[k]);
19929 stack.append(DUMP_MEM_OOM_ADJ[k]);
19936 appendMemInfo(fullNativeBuilder, mi);
19937 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19938 // The short form only has native processes that are >= 512K.
19939 if (mi.pss >= 512) {
19940 appendMemInfo(shortNativeBuilder, mi);
19942 extraNativeRam += mi.pss;
19943 extraNativeMemtrack += mi.memtrack;
19946 // Short form has all other details, but if we have collected RAM
19947 // from smaller native processes let's dump a summary of that.
19948 if (extraNativeRam > 0) {
19949 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19950 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19951 shortNativeBuilder.append('\n');
19952 extraNativeRam = 0;
19954 appendMemInfo(fullJavaBuilder, mi);
19958 fullJavaBuilder.append(" ");
19959 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19960 fullJavaBuilder.append(": TOTAL");
19961 if (totalMemtrack > 0) {
19962 fullJavaBuilder.append(" (");
19963 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19964 fullJavaBuilder.append(" memtrack)");
19967 fullJavaBuilder.append("\n");
19969 MemInfoReader memInfo = new MemInfoReader();
19970 memInfo.readMemInfo();
19971 final long[] infos = memInfo.getRawInfo();
19973 StringBuilder memInfoBuilder = new StringBuilder(1024);
19974 Debug.getMemInfo(infos);
19975 memInfoBuilder.append(" MemInfo: ");
19976 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
19977 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
19978 memInfoBuilder.append(stringifyKBSize(
19979 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
19980 memInfoBuilder.append(stringifyKBSize(
19981 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
19982 memInfoBuilder.append(stringifyKBSize(
19983 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
19984 memInfoBuilder.append(" ");
19985 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
19986 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
19987 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
19988 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
19989 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
19990 memInfoBuilder.append(" ZRAM: ");
19991 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
19992 memInfoBuilder.append(" RAM, ");
19993 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
19994 memInfoBuilder.append(" swap total, ");
19995 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
19996 memInfoBuilder.append(" swap free\n");
19998 final long[] ksm = getKsmInfo();
19999 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
20000 || ksm[KSM_VOLATILE] != 0) {
20001 memInfoBuilder.append(" KSM: ");
20002 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
20003 memInfoBuilder.append(" saved from shared ");
20004 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
20005 memInfoBuilder.append("\n ");
20006 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
20007 memInfoBuilder.append(" unshared; ");
20008 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
20009 memInfoBuilder.append(" volatile\n");
20011 memInfoBuilder.append(" Free RAM: ");
20012 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
20013 + memInfo.getFreeSizeKb()));
20014 memInfoBuilder.append("\n");
20015 memInfoBuilder.append(" Used RAM: ");
20016 memInfoBuilder.append(stringifyKBSize(
20017 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
20018 memInfoBuilder.append("\n");
20019 memInfoBuilder.append(" Lost RAM: ");
20020 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
20021 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
20022 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
20023 memInfoBuilder.append("\n");
20024 Slog.i(TAG, "Low on memory:");
20025 Slog.i(TAG, shortNativeBuilder.toString());
20026 Slog.i(TAG, fullJavaBuilder.toString());
20027 Slog.i(TAG, memInfoBuilder.toString());
20029 StringBuilder dropBuilder = new StringBuilder(1024);
20031 StringWriter oomSw = new StringWriter();
20032 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
20033 StringWriter catSw = new StringWriter();
20034 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
20035 String[] emptyArgs = new String[] { };
20036 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
20038 String oomString = oomSw.toString();
20040 dropBuilder.append("Low on memory:");
20041 dropBuilder.append(stack);
20042 dropBuilder.append('\n');
20043 dropBuilder.append(fullNativeBuilder);
20044 dropBuilder.append(fullJavaBuilder);
20045 dropBuilder.append('\n');
20046 dropBuilder.append(memInfoBuilder);
20047 dropBuilder.append('\n');
20049 dropBuilder.append(oomString);
20050 dropBuilder.append('\n');
20052 StringWriter catSw = new StringWriter();
20053 synchronized (ActivityManagerService.this) {
20054 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
20055 String[] emptyArgs = new String[] { };
20057 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
20059 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
20060 false, null).dumpLocked();
20062 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
20065 dropBuilder.append(catSw.toString());
20066 StatsLog.write(StatsLog.LOW_MEM_REPORTED);
20067 addErrorToDropBox("lowmem", null, "system_server", null,
20068 null, tag.toString(), dropBuilder.toString(), null, null);
20069 //Slog.i(TAG, "Sent to dropbox:");
20070 //Slog.i(TAG, dropBuilder.toString());
20071 synchronized (ActivityManagerService.this) {
20072 long now = SystemClock.uptimeMillis();
20073 if (mLastMemUsageReportTime < now) {
20074 mLastMemUsageReportTime = now;
20080 * Searches array of arguments for the specified string
20081 * @param args array of argument strings
20082 * @param value value to search for
20083 * @return true if the value is contained in the array
20085 private static boolean scanArgs(String[] args, String value) {
20086 if (args != null) {
20087 for (String arg : args) {
20088 if (value.equals(arg)) {
20096 private final boolean removeDyingProviderLocked(ProcessRecord proc,
20097 ContentProviderRecord cpr, boolean always) {
20098 final boolean inLaunching = mLaunchingProviders.contains(cpr);
20100 if (!inLaunching || always) {
20101 synchronized (cpr) {
20102 cpr.launchingApp = null;
20105 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
20106 String names[] = cpr.info.authority.split(";");
20107 for (int j = 0; j < names.length; j++) {
20108 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
20112 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
20113 ContentProviderConnection conn = cpr.connections.get(i);
20114 if (conn.waiting) {
20115 // If this connection is waiting for the provider, then we don't
20116 // need to mess with its process unless we are always removing
20117 // or for some reason the provider is not currently launching.
20118 if (inLaunching && !always) {
20122 ProcessRecord capp = conn.client;
20124 if (conn.stableCount > 0) {
20125 if (!capp.persistent && capp.thread != null
20127 && capp.pid != MY_PID) {
20128 capp.kill("depends on provider "
20129 + cpr.name.flattenToShortString()
20130 + " in dying proc " + (proc != null ? proc.processName : "??")
20131 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
20133 } else if (capp.thread != null && conn.provider.provider != null) {
20135 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
20136 } catch (RemoteException e) {
20138 // In the protocol here, we don't expect the client to correctly
20139 // clean up this connection, we'll just remove it.
20140 cpr.connections.remove(i);
20141 if (conn.client.conProviders.remove(conn)) {
20142 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
20147 if (inLaunching && always) {
20148 mLaunchingProviders.remove(cpr);
20150 return inLaunching;
20154 * Main code for cleaning up a process when it has gone away. This is
20155 * called both as a result of the process dying, or directly when stopping
20156 * a process when running in single process mode.
20158 * @return Returns true if the given process has been restarted, so the
20159 * app that was passed in must remain on the process lists.
20162 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
20163 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
20165 removeLruProcessLocked(app);
20166 ProcessList.remove(app.pid);
20169 mProcessesToGc.remove(app);
20170 mPendingPssProcesses.remove(app);
20171 ProcessList.abortNextPssTime(app.procStateMemTracker);
20173 // Dismiss any open dialogs.
20174 if (app.crashDialog != null && !app.forceCrashReport) {
20175 app.crashDialog.dismiss();
20176 app.crashDialog = null;
20178 if (app.anrDialog != null) {
20179 app.anrDialog.dismiss();
20180 app.anrDialog = null;
20182 if (app.waitDialog != null) {
20183 app.waitDialog.dismiss();
20184 app.waitDialog = null;
20187 app.crashing = false;
20188 app.notResponding = false;
20190 app.resetPackageList(mProcessStats);
20191 app.unlinkDeathRecipient();
20192 app.makeInactive(mProcessStats);
20193 app.waitingToKill = null;
20194 app.forcingToImportant = null;
20195 updateProcessForegroundLocked(app, false, false);
20196 app.foregroundActivities = false;
20197 app.hasShownUi = false;
20198 app.treatLikeActivity = false;
20199 app.hasAboveClient = false;
20200 app.hasClientActivities = false;
20202 mServices.killServicesLocked(app, allowRestart);
20204 boolean restart = false;
20206 // Remove published content providers.
20207 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
20208 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
20209 final boolean always = app.bad || !allowRestart;
20210 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
20211 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
20212 // We left the provider in the launching list, need to
20217 cpr.provider = null;
20220 app.pubProviders.clear();
20222 // Take care of any launching providers waiting for this process.
20223 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
20227 // Unregister from connected content providers.
20228 if (!app.conProviders.isEmpty()) {
20229 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
20230 ContentProviderConnection conn = app.conProviders.get(i);
20231 conn.provider.connections.remove(conn);
20232 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
20233 conn.provider.name);
20235 app.conProviders.clear();
20238 // At this point there may be remaining entries in mLaunchingProviders
20239 // where we were the only one waiting, so they are no longer of use.
20240 // Look for these and clean up if found.
20241 // XXX Commented out for now. Trying to figure out a way to reproduce
20242 // the actual situation to identify what is actually going on.
20244 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20245 ContentProviderRecord cpr = mLaunchingProviders.get(i);
20246 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
20247 synchronized (cpr) {
20248 cpr.launchingApp = null;
20255 skipCurrentReceiverLocked(app);
20257 // Unregister any receivers.
20258 for (int i = app.receivers.size() - 1; i >= 0; i--) {
20259 removeReceiverLocked(app.receivers.valueAt(i));
20261 app.receivers.clear();
20263 // If the app is undergoing backup, tell the backup manager about it
20264 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
20265 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
20266 + mBackupTarget.appInfo + " died during backup");
20267 mHandler.post(new Runnable() {
20271 IBackupManager bm = IBackupManager.Stub.asInterface(
20272 ServiceManager.getService(Context.BACKUP_SERVICE));
20273 bm.agentDisconnected(app.info.packageName);
20274 } catch (RemoteException e) {
20275 // can't happen; backup manager is local
20281 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
20282 ProcessChangeItem item = mPendingProcessChanges.get(i);
20283 if (app.pid > 0 && item.pid == app.pid) {
20284 mPendingProcessChanges.remove(i);
20285 mAvailProcessChanges.add(item);
20288 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
20289 null).sendToTarget();
20291 // If the caller is restarting this app, then leave it in its
20292 // current lists and let the caller take care of it.
20297 if (!app.persistent || app.isolated) {
20298 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
20299 "Removing non-persistent process during cleanup: " + app);
20300 if (!replacingPid) {
20301 removeProcessNameLocked(app.processName, app.uid, app);
20303 if (mHeavyWeightProcess == app) {
20304 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
20305 mHeavyWeightProcess.userId, 0));
20306 mHeavyWeightProcess = null;
20308 } else if (!app.removed) {
20309 // This app is persistent, so we need to keep its record around.
20310 // If it is not already on the pending app list, add it there
20311 // and start a new process for it.
20312 if (mPersistentStartingProcesses.indexOf(app) < 0) {
20313 mPersistentStartingProcesses.add(app);
20317 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
20318 TAG_CLEANUP, "Clean-up removing on hold: " + app);
20319 mProcessesOnHold.remove(app);
20321 if (app == mHomeProcess) {
20322 mHomeProcess = null;
20324 if (app == mPreviousProcess) {
20325 mPreviousProcess = null;
20328 if (restart && !app.isolated) {
20329 // We have components that still need to be running in the
20330 // process, so re-launch it.
20332 ProcessList.remove(app.pid);
20334 addProcessNameLocked(app);
20335 app.pendingStart = false;
20336 startProcessLocked(app, "restart", app.processName);
20338 } else if (app.pid > 0 && app.pid != MY_PID) {
20341 synchronized (mPidsSelfLocked) {
20342 mPidsSelfLocked.remove(app.pid);
20343 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
20345 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
20346 if (app.isolated) {
20347 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
20354 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
20355 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20356 ContentProviderRecord cpr = mLaunchingProviders.get(i);
20357 if (cpr.launchingApp == app) {
20364 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
20365 // Look through the content providers we are waiting to have launched,
20366 // and if any run in this process then either schedule a restart of
20367 // the process or kill the client waiting for it if this process has
20369 boolean restart = false;
20370 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20371 ContentProviderRecord cpr = mLaunchingProviders.get(i);
20372 if (cpr.launchingApp == app) {
20373 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
20376 removeDyingProviderLocked(app, cpr, true);
20383 // =========================================================
20385 // =========================================================
20388 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
20389 enforceNotIsolatedCaller("getServices");
20391 final int callingUid = Binder.getCallingUid();
20392 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
20393 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
20394 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
20396 synchronized (this) {
20397 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
20398 allowed, canInteractAcrossUsers);
20403 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
20404 enforceNotIsolatedCaller("getRunningServiceControlPanel");
20405 synchronized (this) {
20406 return mServices.getRunningServiceControlPanelLocked(name);
20411 public ComponentName startService(IApplicationThread caller, Intent service,
20412 String resolvedType, boolean requireForeground, String callingPackage, int userId)
20413 throws TransactionTooLargeException {
20414 enforceNotIsolatedCaller("startService");
20415 // Refuse possible leaked file descriptors
20416 if (service != null && service.hasFileDescriptors() == true) {
20417 throw new IllegalArgumentException("File descriptors passed in Intent");
20420 if (callingPackage == null) {
20421 throw new IllegalArgumentException("callingPackage cannot be null");
20424 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20425 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
20426 synchronized(this) {
20427 final int callingPid = Binder.getCallingPid();
20428 final int callingUid = Binder.getCallingUid();
20429 final long origId = Binder.clearCallingIdentity();
20432 res = mServices.startServiceLocked(caller, service,
20433 resolvedType, callingPid, callingUid,
20434 requireForeground, callingPackage, userId);
20436 Binder.restoreCallingIdentity(origId);
20442 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
20443 boolean fgRequired, String callingPackage, int userId)
20444 throws TransactionTooLargeException {
20445 synchronized(this) {
20446 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20447 "startServiceInPackage: " + service + " type=" + resolvedType);
20448 final long origId = Binder.clearCallingIdentity();
20451 res = mServices.startServiceLocked(null, service,
20452 resolvedType, -1, uid, fgRequired, callingPackage, userId);
20454 Binder.restoreCallingIdentity(origId);
20461 public int stopService(IApplicationThread caller, Intent service,
20462 String resolvedType, int userId) {
20463 enforceNotIsolatedCaller("stopService");
20464 // Refuse possible leaked file descriptors
20465 if (service != null && service.hasFileDescriptors() == true) {
20466 throw new IllegalArgumentException("File descriptors passed in Intent");
20469 synchronized(this) {
20470 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
20475 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
20476 enforceNotIsolatedCaller("peekService");
20477 // Refuse possible leaked file descriptors
20478 if (service != null && service.hasFileDescriptors() == true) {
20479 throw new IllegalArgumentException("File descriptors passed in Intent");
20482 if (callingPackage == null) {
20483 throw new IllegalArgumentException("callingPackage cannot be null");
20486 synchronized(this) {
20487 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
20492 public boolean stopServiceToken(ComponentName className, IBinder token,
20494 synchronized(this) {
20495 return mServices.stopServiceTokenLocked(className, token, startId);
20500 public void setServiceForeground(ComponentName className, IBinder token,
20501 int id, Notification notification, int flags) {
20502 synchronized(this) {
20503 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
20508 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
20509 boolean requireFull, String name, String callerPackage) {
20510 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
20511 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
20514 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
20515 String className, int flags) {
20516 boolean result = false;
20517 // For apps that don't have pre-defined UIDs, check for permission
20518 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
20519 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20520 if (ActivityManager.checkUidPermission(
20521 INTERACT_ACROSS_USERS,
20522 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
20523 ComponentName comp = new ComponentName(aInfo.packageName, className);
20524 String msg = "Permission Denial: Component " + comp.flattenToShortString()
20525 + " requests FLAG_SINGLE_USER, but app does not hold "
20526 + INTERACT_ACROSS_USERS;
20528 throw new SecurityException(msg);
20530 // Permission passed
20533 } else if ("system".equals(componentProcessName)) {
20535 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20536 // Phone app and persistent apps are allowed to export singleuser providers.
20537 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
20538 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
20540 if (DEBUG_MU) Slog.v(TAG_MU,
20541 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
20542 + Integer.toHexString(flags) + ") = " + result);
20547 * Checks to see if the caller is in the same app as the singleton
20548 * component, or the component is in a special app. It allows special apps
20549 * to export singleton components but prevents exporting singleton
20550 * components for regular apps.
20552 boolean isValidSingletonCall(int callingUid, int componentUid) {
20553 int componentAppId = UserHandle.getAppId(componentUid);
20554 return UserHandle.isSameApp(callingUid, componentUid)
20555 || componentAppId == SYSTEM_UID
20556 || componentAppId == PHONE_UID
20557 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
20558 == PackageManager.PERMISSION_GRANTED;
20561 public int bindService(IApplicationThread caller, IBinder token, Intent service,
20562 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
20563 int userId) throws TransactionTooLargeException {
20564 enforceNotIsolatedCaller("bindService");
20566 // Refuse possible leaked file descriptors
20567 if (service != null && service.hasFileDescriptors() == true) {
20568 throw new IllegalArgumentException("File descriptors passed in Intent");
20571 if (callingPackage == null) {
20572 throw new IllegalArgumentException("callingPackage cannot be null");
20575 synchronized(this) {
20576 return mServices.bindServiceLocked(caller, token, service,
20577 resolvedType, connection, flags, callingPackage, userId);
20581 public boolean unbindService(IServiceConnection connection) {
20582 synchronized (this) {
20583 return mServices.unbindServiceLocked(connection);
20587 public void publishService(IBinder token, Intent intent, IBinder service) {
20588 // Refuse possible leaked file descriptors
20589 if (intent != null && intent.hasFileDescriptors() == true) {
20590 throw new IllegalArgumentException("File descriptors passed in Intent");
20593 synchronized(this) {
20594 if (!(token instanceof ServiceRecord)) {
20595 throw new IllegalArgumentException("Invalid service token");
20597 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
20601 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
20602 // Refuse possible leaked file descriptors
20603 if (intent != null && intent.hasFileDescriptors() == true) {
20604 throw new IllegalArgumentException("File descriptors passed in Intent");
20607 synchronized(this) {
20608 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
20612 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
20613 synchronized(this) {
20614 if (!(token instanceof ServiceRecord)) {
20615 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
20616 throw new IllegalArgumentException("Invalid service token");
20618 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
20622 // =========================================================
20623 // BACKUP AND RESTORE
20624 // =========================================================
20626 // Cause the target app to be launched if necessary and its backup agent
20627 // instantiated. The backup agent will invoke backupAgentCreated() on the
20628 // activity manager to announce its creation.
20629 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
20630 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
20631 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
20633 IPackageManager pm = AppGlobals.getPackageManager();
20634 ApplicationInfo app = null;
20636 app = pm.getApplicationInfo(packageName, STOCK_PM_FLAGS, userId);
20637 } catch (RemoteException e) {
20638 // can't happen; package manager is process-local
20641 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
20648 synchronized(this) {
20649 // !!! TODO: currently no check here that we're already bound
20650 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
20651 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20652 synchronized (stats) {
20653 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
20656 // Backup agent is now in use, its package can't be stopped.
20658 AppGlobals.getPackageManager().setPackageStoppedState(
20659 app.packageName, false, UserHandle.getUserId(app.uid));
20660 } catch (RemoteException e) {
20661 } catch (IllegalArgumentException e) {
20662 Slog.w(TAG, "Failed trying to unstop package "
20663 + app.packageName + ": " + e);
20666 BackupRecord r = new BackupRecord(ss, app, backupMode);
20667 ComponentName hostingName =
20668 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
20669 ? new ComponentName(app.packageName, app.backupAgentName)
20670 : new ComponentName("android", "FullBackupAgent");
20671 // startProcessLocked() returns existing proc's record if it's already running
20672 ProcessRecord proc = startProcessLocked(app.processName, app,
20673 false, 0, "backup", hostingName, false, false, false);
20674 if (proc == null) {
20675 Slog.e(TAG, "Unable to start backup agent process " + r);
20679 // If the app is a regular app (uid >= 10000) and not the system server or phone
20680 // process, etc, then mark it as being in full backup so that certain calls to the
20681 // process can be blocked. This is not reset to false anywhere because we kill the
20682 // process after the full backup is done and the ProcessRecord will vaporize anyway.
20683 if (UserHandle.isApp(app.uid) &&
20684 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
20685 proc.inFullBackup = true;
20688 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20689 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20691 mBackupAppName = app.packageName;
20693 // Try not to kill the process during backup
20694 updateOomAdjLocked(proc, true);
20696 // If the process is already attached, schedule the creation of the backup agent now.
20697 // If it is not yet live, this will be done when it attaches to the framework.
20698 if (proc.thread != null) {
20699 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20701 proc.thread.scheduleCreateBackupAgent(app,
20702 compatibilityInfoForPackageLocked(app), backupMode);
20703 } catch (RemoteException e) {
20704 // Will time out on the backup manager side
20707 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20709 // Invariants: at this point, the target app process exists and the application
20710 // is either already running or in the process of coming up. mBackupTarget and
20711 // mBackupAppName describe the app, so that when it binds back to the AM we
20712 // know that it's scheduled for a backup-agent operation.
20715 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20716 if (oldBackupUid != -1) {
20717 js.removeBackingUpUid(oldBackupUid);
20719 if (newBackupUid != -1) {
20720 js.addBackingUpUid(newBackupUid);
20727 public void clearPendingBackup() {
20728 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20729 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20731 synchronized (this) {
20732 mBackupTarget = null;
20733 mBackupAppName = null;
20736 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20737 js.clearAllBackingUpUids();
20740 // A backup agent has just come up
20741 public void backupAgentCreated(String agentPackageName, IBinder agent) {
20742 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20745 synchronized(this) {
20746 if (!agentPackageName.equals(mBackupAppName)) {
20747 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20752 long oldIdent = Binder.clearCallingIdentity();
20754 IBackupManager bm = IBackupManager.Stub.asInterface(
20755 ServiceManager.getService(Context.BACKUP_SERVICE));
20756 bm.agentConnected(agentPackageName, agent);
20757 } catch (RemoteException e) {
20758 // can't happen; the backup manager service is local
20759 } catch (Exception e) {
20760 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20761 e.printStackTrace();
20763 Binder.restoreCallingIdentity(oldIdent);
20767 // done with this agent
20768 public void unbindBackupAgent(ApplicationInfo appInfo) {
20769 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20770 if (appInfo == null) {
20771 Slog.w(TAG, "unbind backup agent for null app");
20777 synchronized(this) {
20779 if (mBackupAppName == null) {
20780 Slog.w(TAG, "Unbinding backup agent with no active backup");
20784 if (!mBackupAppName.equals(appInfo.packageName)) {
20785 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20789 // Not backing this app up any more; reset its OOM adjustment
20790 final ProcessRecord proc = mBackupTarget.app;
20791 updateOomAdjLocked(proc, true);
20792 proc.inFullBackup = false;
20794 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20796 // If the app crashed during backup, 'thread' will be null here
20797 if (proc.thread != null) {
20799 proc.thread.scheduleDestroyBackupAgent(appInfo,
20800 compatibilityInfoForPackageLocked(appInfo));
20801 } catch (Exception e) {
20802 Slog.e(TAG, "Exception when unbinding backup agent:");
20803 e.printStackTrace();
20807 mBackupTarget = null;
20808 mBackupAppName = null;
20812 if (oldBackupUid != -1) {
20813 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20814 js.removeBackingUpUid(oldBackupUid);
20818 // =========================================================
20820 // =========================================================
20822 private boolean isInstantApp(ProcessRecord record, @Nullable String callerPackage, int uid) {
20823 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20826 // Easy case -- we have the app's ProcessRecord.
20827 if (record != null) {
20828 return record.info.isInstantApp();
20830 // Otherwise check with PackageManager.
20831 IPackageManager pm = AppGlobals.getPackageManager();
20833 if (callerPackage == null) {
20834 final String[] packageNames = pm.getPackagesForUid(uid);
20835 if (packageNames == null || packageNames.length == 0) {
20836 throw new IllegalArgumentException("Unable to determine caller package name");
20838 // Instant Apps can't use shared uids, so its safe to only check the first package.
20839 callerPackage = packageNames[0];
20841 mAppOpsService.checkPackage(uid, callerPackage);
20842 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20843 } catch (RemoteException e) {
20844 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20849 boolean isPendingBroadcastProcessLocked(int pid) {
20850 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20851 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20854 void skipPendingBroadcastLocked(int pid) {
20855 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20856 for (BroadcastQueue queue : mBroadcastQueues) {
20857 queue.skipPendingBroadcastLocked(pid);
20861 // The app just attached; send any pending broadcasts that it should receive
20862 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20863 boolean didSomething = false;
20864 for (BroadcastQueue queue : mBroadcastQueues) {
20865 didSomething |= queue.sendPendingBroadcastsLocked(app);
20867 return didSomething;
20870 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20871 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20873 enforceNotIsolatedCaller("registerReceiver");
20874 ArrayList<Intent> stickyIntents = null;
20875 ProcessRecord callerApp = null;
20876 final boolean visibleToInstantApps
20877 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20880 boolean instantApp;
20881 synchronized(this) {
20882 if (caller != null) {
20883 callerApp = getRecordForAppLocked(caller);
20884 if (callerApp == null) {
20885 throw new SecurityException(
20886 "Unable to find app for caller " + caller
20887 + " (pid=" + Binder.getCallingPid()
20888 + ") when registering receiver " + receiver);
20890 if (callerApp.info.uid != SYSTEM_UID &&
20891 !callerApp.pkgList.containsKey(callerPackage) &&
20892 !"android".equals(callerPackage)) {
20893 throw new SecurityException("Given caller package " + callerPackage
20894 + " is not running in process " + callerApp);
20896 callingUid = callerApp.info.uid;
20897 callingPid = callerApp.pid;
20899 callerPackage = null;
20900 callingUid = Binder.getCallingUid();
20901 callingPid = Binder.getCallingPid();
20904 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20905 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20906 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20908 Iterator<String> actions = filter.actionsIterator();
20909 if (actions == null) {
20910 ArrayList<String> noAction = new ArrayList<String>(1);
20911 noAction.add(null);
20912 actions = noAction.iterator();
20915 // Collect stickies of users
20916 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20917 while (actions.hasNext()) {
20918 String action = actions.next();
20919 for (int id : userIds) {
20920 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20921 if (stickies != null) {
20922 ArrayList<Intent> intents = stickies.get(action);
20923 if (intents != null) {
20924 if (stickyIntents == null) {
20925 stickyIntents = new ArrayList<Intent>();
20927 stickyIntents.addAll(intents);
20934 ArrayList<Intent> allSticky = null;
20935 if (stickyIntents != null) {
20936 final ContentResolver resolver = mContext.getContentResolver();
20937 // Look for any matching sticky broadcasts...
20938 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20939 Intent intent = stickyIntents.get(i);
20940 // Don't provided intents that aren't available to instant apps.
20942 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20945 // If intent has scheme "content", it will need to acccess
20946 // provider that needs to lock mProviderMap in ActivityThread
20947 // and also it may need to wait application response, so we
20948 // cannot lock ActivityManagerService here.
20949 if (filter.match(resolver, intent, true, TAG) >= 0) {
20950 if (allSticky == null) {
20951 allSticky = new ArrayList<Intent>();
20953 allSticky.add(intent);
20958 // The first sticky in the list is returned directly back to the client.
20959 Intent sticky = allSticky != null ? allSticky.get(0) : null;
20960 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20961 if (receiver == null) {
20965 synchronized (this) {
20966 if (callerApp != null && (callerApp.thread == null
20967 || callerApp.thread.asBinder() != caller.asBinder())) {
20968 // Original caller already died
20971 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20973 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
20975 if (rl.app != null) {
20976 final int totalReceiversForApp = rl.app.receivers.size();
20977 if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
20978 throw new IllegalStateException("Too many receivers, total of "
20979 + totalReceiversForApp + ", registered for pid: "
20980 + rl.pid + ", callerPackage: " + callerPackage);
20982 rl.app.receivers.add(rl);
20985 receiver.asBinder().linkToDeath(rl, 0);
20986 } catch (RemoteException e) {
20989 rl.linkedToDeath = true;
20991 mRegisteredReceivers.put(receiver.asBinder(), rl);
20992 } else if (rl.uid != callingUid) {
20993 throw new IllegalArgumentException(
20994 "Receiver requested to register for uid " + callingUid
20995 + " was previously registered for uid " + rl.uid
20996 + " callerPackage is " + callerPackage);
20997 } else if (rl.pid != callingPid) {
20998 throw new IllegalArgumentException(
20999 "Receiver requested to register for pid " + callingPid
21000 + " was previously registered for pid " + rl.pid
21001 + " callerPackage is " + callerPackage);
21002 } else if (rl.userId != userId) {
21003 throw new IllegalArgumentException(
21004 "Receiver requested to register for user " + userId
21005 + " was previously registered for user " + rl.userId
21006 + " callerPackage is " + callerPackage);
21008 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
21009 permission, callingUid, userId, instantApp, visibleToInstantApps);
21010 if (rl.containsFilter(filter)) {
21011 Slog.w(TAG, "Receiver with filter " + filter
21012 + " already registered for pid " + rl.pid
21013 + ", callerPackage is " + callerPackage);
21016 if (!bf.debugCheck()) {
21017 Slog.w(TAG, "==> For Dynamic broadcast");
21019 mReceiverResolver.addFilter(bf);
21022 // Enqueue broadcasts for all existing stickies that match
21024 if (allSticky != null) {
21025 ArrayList receivers = new ArrayList();
21028 final int stickyCount = allSticky.size();
21029 for (int i = 0; i < stickyCount; i++) {
21030 Intent intent = allSticky.get(i);
21031 BroadcastQueue queue = broadcastQueueForIntent(intent);
21032 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
21033 null, -1, -1, false, null, null, OP_NONE, null, receivers,
21034 null, 0, null, null, false, true, true, -1);
21035 queue.enqueueParallelBroadcastLocked(r);
21036 queue.scheduleBroadcastsLocked();
21044 public void unregisterReceiver(IIntentReceiver receiver) {
21045 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
21047 final long origId = Binder.clearCallingIdentity();
21049 boolean doTrim = false;
21051 synchronized(this) {
21052 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
21054 final BroadcastRecord r = rl.curBroadcast;
21055 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
21056 final boolean doNext = r.queue.finishReceiverLocked(
21057 r, r.resultCode, r.resultData, r.resultExtras,
21058 r.resultAbort, false);
21061 r.queue.processNextBroadcast(false);
21065 if (rl.app != null) {
21066 rl.app.receivers.remove(rl);
21068 removeReceiverLocked(rl);
21069 if (rl.linkedToDeath) {
21070 rl.linkedToDeath = false;
21071 rl.receiver.asBinder().unlinkToDeath(rl, 0);
21076 // If we actually concluded any broadcasts, we might now be able
21077 // to trim the recipients' apps from our working set
21079 trimApplications();
21084 Binder.restoreCallingIdentity(origId);
21088 void removeReceiverLocked(ReceiverList rl) {
21089 mRegisteredReceivers.remove(rl.receiver.asBinder());
21090 for (int i = rl.size() - 1; i >= 0; i--) {
21091 mReceiverResolver.removeFilter(rl.get(i));
21095 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
21096 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21097 ProcessRecord r = mLruProcesses.get(i);
21098 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
21100 r.thread.dispatchPackageBroadcast(cmd, packages);
21101 } catch (RemoteException ex) {
21107 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
21108 int callingUid, int[] users) {
21109 // TODO: come back and remove this assumption to triage all broadcasts
21110 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
21112 List<ResolveInfo> receivers = null;
21114 HashSet<ComponentName> singleUserReceivers = null;
21115 boolean scannedFirstReceivers = false;
21116 for (int user : users) {
21117 // Skip users that have Shell restrictions, with exception of always permitted
21118 // Shell broadcasts
21119 if (callingUid == SHELL_UID
21120 && mUserController.hasUserRestriction(
21121 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
21122 && !isPermittedShellBroadcast(intent)) {
21125 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
21126 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
21127 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
21128 // If this is not the system user, we need to check for
21129 // any receivers that should be filtered out.
21130 for (int i=0; i<newReceivers.size(); i++) {
21131 ResolveInfo ri = newReceivers.get(i);
21132 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
21133 newReceivers.remove(i);
21138 if (newReceivers != null && newReceivers.size() == 0) {
21139 newReceivers = null;
21141 if (receivers == null) {
21142 receivers = newReceivers;
21143 } else if (newReceivers != null) {
21144 // We need to concatenate the additional receivers
21145 // found with what we have do far. This would be easy,
21146 // but we also need to de-dup any receivers that are
21148 if (!scannedFirstReceivers) {
21149 // Collect any single user receivers we had already retrieved.
21150 scannedFirstReceivers = true;
21151 for (int i=0; i<receivers.size(); i++) {
21152 ResolveInfo ri = receivers.get(i);
21153 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21154 ComponentName cn = new ComponentName(
21155 ri.activityInfo.packageName, ri.activityInfo.name);
21156 if (singleUserReceivers == null) {
21157 singleUserReceivers = new HashSet<ComponentName>();
21159 singleUserReceivers.add(cn);
21163 // Add the new results to the existing results, tracking
21164 // and de-dupping single user receivers.
21165 for (int i=0; i<newReceivers.size(); i++) {
21166 ResolveInfo ri = newReceivers.get(i);
21167 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21168 ComponentName cn = new ComponentName(
21169 ri.activityInfo.packageName, ri.activityInfo.name);
21170 if (singleUserReceivers == null) {
21171 singleUserReceivers = new HashSet<ComponentName>();
21173 if (!singleUserReceivers.contains(cn)) {
21174 singleUserReceivers.add(cn);
21183 } catch (RemoteException ex) {
21184 // pm is in same process, this will never happen.
21189 private boolean isPermittedShellBroadcast(Intent intent) {
21190 // remote bugreport should always be allowed to be taken
21191 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
21194 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
21195 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
21196 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21197 // Don't yell about broadcasts sent via shell
21201 final String action = intent.getAction();
21202 if (isProtectedBroadcast
21203 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
21204 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
21205 || Intent.ACTION_MEDIA_BUTTON.equals(action)
21206 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
21207 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
21208 || Intent.ACTION_MASTER_CLEAR.equals(action)
21209 || Intent.ACTION_FACTORY_RESET.equals(action)
21210 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21211 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
21212 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
21213 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
21214 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
21215 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
21216 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
21217 // Broadcast is either protected, or it's a public action that
21218 // we've relaxed, so it's fine for system internals to send.
21222 // This broadcast may be a problem... but there are often system components that
21223 // want to send an internal broadcast to themselves, which is annoying to have to
21224 // explicitly list each action as a protected broadcast, so we will check for that
21225 // one safe case and allow it: an explicit broadcast, only being received by something
21226 // that has protected itself.
21227 if (intent.getPackage() != null || intent.getComponent() != null) {
21228 if (receivers == null || receivers.size() == 0) {
21229 // Intent is explicit and there's no receivers.
21230 // This happens, e.g. , when a system component sends a broadcast to
21231 // its own runtime receiver, and there's no manifest receivers for it,
21232 // because this method is called twice for each broadcast,
21233 // for runtime receivers and manifest receivers and the later check would find
21237 boolean allProtected = true;
21238 for (int i = receivers.size()-1; i >= 0; i--) {
21239 Object target = receivers.get(i);
21240 if (target instanceof ResolveInfo) {
21241 ResolveInfo ri = (ResolveInfo)target;
21242 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
21243 allProtected = false;
21247 BroadcastFilter bf = (BroadcastFilter)target;
21248 if (bf.requiredPermission == null) {
21249 allProtected = false;
21254 if (allProtected) {
21260 // The vast majority of broadcasts sent from system internals
21261 // should be protected to avoid security holes, so yell loudly
21262 // to ensure we examine these cases.
21263 if (callerApp != null) {
21264 Log.wtf(TAG, "Sending non-protected broadcast " + action
21265 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
21268 Log.wtf(TAG, "Sending non-protected broadcast " + action
21269 + " from system uid " + UserHandle.formatUid(callingUid)
21270 + " pkg " + callerPackage,
21276 final int broadcastIntentLocked(ProcessRecord callerApp,
21277 String callerPackage, Intent intent, String resolvedType,
21278 IIntentReceiver resultTo, int resultCode, String resultData,
21279 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
21280 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
21281 intent = new Intent(intent);
21283 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
21284 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
21285 if (callerInstantApp) {
21286 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21289 // By default broadcasts do not go to stopped apps.
21290 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
21292 // If we have not finished booting, don't allow this to launch new processes.
21293 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
21294 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21297 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
21298 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
21299 + " ordered=" + ordered + " userid=" + userId);
21300 if ((resultTo != null) && !ordered) {
21301 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
21304 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
21305 ALLOW_NON_FULL, "broadcast", callerPackage);
21307 // Make sure that the user who is receiving this broadcast or its parent is running.
21308 // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
21309 if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
21310 if ((callingUid != SYSTEM_UID
21311 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
21312 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
21313 Slog.w(TAG, "Skipping broadcast of " + intent
21314 + ": user " + userId + " and its parent (if any) are stopped");
21315 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
21319 final String action = intent.getAction();
21320 BroadcastOptions brOptions = null;
21321 if (bOptions != null) {
21322 brOptions = new BroadcastOptions(bOptions);
21323 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
21324 // See if the caller is allowed to do this. Note we are checking against
21325 // the actual real caller (not whoever provided the operation as say a
21326 // PendingIntent), because that who is actually supplied the arguments.
21327 if (checkComponentPermission(
21328 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
21329 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
21330 != PackageManager.PERMISSION_GRANTED) {
21331 String msg = "Permission Denial: " + intent.getAction()
21332 + " broadcast from " + callerPackage + " (pid=" + callingPid
21333 + ", uid=" + callingUid + ")"
21335 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21337 throw new SecurityException(msg);
21340 if (brOptions.isDontSendToRestrictedApps()
21341 && !isUidActiveLocked(callingUid)
21342 && isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
21343 Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage
21344 + " has background restrictions");
21345 return ActivityManager.START_CANCELED;
21349 // Verify that protected broadcasts are only being sent by system code,
21350 // and that system code is only sending protected broadcasts.
21351 final boolean isProtectedBroadcast;
21353 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
21354 } catch (RemoteException e) {
21355 Slog.w(TAG, "Remote exception", e);
21356 return ActivityManager.BROADCAST_SUCCESS;
21359 final boolean isCallerSystem;
21360 switch (UserHandle.getAppId(callingUid)) {
21364 case BLUETOOTH_UID:
21367 isCallerSystem = true;
21370 isCallerSystem = (callerApp != null) && callerApp.persistent;
21374 // First line security check before anything else: stop non-system apps from
21375 // sending protected broadcasts.
21376 if (!isCallerSystem) {
21377 if (isProtectedBroadcast) {
21378 String msg = "Permission Denial: not allowed to send broadcast "
21379 + action + " from pid="
21380 + callingPid + ", uid=" + callingUid;
21382 throw new SecurityException(msg);
21384 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21385 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
21386 // Special case for compatibility: we don't want apps to send this,
21387 // but historically it has not been protected and apps may be using it
21388 // to poke their own app widget. So, instead of making it protected,
21389 // just limit it to the caller.
21390 if (callerPackage == null) {
21391 String msg = "Permission Denial: not allowed to send broadcast "
21392 + action + " from unknown caller.";
21394 throw new SecurityException(msg);
21395 } else if (intent.getComponent() != null) {
21396 // They are good enough to send to an explicit component... verify
21397 // it is being sent to the calling app.
21398 if (!intent.getComponent().getPackageName().equals(
21400 String msg = "Permission Denial: not allowed to send broadcast "
21402 + intent.getComponent().getPackageName() + " from "
21405 throw new SecurityException(msg);
21408 // Limit broadcast to their own package.
21409 intent.setPackage(callerPackage);
21414 if (action != null) {
21415 if (getBackgroundLaunchBroadcasts().contains(action)) {
21416 if (DEBUG_BACKGROUND_CHECK) {
21417 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
21419 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
21423 case Intent.ACTION_UID_REMOVED:
21424 case Intent.ACTION_PACKAGE_REMOVED:
21425 case Intent.ACTION_PACKAGE_CHANGED:
21426 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21427 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21428 case Intent.ACTION_PACKAGES_SUSPENDED:
21429 case Intent.ACTION_PACKAGES_UNSUSPENDED:
21430 // Handle special intents: if this broadcast is from the package
21431 // manager about a package being removed, we need to remove all of
21432 // its activities from the history stack.
21433 if (checkComponentPermission(
21434 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
21435 callingPid, callingUid, -1, true)
21436 != PackageManager.PERMISSION_GRANTED) {
21437 String msg = "Permission Denial: " + intent.getAction()
21438 + " broadcast from " + callerPackage + " (pid=" + callingPid
21439 + ", uid=" + callingUid + ")"
21441 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
21443 throw new SecurityException(msg);
21446 case Intent.ACTION_UID_REMOVED:
21447 final int uid = getUidFromIntent(intent);
21449 mBatteryStatsService.removeUid(uid);
21450 mAppOpsService.uidRemoved(uid);
21453 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21454 // If resources are unavailable just force stop all those packages
21455 // and flush the attribute cache as well.
21457 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21458 if (list != null && list.length > 0) {
21459 for (int i = 0; i < list.length; i++) {
21460 forceStopPackageLocked(list[i], -1, false, true, true,
21461 false, false, userId, "storage unmount");
21463 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21464 sendPackageBroadcastLocked(
21465 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
21469 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21470 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21472 case Intent.ACTION_PACKAGE_REMOVED:
21473 case Intent.ACTION_PACKAGE_CHANGED:
21474 Uri data = intent.getData();
21476 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
21477 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
21478 final boolean replacing =
21479 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21480 final boolean killProcess =
21481 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
21482 final boolean fullUninstall = removed && !replacing;
21485 forceStopPackageLocked(ssp, UserHandle.getAppId(
21486 intent.getIntExtra(Intent.EXTRA_UID, -1)),
21487 false, true, true, false, fullUninstall, userId,
21488 removed ? "pkg removed" : "pkg changed");
21490 final int cmd = killProcess
21491 ? ApplicationThreadConstants.PACKAGE_REMOVED
21492 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
21493 sendPackageBroadcastLocked(cmd,
21494 new String[] {ssp}, userId);
21495 if (fullUninstall) {
21496 mAppOpsService.packageRemoved(
21497 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
21499 // Remove all permissions granted from/to this package
21500 removeUriPermissionsForPackageLocked(ssp, userId, true,
21503 mRecentTasks.removeTasksByPackageName(ssp, userId);
21505 mServices.forceStopPackageLocked(ssp, userId);
21506 mAppWarnings.onPackageUninstalled(ssp);
21507 mCompatModePackages.handlePackageUninstalledLocked(ssp);
21508 mBatteryStatsService.notePackageUninstalled(ssp);
21512 killPackageProcessesLocked(ssp, UserHandle.getAppId(
21513 intent.getIntExtra(Intent.EXTRA_UID, -1)),
21514 userId, ProcessList.INVALID_ADJ,
21515 false, true, true, false, "change " + ssp);
21517 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
21518 intent.getStringArrayExtra(
21519 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
21523 case Intent.ACTION_PACKAGES_SUSPENDED:
21524 case Intent.ACTION_PACKAGES_UNSUSPENDED:
21525 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
21526 intent.getAction());
21527 final String[] packageNames = intent.getStringArrayExtra(
21528 Intent.EXTRA_CHANGED_PACKAGE_LIST);
21529 final int userHandle = intent.getIntExtra(
21530 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
21532 synchronized(ActivityManagerService.this) {
21533 mRecentTasks.onPackagesSuspendedChanged(
21534 packageNames, suspended, userHandle);
21539 case Intent.ACTION_PACKAGE_REPLACED:
21541 final Uri data = intent.getData();
21543 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21544 ApplicationInfo aInfo = null;
21546 aInfo = AppGlobals.getPackageManager()
21547 .getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
21548 } catch (RemoteException ignore) {}
21549 if (aInfo == null) {
21550 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
21551 + " ssp=" + ssp + " data=" + data);
21552 return ActivityManager.BROADCAST_SUCCESS;
21554 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
21555 mServices.updateServiceApplicationInfoLocked(aInfo);
21556 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
21557 new String[] {ssp}, userId);
21561 case Intent.ACTION_PACKAGE_ADDED:
21563 // Special case for adding a package: by default turn on compatibility mode.
21564 Uri data = intent.getData();
21566 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21567 final boolean replacing =
21568 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21569 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
21572 ApplicationInfo ai = AppGlobals.getPackageManager().
21573 getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
21574 mBatteryStatsService.notePackageInstalled(ssp,
21575 ai != null ? ai.versionCode : 0);
21576 } catch (RemoteException e) {
21581 case Intent.ACTION_PACKAGE_DATA_CLEARED:
21583 Uri data = intent.getData();
21585 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21586 mCompatModePackages.handlePackageDataClearedLocked(ssp);
21587 mAppWarnings.onPackageDataCleared(ssp);
21591 case Intent.ACTION_TIMEZONE_CHANGED:
21592 // If this is the time zone changed action, queue up a message that will reset
21593 // the timezone of all currently running processes. This message will get
21594 // queued up before the broadcast happens.
21595 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
21597 case Intent.ACTION_TIME_CHANGED:
21598 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
21599 // the tri-state value it may contain and "unknown".
21600 // For convenience we re-use the Intent extra values.
21601 final int NO_EXTRA_VALUE_FOUND = -1;
21602 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
21603 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
21604 NO_EXTRA_VALUE_FOUND /* defaultValue */);
21605 // Only send a message if the time preference is available.
21606 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
21607 Message updateTimePreferenceMsg =
21608 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
21609 timeFormatPreferenceMsgValue, 0);
21610 mHandler.sendMessage(updateTimePreferenceMsg);
21612 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21613 synchronized (stats) {
21614 stats.noteCurrentTimeChangedLocked();
21617 case Intent.ACTION_CLEAR_DNS_CACHE:
21618 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
21620 case Proxy.PROXY_CHANGE_ACTION:
21621 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
21622 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
21624 case android.hardware.Camera.ACTION_NEW_PICTURE:
21625 case android.hardware.Camera.ACTION_NEW_VIDEO:
21626 // In N we just turned these off; in O we are turing them back on partly,
21627 // only for registered receivers. This will still address the main problem
21628 // (a spam of apps waking up when a picture is taken putting significant
21629 // memory pressure on the system at a bad point), while still allowing apps
21630 // that are already actively running to know about this happening.
21631 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21633 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
21634 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
21636 case "com.android.launcher.action.INSTALL_SHORTCUT":
21637 // As of O, we no longer support this broadcasts, even for pre-O apps.
21638 // Apps should now be using ShortcutManager.pinRequestShortcut().
21639 Log.w(TAG, "Broadcast " + action
21640 + " no longer supported. It will not be delivered.");
21641 return ActivityManager.BROADCAST_SUCCESS;
21644 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
21645 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
21646 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
21647 final int uid = getUidFromIntent(intent);
21649 final UidRecord uidRec = mActiveUids.get(uid);
21650 if (uidRec != null) {
21651 uidRec.updateHasInternetPermission();
21657 // Add to the sticky list if requested.
21659 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
21660 callingPid, callingUid)
21661 != PackageManager.PERMISSION_GRANTED) {
21662 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
21663 + callingPid + ", uid=" + callingUid
21664 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21666 throw new SecurityException(msg);
21668 if (requiredPermissions != null && requiredPermissions.length > 0) {
21669 Slog.w(TAG, "Can't broadcast sticky intent " + intent
21670 + " and enforce permissions " + Arrays.toString(requiredPermissions));
21671 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
21673 if (intent.getComponent() != null) {
21674 throw new SecurityException(
21675 "Sticky broadcasts can't target a specific component");
21677 // We use userId directly here, since the "all" target is maintained
21678 // as a separate set of sticky broadcasts.
21679 if (userId != UserHandle.USER_ALL) {
21680 // But first, if this is not a broadcast to all users, then
21681 // make sure it doesn't conflict with an existing broadcast to
21683 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
21684 UserHandle.USER_ALL);
21685 if (stickies != null) {
21686 ArrayList<Intent> list = stickies.get(intent.getAction());
21687 if (list != null) {
21688 int N = list.size();
21690 for (i=0; i<N; i++) {
21691 if (intent.filterEquals(list.get(i))) {
21692 throw new IllegalArgumentException(
21693 "Sticky broadcast " + intent + " for user "
21694 + userId + " conflicts with existing global broadcast");
21700 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21701 if (stickies == null) {
21702 stickies = new ArrayMap<>();
21703 mStickyBroadcasts.put(userId, stickies);
21705 ArrayList<Intent> list = stickies.get(intent.getAction());
21706 if (list == null) {
21707 list = new ArrayList<>();
21708 stickies.put(intent.getAction(), list);
21710 final int stickiesCount = list.size();
21712 for (i = 0; i < stickiesCount; i++) {
21713 if (intent.filterEquals(list.get(i))) {
21714 // This sticky already exists, replace it.
21715 list.set(i, new Intent(intent));
21719 if (i >= stickiesCount) {
21720 list.add(new Intent(intent));
21725 if (userId == UserHandle.USER_ALL) {
21726 // Caller wants broadcast to go to all started users.
21727 users = mUserController.getStartedUserArray();
21729 // Caller wants broadcast to go to one specific user.
21730 users = new int[] {userId};
21733 // Figure out who all will receive this broadcast.
21734 List receivers = null;
21735 List<BroadcastFilter> registeredReceivers = null;
21736 // Need to resolve the intent to interested receivers...
21737 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21739 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21741 if (intent.getComponent() == null) {
21742 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21743 // Query one target user at a time, excluding shell-restricted users
21744 for (int i = 0; i < users.length; i++) {
21745 if (mUserController.hasUserRestriction(
21746 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21749 List<BroadcastFilter> registeredReceiversForUser =
21750 mReceiverResolver.queryIntent(intent,
21751 resolvedType, false /*defaultOnly*/, users[i]);
21752 if (registeredReceivers == null) {
21753 registeredReceivers = registeredReceiversForUser;
21754 } else if (registeredReceiversForUser != null) {
21755 registeredReceivers.addAll(registeredReceiversForUser);
21759 registeredReceivers = mReceiverResolver.queryIntent(intent,
21760 resolvedType, false /*defaultOnly*/, userId);
21764 final boolean replacePending =
21765 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21767 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21768 + " replacePending=" + replacePending);
21770 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21771 if (!ordered && NR > 0) {
21772 // If we are not serializing this broadcast, then send the
21773 // registered receivers separately so they don't wait for the
21774 // components to be launched.
21775 if (isCallerSystem) {
21776 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21777 isProtectedBroadcast, registeredReceivers);
21779 final BroadcastQueue queue = broadcastQueueForIntent(intent);
21780 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21781 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21782 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21783 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21784 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21785 final boolean replaced = replacePending
21786 && (queue.replaceParallelBroadcastLocked(r) != null);
21787 // Note: We assume resultTo is null for non-ordered broadcasts.
21789 queue.enqueueParallelBroadcastLocked(r);
21790 queue.scheduleBroadcastsLocked();
21792 registeredReceivers = null;
21796 // Merge into one list.
21798 if (receivers != null) {
21799 // A special case for PACKAGE_ADDED: do not allow the package
21800 // being added to see this broadcast. This prevents them from
21801 // using this as a back door to get run as soon as they are
21802 // installed. Maybe in the future we want to have a special install
21803 // broadcast or such for apps, but we'd like to deliberately make
21805 String skipPackages[] = null;
21806 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21807 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21808 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21809 Uri data = intent.getData();
21810 if (data != null) {
21811 String pkgName = data.getSchemeSpecificPart();
21812 if (pkgName != null) {
21813 skipPackages = new String[] { pkgName };
21816 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21817 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21819 if (skipPackages != null && (skipPackages.length > 0)) {
21820 for (String skipPackage : skipPackages) {
21821 if (skipPackage != null) {
21822 int NT = receivers.size();
21823 for (int it=0; it<NT; it++) {
21824 ResolveInfo curt = (ResolveInfo)receivers.get(it);
21825 if (curt.activityInfo.packageName.equals(skipPackage)) {
21826 receivers.remove(it);
21835 int NT = receivers != null ? receivers.size() : 0;
21837 ResolveInfo curt = null;
21838 BroadcastFilter curr = null;
21839 while (it < NT && ir < NR) {
21840 if (curt == null) {
21841 curt = (ResolveInfo)receivers.get(it);
21843 if (curr == null) {
21844 curr = registeredReceivers.get(ir);
21846 if (curr.getPriority() >= curt.priority) {
21847 // Insert this broadcast record into the final list.
21848 receivers.add(it, curr);
21854 // Skip to the next ResolveInfo in the final list.
21861 if (receivers == null) {
21862 receivers = new ArrayList();
21864 receivers.add(registeredReceivers.get(ir));
21868 if (isCallerSystem) {
21869 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21870 isProtectedBroadcast, receivers);
21873 if ((receivers != null && receivers.size() > 0)
21874 || resultTo != null) {
21875 BroadcastQueue queue = broadcastQueueForIntent(intent);
21876 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21877 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21878 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21879 resultData, resultExtras, ordered, sticky, false, userId);
21881 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21882 + ": prev had " + queue.mOrderedBroadcasts.size());
21883 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21884 "Enqueueing broadcast " + r.intent.getAction());
21886 final BroadcastRecord oldRecord =
21887 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21888 if (oldRecord != null) {
21889 // Replaced, fire the result-to receiver.
21890 if (oldRecord.resultTo != null) {
21891 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21893 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21895 Activity.RESULT_CANCELED, null, null,
21896 false, false, oldRecord.userId);
21897 } catch (RemoteException e) {
21898 Slog.w(TAG, "Failure ["
21899 + queue.mQueueName + "] sending broadcast result of "
21905 queue.enqueueOrderedBroadcastLocked(r);
21906 queue.scheduleBroadcastsLocked();
21909 // There was nobody interested in the broadcast, but we still want to record
21910 // that it happened.
21911 if (intent.getComponent() == null && intent.getPackage() == null
21912 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21913 // This was an implicit broadcast... let's record it for posterity.
21914 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21918 return ActivityManager.BROADCAST_SUCCESS;
21922 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21924 private int getUidFromIntent(Intent intent) {
21925 if (intent == null) {
21928 final Bundle intentExtras = intent.getExtras();
21929 return intent.hasExtra(Intent.EXTRA_UID)
21930 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21933 final void rotateBroadcastStatsIfNeededLocked() {
21934 final long now = SystemClock.elapsedRealtime();
21935 if (mCurBroadcastStats == null ||
21936 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21937 mLastBroadcastStats = mCurBroadcastStats;
21938 if (mLastBroadcastStats != null) {
21939 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21940 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21942 mCurBroadcastStats = new BroadcastStats();
21946 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21947 int skipCount, long dispatchTime) {
21948 rotateBroadcastStatsIfNeededLocked();
21949 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21952 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21953 rotateBroadcastStatsIfNeededLocked();
21954 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21957 final Intent verifyBroadcastLocked(Intent intent) {
21958 // Refuse possible leaked file descriptors
21959 if (intent != null && intent.hasFileDescriptors() == true) {
21960 throw new IllegalArgumentException("File descriptors passed in Intent");
21963 int flags = intent.getFlags();
21965 if (!mProcessesReady) {
21966 // if the caller really truly claims to know what they're doing, go
21967 // ahead and allow the broadcast without launching any receivers
21968 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
21969 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
21970 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21971 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
21972 + " before boot completion");
21973 throw new IllegalStateException("Cannot broadcast before boot completed");
21977 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
21978 throw new IllegalArgumentException(
21979 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
21982 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21983 switch (Binder.getCallingUid()) {
21988 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
21989 + Binder.getCallingUid());
21990 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
21998 public final int broadcastIntent(IApplicationThread caller,
21999 Intent intent, String resolvedType, IIntentReceiver resultTo,
22000 int resultCode, String resultData, Bundle resultExtras,
22001 String[] requiredPermissions, int appOp, Bundle bOptions,
22002 boolean serialized, boolean sticky, int userId) {
22003 enforceNotIsolatedCaller("broadcastIntent");
22004 synchronized(this) {
22005 intent = verifyBroadcastLocked(intent);
22007 final ProcessRecord callerApp = getRecordForAppLocked(caller);
22008 final int callingPid = Binder.getCallingPid();
22009 final int callingUid = Binder.getCallingUid();
22010 final long origId = Binder.clearCallingIdentity();
22011 int res = broadcastIntentLocked(callerApp,
22012 callerApp != null ? callerApp.info.packageName : null,
22013 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
22014 requiredPermissions, appOp, bOptions, serialized, sticky,
22015 callingPid, callingUid, userId);
22016 Binder.restoreCallingIdentity(origId);
22022 int broadcastIntentInPackage(String packageName, int uid,
22023 Intent intent, String resolvedType, IIntentReceiver resultTo,
22024 int resultCode, String resultData, Bundle resultExtras,
22025 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
22027 synchronized(this) {
22028 intent = verifyBroadcastLocked(intent);
22030 final long origId = Binder.clearCallingIdentity();
22031 String[] requiredPermissions = requiredPermission == null ? null
22032 : new String[] {requiredPermission};
22033 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
22034 resultTo, resultCode, resultData, resultExtras,
22035 requiredPermissions, OP_NONE, bOptions, serialized,
22036 sticky, -1, uid, userId);
22037 Binder.restoreCallingIdentity(origId);
22042 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
22043 // Refuse possible leaked file descriptors
22044 if (intent != null && intent.hasFileDescriptors() == true) {
22045 throw new IllegalArgumentException("File descriptors passed in Intent");
22048 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22049 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
22051 synchronized(this) {
22052 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
22053 != PackageManager.PERMISSION_GRANTED) {
22054 String msg = "Permission Denial: unbroadcastIntent() from pid="
22055 + Binder.getCallingPid()
22056 + ", uid=" + Binder.getCallingUid()
22057 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
22059 throw new SecurityException(msg);
22061 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
22062 if (stickies != null) {
22063 ArrayList<Intent> list = stickies.get(intent.getAction());
22064 if (list != null) {
22065 int N = list.size();
22067 for (i=0; i<N; i++) {
22068 if (intent.filterEquals(list.get(i))) {
22073 if (list.size() <= 0) {
22074 stickies.remove(intent.getAction());
22077 if (stickies.size() <= 0) {
22078 mStickyBroadcasts.remove(userId);
22084 void backgroundServicesFinishedLocked(int userId) {
22085 for (BroadcastQueue queue : mBroadcastQueues) {
22086 queue.backgroundServicesFinishedLocked(userId);
22090 public void finishReceiver(IBinder who, int resultCode, String resultData,
22091 Bundle resultExtras, boolean resultAbort, int flags) {
22092 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
22094 // Refuse possible leaked file descriptors
22095 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
22096 throw new IllegalArgumentException("File descriptors passed in Bundle");
22099 final long origId = Binder.clearCallingIdentity();
22101 boolean doNext = false;
22104 synchronized(this) {
22105 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
22106 ? mFgBroadcastQueue : mBgBroadcastQueue;
22107 r = queue.getMatchingOrderedReceiver(who);
22109 doNext = r.queue.finishReceiverLocked(r, resultCode,
22110 resultData, resultExtras, resultAbort, true);
22113 r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
22115 // updateOomAdjLocked() will be done here
22116 trimApplicationsLocked();
22120 Binder.restoreCallingIdentity(origId);
22124 // =========================================================
22126 // =========================================================
22128 public boolean startInstrumentation(ComponentName className,
22129 String profileFile, int flags, Bundle arguments,
22130 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
22131 int userId, String abiOverride) {
22132 enforceNotIsolatedCaller("startInstrumentation");
22133 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22134 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
22135 // Refuse possible leaked file descriptors
22136 if (arguments != null && arguments.hasFileDescriptors()) {
22137 throw new IllegalArgumentException("File descriptors passed in Bundle");
22140 synchronized(this) {
22141 InstrumentationInfo ii = null;
22142 ApplicationInfo ai = null;
22144 ii = mContext.getPackageManager().getInstrumentationInfo(
22145 className, STOCK_PM_FLAGS);
22146 ai = AppGlobals.getPackageManager().getApplicationInfo(
22147 ii.targetPackage, STOCK_PM_FLAGS, userId);
22148 } catch (PackageManager.NameNotFoundException e) {
22149 } catch (RemoteException e) {
22152 reportStartInstrumentationFailureLocked(watcher, className,
22153 "Unable to find instrumentation info for: " + className);
22157 reportStartInstrumentationFailureLocked(watcher, className,
22158 "Unable to find instrumentation target package: " + ii.targetPackage);
22161 if (!ai.hasCode()) {
22162 reportStartInstrumentationFailureLocked(watcher, className,
22163 "Instrumentation target has no code: " + ii.targetPackage);
22167 int match = mContext.getPackageManager().checkSignatures(
22168 ii.targetPackage, ii.packageName);
22169 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
22170 String msg = "Permission Denial: starting instrumentation "
22171 + className + " from pid="
22172 + Binder.getCallingPid()
22173 + ", uid=" + Binder.getCallingPid()
22174 + " not allowed because package " + ii.packageName
22175 + " does not have a signature matching the target "
22176 + ii.targetPackage;
22177 reportStartInstrumentationFailureLocked(watcher, className, msg);
22178 throw new SecurityException(msg);
22181 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
22182 activeInstr.mClass = className;
22183 String defProcess = ai.processName;;
22184 if (ii.targetProcesses == null) {
22185 activeInstr.mTargetProcesses = new String[]{ai.processName};
22186 } else if (ii.targetProcesses.equals("*")) {
22187 activeInstr.mTargetProcesses = new String[0];
22189 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
22190 defProcess = activeInstr.mTargetProcesses[0];
22192 activeInstr.mTargetInfo = ai;
22193 activeInstr.mProfileFile = profileFile;
22194 activeInstr.mArguments = arguments;
22195 activeInstr.mWatcher = watcher;
22196 activeInstr.mUiAutomationConnection = uiAutomationConnection;
22197 activeInstr.mResultClass = className;
22199 boolean disableHiddenApiChecks =
22200 (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
22201 if (disableHiddenApiChecks) {
22202 enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS,
22203 "disable hidden API checks");
22206 final long origId = Binder.clearCallingIdentity();
22207 // Instrumentation can kill and relaunch even persistent processes
22208 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
22210 // Inform usage stats to make the target package active
22211 if (mUsageStatsService != null) {
22212 mUsageStatsService.reportEvent(ii.targetPackage, userId,
22213 UsageEvents.Event.SYSTEM_INTERACTION);
22216 ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
22218 app.instr = activeInstr;
22219 activeInstr.mFinished = false;
22220 activeInstr.mRunningProcesses.add(app);
22221 if (!mActiveInstrumentation.contains(activeInstr)) {
22222 mActiveInstrumentation.add(activeInstr);
22224 Binder.restoreCallingIdentity(origId);
22231 * Report errors that occur while attempting to start Instrumentation. Always writes the
22232 * error to the logs, but if somebody is watching, send the report there too. This enables
22233 * the "am" command to report errors with more information.
22235 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
22236 * @param cn The component name of the instrumentation.
22237 * @param report The error report.
22239 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
22240 ComponentName cn, String report) {
22241 Slog.w(TAG, report);
22242 if (watcher != null) {
22243 Bundle results = new Bundle();
22244 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
22245 results.putString("Error", report);
22246 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
22250 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
22251 if (app.instr == null) {
22252 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22256 if (!app.instr.mFinished && results != null) {
22257 if (app.instr.mCurResults == null) {
22258 app.instr.mCurResults = new Bundle(results);
22260 app.instr.mCurResults.putAll(results);
22265 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
22266 int userId = UserHandle.getCallingUserId();
22267 // Refuse possible leaked file descriptors
22268 if (results != null && results.hasFileDescriptors()) {
22269 throw new IllegalArgumentException("File descriptors passed in Intent");
22272 synchronized(this) {
22273 ProcessRecord app = getRecordForAppLocked(target);
22275 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
22278 final long origId = Binder.clearCallingIdentity();
22279 addInstrumentationResultsLocked(app, results);
22280 Binder.restoreCallingIdentity(origId);
22285 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
22286 if (app.instr == null) {
22287 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22291 if (!app.instr.mFinished) {
22292 if (app.instr.mWatcher != null) {
22293 Bundle finalResults = app.instr.mCurResults;
22294 if (finalResults != null) {
22295 if (app.instr.mCurResults != null && results != null) {
22296 finalResults.putAll(results);
22299 finalResults = results;
22301 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
22302 app.instr.mClass, resultCode, finalResults);
22305 // Can't call out of the system process with a lock held, so post a message.
22306 if (app.instr.mUiAutomationConnection != null) {
22307 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
22308 app.instr.mUiAutomationConnection).sendToTarget();
22310 app.instr.mFinished = true;
22313 app.instr.removeProcess(app);
22316 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
22320 public void finishInstrumentation(IApplicationThread target,
22321 int resultCode, Bundle results) {
22322 int userId = UserHandle.getCallingUserId();
22323 // Refuse possible leaked file descriptors
22324 if (results != null && results.hasFileDescriptors()) {
22325 throw new IllegalArgumentException("File descriptors passed in Intent");
22328 synchronized(this) {
22329 ProcessRecord app = getRecordForAppLocked(target);
22331 Slog.w(TAG, "finishInstrumentation: no app for " + target);
22334 final long origId = Binder.clearCallingIdentity();
22335 finishInstrumentationLocked(app, resultCode, results);
22336 Binder.restoreCallingIdentity(origId);
22340 // =========================================================
22342 // =========================================================
22344 public ConfigurationInfo getDeviceConfigurationInfo() {
22345 ConfigurationInfo config = new ConfigurationInfo();
22346 synchronized (this) {
22347 final Configuration globalConfig = getGlobalConfiguration();
22348 config.reqTouchScreen = globalConfig.touchscreen;
22349 config.reqKeyboardType = globalConfig.keyboard;
22350 config.reqNavigation = globalConfig.navigation;
22351 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
22352 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
22353 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
22355 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
22356 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
22357 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
22359 config.reqGlEsVersion = GL_ES_VERSION;
22364 ActivityStack getFocusedStack() {
22365 return mStackSupervisor.getFocusedStack();
22369 public StackInfo getFocusedStackInfo() throws RemoteException {
22370 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
22371 long ident = Binder.clearCallingIdentity();
22373 synchronized (this) {
22374 ActivityStack focusedStack = getFocusedStack();
22375 if (focusedStack != null) {
22376 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
22381 Binder.restoreCallingIdentity(ident);
22385 public Configuration getConfiguration() {
22387 synchronized(this) {
22388 ci = new Configuration(getGlobalConfiguration());
22389 ci.userSetLocale = false;
22395 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
22396 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
22397 synchronized (this) {
22398 mSuppressResizeConfigChanges = suppress;
22403 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
22404 * animated the stack to the fullscreen, but can also be called if we are relaunching an
22405 * activity and clearing the task at the same time.
22408 // TODO: API should just be about changing windowing modes...
22409 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
22410 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
22411 "moveTasksToFullscreenStack()");
22412 synchronized (this) {
22413 final long origId = Binder.clearCallingIdentity();
22415 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
22416 if (stack != null){
22417 if (!stack.isActivityTypeStandardOrUndefined()) {
22418 throw new IllegalArgumentException(
22419 "You can't move tasks from non-standard stacks.");
22421 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
22424 Binder.restoreCallingIdentity(origId);
22430 public void updatePersistentConfiguration(Configuration values) {
22431 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
22432 enforceWriteSettingsPermission("updatePersistentConfiguration()");
22433 if (values == null) {
22434 throw new NullPointerException("Configuration must not be null");
22437 int userId = UserHandle.getCallingUserId();
22439 synchronized(this) {
22440 updatePersistentConfigurationLocked(values, userId);
22444 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
22445 final long origId = Binder.clearCallingIdentity();
22447 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
22449 Binder.restoreCallingIdentity(origId);
22453 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
22454 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
22455 FONT_SCALE, 1.0f, userId);
22457 synchronized (this) {
22458 if (getGlobalConfiguration().fontScale == scaleFactor) {
22462 final Configuration configuration
22463 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22464 configuration.fontScale = scaleFactor;
22465 updatePersistentConfigurationLocked(configuration, userId);
22469 private void enforceWriteSettingsPermission(String func) {
22470 int uid = Binder.getCallingUid();
22471 if (uid == ROOT_UID) {
22475 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
22476 Settings.getPackageNameForUid(mContext, uid), false)) {
22480 String msg = "Permission Denial: " + func + " from pid="
22481 + Binder.getCallingPid()
22483 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
22485 throw new SecurityException(msg);
22489 public boolean updateConfiguration(Configuration values) {
22490 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
22492 synchronized(this) {
22493 if (values == null && mWindowManager != null) {
22494 // sentinel: fetch the current configuration from the window manager
22495 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22498 if (mWindowManager != null) {
22499 // Update OOM levels based on display size.
22500 mProcessList.applyDisplaySize(mWindowManager);
22503 final long origId = Binder.clearCallingIdentity();
22505 if (values != null) {
22506 Settings.System.clearConfiguration(values);
22508 updateConfigurationLocked(values, null, false, false /* persistent */,
22509 UserHandle.USER_NULL, false /* deferResume */,
22510 mTmpUpdateConfigurationResult);
22511 return mTmpUpdateConfigurationResult.changes != 0;
22513 Binder.restoreCallingIdentity(origId);
22518 void updateUserConfigurationLocked() {
22519 final Configuration configuration = new Configuration(getGlobalConfiguration());
22520 final int currentUserId = mUserController.getCurrentUserId();
22521 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
22522 currentUserId, Settings.System.canWrite(mContext));
22523 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
22524 false /* persistent */, currentUserId, false /* deferResume */);
22527 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22528 boolean initLocale) {
22529 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
22532 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22533 boolean initLocale, boolean deferResume) {
22534 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
22535 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
22536 UserHandle.USER_NULL, deferResume);
22539 // To cache the list of supported system locales
22540 private String[] mSupportedSystemLocales = null;
22542 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22543 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
22544 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
22545 deferResume, null /* result */);
22549 * Do either or both things: (1) change the current configuration, and (2)
22550 * make sure the given activity is running with the (now) current
22551 * configuration. Returns true if the activity has been left running, or
22552 * false if <var>starting</var> is being destroyed to match the new
22555 * @param userId is only used when persistent parameter is set to true to persist configuration
22556 * for that particular user
22558 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22559 boolean initLocale, boolean persistent, int userId, boolean deferResume,
22560 UpdateConfigurationResult result) {
22562 boolean kept = true;
22564 if (mWindowManager != null) {
22565 mWindowManager.deferSurfaceLayout();
22568 if (values != null) {
22569 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
22573 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22575 if (mWindowManager != null) {
22576 mWindowManager.continueSurfaceLayout();
22580 if (result != null) {
22581 result.changes = changes;
22582 result.activityRelaunched = !kept;
22588 * Returns true if this configuration change is interesting enough to send an
22589 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
22591 private static boolean isSplitConfigurationChange(int configDiff) {
22592 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
22595 /** Update default (global) configuration and notify listeners about changes. */
22596 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
22597 boolean persistent, int userId, boolean deferResume) {
22598 mTempConfig.setTo(getGlobalConfiguration());
22599 final int changes = mTempConfig.updateFrom(values);
22600 if (changes == 0) {
22601 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
22602 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
22603 // performDisplayOverrideConfigUpdate in order to send the new display configuration
22604 // (even if there are no actual changes) to unfreeze the window.
22605 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
22609 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
22610 "Updating global configuration to: " + values);
22612 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
22613 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
22617 values.hardKeyboardHidden,
22619 values.keyboardHidden,
22623 values.navigationHidden,
22624 values.orientation,
22625 values.screenHeightDp,
22626 values.screenLayout,
22627 values.screenWidthDp,
22628 values.smallestScreenWidthDp,
22629 values.touchscreen,
22633 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
22634 final LocaleList locales = values.getLocales();
22635 int bestLocaleIndex = 0;
22636 if (locales.size() > 1) {
22637 if (mSupportedSystemLocales == null) {
22638 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
22640 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
22642 SystemProperties.set("persist.sys.locale",
22643 locales.get(bestLocaleIndex).toLanguageTag());
22644 LocaleList.setDefault(locales, bestLocaleIndex);
22645 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
22646 locales.get(bestLocaleIndex)));
22649 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
22650 mTempConfig.seq = mConfigurationSeq;
22652 // Update stored global config and notify everyone about the change.
22653 mStackSupervisor.onConfigurationChanged(mTempConfig);
22655 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
22656 // TODO(multi-display): Update UsageEvents#Event to include displayId.
22657 mUsageStatsService.reportConfigurationChange(mTempConfig,
22658 mUserController.getCurrentUserId());
22660 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
22661 updateShouldShowDialogsLocked(mTempConfig);
22663 AttributeCache ac = AttributeCache.instance();
22665 ac.updateConfiguration(mTempConfig);
22668 // Make sure all resources in our process are updated right now, so that anyone who is going
22669 // to retrieve resource values after we return will be sure to get the new ones. This is
22670 // especially important during boot, where the first config change needs to guarantee all
22671 // resources have that config before following boot code is executed.
22672 mSystemThread.applyConfigurationToResources(mTempConfig);
22674 // We need another copy of global config because we're scheduling some calls instead of
22675 // running them in place. We need to be sure that object we send will be handled unchanged.
22676 final Configuration configCopy = new Configuration(mTempConfig);
22677 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
22678 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
22679 msg.obj = configCopy;
22681 mHandler.sendMessage(msg);
22684 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22685 ProcessRecord app = mLruProcesses.get(i);
22687 if (app.thread != null) {
22688 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
22689 + app.processName + " new config " + configCopy);
22690 mLifecycleManager.scheduleTransaction(app.thread,
22691 ConfigurationChangeItem.obtain(configCopy));
22693 } catch (Exception e) {
22694 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
22698 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
22699 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
22700 | Intent.FLAG_RECEIVER_FOREGROUND
22701 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22702 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22703 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22704 UserHandle.USER_ALL);
22705 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
22706 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
22707 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
22708 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
22709 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22710 if (initLocale || !mProcessesReady) {
22711 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22713 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22714 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22715 UserHandle.USER_ALL);
22718 // Send a broadcast to PackageInstallers if the configuration change is interesting
22719 // for the purposes of installing additional splits.
22720 if (!initLocale && isSplitConfigurationChange(changes)) {
22721 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
22722 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
22723 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
22725 // Typically only app stores will have this permission.
22726 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
22727 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
22728 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
22731 // Override configuration of the default display duplicates global config, so we need to
22732 // update it also. This will also notify WindowManager about changes.
22733 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
22740 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22741 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
22743 synchronized (this) {
22744 // Check if display is initialized in AM.
22745 if (!mStackSupervisor.isDisplayAdded(displayId)) {
22746 // Call might come when display is not yet added or has already been removed.
22747 if (DEBUG_CONFIGURATION) {
22748 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
22754 if (values == null && mWindowManager != null) {
22755 // sentinel: fetch the current configuration from the window manager
22756 values = mWindowManager.computeNewConfiguration(displayId);
22759 if (mWindowManager != null) {
22760 // Update OOM levels based on display size.
22761 mProcessList.applyDisplaySize(mWindowManager);
22764 final long origId = Binder.clearCallingIdentity();
22766 if (values != null) {
22767 Settings.System.clearConfiguration(values);
22769 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22770 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22771 return mTmpUpdateConfigurationResult.changes != 0;
22773 Binder.restoreCallingIdentity(origId);
22778 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22779 boolean deferResume, int displayId) {
22780 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22781 displayId, null /* result */);
22785 * Updates override configuration specific for the selected display. If no config is provided,
22786 * new one will be computed in WM based on current display info.
22788 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22789 ActivityRecord starting, boolean deferResume, int displayId,
22790 UpdateConfigurationResult result) {
22792 boolean kept = true;
22794 if (mWindowManager != null) {
22795 mWindowManager.deferSurfaceLayout();
22798 if (values != null) {
22799 if (displayId == DEFAULT_DISPLAY) {
22800 // Override configuration of the default display duplicates global config, so
22801 // we're calling global config update instead for default display. It will also
22802 // apply the correct override config.
22803 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
22804 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22806 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22810 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22812 if (mWindowManager != null) {
22813 mWindowManager.continueSurfaceLayout();
22817 if (result != null) {
22818 result.changes = changes;
22819 result.activityRelaunched = !kept;
22824 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22826 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22827 final int changes = mTempConfig.updateFrom(values);
22828 if (changes != 0) {
22829 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22830 + mTempConfig + " for displayId=" + displayId);
22831 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22833 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22834 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22835 mAppWarnings.onDensityChanged();
22837 killAllBackgroundProcessesExcept(N,
22838 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22842 // Update the configuration with WM first and check if any of the stacks need to be resized
22843 // due to the configuration change. If so, resize the stacks now and do any relaunches if
22844 // necessary. This way we don't need to relaunch again afterwards in
22845 // ensureActivityConfiguration().
22846 if (mWindowManager != null) {
22847 final int[] resizedStacks =
22848 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22849 if (resizedStacks != null) {
22850 for (int stackId : resizedStacks) {
22851 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22859 /** Applies latest configuration and/or visibility updates if needed. */
22860 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22861 boolean kept = true;
22862 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22863 // mainStack is null during startup.
22864 if (mainStack != null) {
22865 if (changes != 0 && starting == null) {
22866 // If the configuration changed, and the caller is not already
22867 // in the process of starting an activity, then find the top
22868 // activity to check if its configuration needs to change.
22869 starting = mainStack.topRunningActivityLocked();
22872 if (starting != null) {
22873 kept = starting.ensureActivityConfiguration(changes,
22874 false /* preserveWindow */);
22875 // And we need to make sure at this point that all other activities
22876 // are made visible with the correct configuration.
22877 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22878 !PRESERVE_WINDOWS);
22885 /** Helper method that requests bounds from WM and applies them to stack. */
22886 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22887 final Rect newStackBounds = new Rect();
22888 final ActivityStack stack = mStackSupervisor.getStack(stackId);
22890 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22891 if (stack == null) {
22892 final StringWriter writer = new StringWriter();
22893 final PrintWriter printWriter = new PrintWriter(writer);
22894 mStackSupervisor.dumpDisplays(printWriter);
22895 printWriter.flush();
22897 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22900 stack.getBoundsForNewConfiguration(newStackBounds);
22901 mStackSupervisor.resizeStackLocked(
22902 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22903 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22904 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22908 * Decide based on the configuration whether we should show the ANR,
22909 * crash, etc dialogs. The idea is that if there is no affordance to
22910 * press the on-screen buttons, or the user experience would be more
22911 * greatly impacted than the crash itself, we shouldn't show the dialog.
22913 * A thought: SystemUI might also want to get told about this, the Power
22914 * dialog / global actions also might want different behaviors.
22916 private void updateShouldShowDialogsLocked(Configuration config) {
22917 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22918 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22919 && config.navigation == Configuration.NAVIGATION_NONAV);
22920 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22921 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22922 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22923 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22924 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22925 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
22926 HIDE_ERROR_DIALOGS, 0) != 0;
22927 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
22931 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22932 synchronized (this) {
22933 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22934 if (srec != null) {
22935 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22941 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22942 Intent resultData) {
22944 synchronized (this) {
22945 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22947 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22953 public int getLaunchedFromUid(IBinder activityToken) {
22954 ActivityRecord srec;
22955 synchronized (this) {
22956 srec = ActivityRecord.forTokenLocked(activityToken);
22958 if (srec == null) {
22961 return srec.launchedFromUid;
22964 public String getLaunchedFromPackage(IBinder activityToken) {
22965 ActivityRecord srec;
22966 synchronized (this) {
22967 srec = ActivityRecord.forTokenLocked(activityToken);
22969 if (srec == null) {
22972 return srec.launchedFromPackage;
22975 // =========================================================
22976 // LIFETIME MANAGEMENT
22977 // =========================================================
22979 // Returns whether the app is receiving broadcast.
22980 // If receiving, fetch all broadcast queues which the app is
22981 // the current [or imminent] receiver on.
22982 private boolean isReceivingBroadcastLocked(ProcessRecord app,
22983 ArraySet<BroadcastQueue> receivingQueues) {
22984 final int N = app.curReceivers.size();
22986 for (int i = 0; i < N; i++) {
22987 receivingQueues.add(app.curReceivers.valueAt(i).queue);
22992 // It's not the current receiver, but it might be starting up to become one
22993 for (BroadcastQueue queue : mBroadcastQueues) {
22994 final BroadcastRecord r = queue.mPendingBroadcast;
22995 if (r != null && r.curApp == app) {
22996 // found it; report which queue it's in
22997 receivingQueues.add(queue);
23001 return !receivingQueues.isEmpty();
23004 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
23005 int targetUid, ComponentName targetComponent, String targetProcess) {
23006 if (!mTrackingAssociations) {
23009 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
23010 = mAssociations.get(targetUid);
23011 if (components == null) {
23012 components = new ArrayMap<>();
23013 mAssociations.put(targetUid, components);
23015 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
23016 if (sourceUids == null) {
23017 sourceUids = new SparseArray<>();
23018 components.put(targetComponent, sourceUids);
23020 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
23021 if (sourceProcesses == null) {
23022 sourceProcesses = new ArrayMap<>();
23023 sourceUids.put(sourceUid, sourceProcesses);
23025 Association ass = sourceProcesses.get(sourceProcess);
23027 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
23029 sourceProcesses.put(sourceProcess, ass);
23033 if (ass.mNesting == 1) {
23034 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
23035 ass.mLastState = sourceState;
23040 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
23041 ComponentName targetComponent) {
23042 if (!mTrackingAssociations) {
23045 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
23046 = mAssociations.get(targetUid);
23047 if (components == null) {
23050 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
23051 if (sourceUids == null) {
23054 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
23055 if (sourceProcesses == null) {
23058 Association ass = sourceProcesses.get(sourceProcess);
23059 if (ass == null || ass.mNesting <= 0) {
23063 if (ass.mNesting == 0) {
23064 long uptime = SystemClock.uptimeMillis();
23065 ass.mTime += uptime - ass.mStartTime;
23066 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
23067 += uptime - ass.mLastStateUptime;
23068 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
23072 private void noteUidProcessState(final int uid, final int state) {
23073 mBatteryStatsService.noteUidProcessState(uid, state);
23074 mAppOpsService.updateUidProcState(uid, state);
23075 if (mTrackingAssociations) {
23076 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
23077 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
23078 = mAssociations.valueAt(i1);
23079 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
23080 SparseArray<ArrayMap<String, Association>> sourceUids
23081 = targetComponents.valueAt(i2);
23082 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
23083 if (sourceProcesses != null) {
23084 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
23085 Association ass = sourceProcesses.valueAt(i4);
23086 if (ass.mNesting >= 1) {
23087 // currently associated
23088 long uptime = SystemClock.uptimeMillis();
23089 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
23090 += uptime - ass.mLastStateUptime;
23091 ass.mLastState = state;
23092 ass.mLastStateUptime = uptime;
23101 private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
23102 boolean doingAll, long now) {
23103 if (mAdjSeq == app.adjSeq) {
23104 if (app.adjSeq == app.completedAdjSeq) {
23105 // This adjustment has already been computed successfully.
23108 // The process is being computed, so there is a cycle. We cannot
23109 // rely on this process's state.
23110 app.containsCycle = true;
23116 if (app.thread == null) {
23117 app.adjSeq = mAdjSeq;
23118 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23119 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23120 app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ;
23121 app.completedAdjSeq = app.adjSeq;
23125 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
23126 app.adjSource = null;
23127 app.adjTarget = null;
23129 app.cached = false;
23131 final int activitiesSize = app.activities.size();
23132 final int appUid = app.info.uid;
23133 final int logUid = mCurOomAdjUid;
23135 int prevAppAdj = app.curAdj;
23136 int prevProcState = app.curProcState;
23138 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
23139 // The max adjustment doesn't allow this app to be anything
23140 // below foreground, so it is not worth doing work for it.
23141 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23142 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app);
23144 app.adjType = "fixed";
23145 app.adjSeq = mAdjSeq;
23146 app.curRawAdj = app.maxAdj;
23147 app.foregroundActivities = false;
23148 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23149 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
23150 // System processes can do UI, and when they do we want to have
23151 // them trim their memory after the user leaves the UI. To
23152 // facilitate this, here we need to determine whether or not it
23153 // is currently showing UI.
23154 app.systemNoUi = true;
23155 if (app == TOP_APP) {
23156 app.systemNoUi = false;
23157 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23158 app.adjType = "pers-top-activity";
23159 } else if (app.hasTopUi) {
23160 // sched group/proc state adjustment is below
23161 app.systemNoUi = false;
23162 app.adjType = "pers-top-ui";
23163 } else if (activitiesSize > 0) {
23164 for (int j = 0; j < activitiesSize; j++) {
23165 final ActivityRecord r = app.activities.get(j);
23167 app.systemNoUi = false;
23171 if (!app.systemNoUi) {
23172 if (mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE) {
23173 // screen on, promote UI
23174 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
23175 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23177 // screen off, restrict UI scheduling
23178 app.curProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23179 app.curSchedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
23182 app.curAdj = app.maxAdj;
23183 app.completedAdjSeq = app.adjSeq;
23184 // if curAdj is less than prevAppAdj, then this process was promoted
23185 return app.curAdj < prevAppAdj;
23188 app.systemNoUi = false;
23190 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
23192 // Determine the importance of the process, starting with most
23193 // important to least, and assign an appropriate OOM adjustment.
23199 boolean foregroundActivities = false;
23200 mTmpBroadcastQueue.clear();
23201 if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
23202 // The last app on the list is the foreground app.
23203 adj = ProcessList.FOREGROUND_APP_ADJ;
23204 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23205 app.adjType = "top-activity";
23206 foregroundActivities = true;
23207 procState = PROCESS_STATE_CUR_TOP;
23208 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23209 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
23211 } else if (app.runningRemoteAnimation) {
23212 adj = ProcessList.VISIBLE_APP_ADJ;
23213 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23214 app.adjType = "running-remote-anim";
23215 procState = PROCESS_STATE_CUR_TOP;
23216 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23217 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
23219 } else if (app.instr != null) {
23220 // Don't want to kill running instrumentation.
23221 adj = ProcessList.FOREGROUND_APP_ADJ;
23222 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23223 app.adjType = "instrumentation";
23224 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23225 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23226 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
23228 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
23229 // An app that is currently receiving a broadcast also
23230 // counts as being in the foreground for OOM killer purposes.
23231 // It's placed in a sched group based on the nature of the
23232 // broadcast as reflected by which queue it's active in.
23233 adj = ProcessList.FOREGROUND_APP_ADJ;
23234 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
23235 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23236 app.adjType = "broadcast";
23237 procState = ActivityManager.PROCESS_STATE_RECEIVER;
23238 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23239 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
23241 } else if (app.executingServices.size() > 0) {
23242 // An app that is currently executing a service callback also
23243 // counts as being in the foreground.
23244 adj = ProcessList.FOREGROUND_APP_ADJ;
23245 schedGroup = app.execServicesFg ?
23246 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23247 app.adjType = "exec-service";
23248 procState = ActivityManager.PROCESS_STATE_SERVICE;
23249 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23250 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
23252 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
23253 } else if (app == TOP_APP) {
23254 adj = ProcessList.FOREGROUND_APP_ADJ;
23255 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23256 app.adjType = "top-sleeping";
23257 foregroundActivities = true;
23258 procState = PROCESS_STATE_CUR_TOP;
23259 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23260 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
23263 // As far as we know the process is empty. We may change our mind later.
23264 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23265 // At this point we don't actually know the adjustment. Use the cached adj
23266 // value that the caller wants us to.
23268 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23271 app.adjType = "cch-empty";
23272 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23273 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
23277 // Examine all activities if not already foreground.
23278 if (!foregroundActivities && activitiesSize > 0) {
23279 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
23280 for (int j = 0; j < activitiesSize; j++) {
23281 final ActivityRecord r = app.activities.get(j);
23282 if (r.app != app) {
23283 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
23284 + " instead of expected " + app);
23285 if (r.app == null || (r.app.uid == app.uid)) {
23286 // Only fix things up when they look sane
23293 // App has a visible activity; only upgrade adjustment.
23294 if (adj > ProcessList.VISIBLE_APP_ADJ) {
23295 adj = ProcessList.VISIBLE_APP_ADJ;
23296 app.adjType = "vis-activity";
23297 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23298 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23299 "Raise adj to vis-activity: " + app);
23302 if (procState > PROCESS_STATE_CUR_TOP) {
23303 procState = PROCESS_STATE_CUR_TOP;
23304 app.adjType = "vis-activity";
23305 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23306 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23307 "Raise procstate to vis-activity (top): " + app);
23310 if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23311 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23313 app.cached = false;
23315 foregroundActivities = true;
23316 final TaskRecord task = r.getTask();
23317 if (task != null && minLayer > 0) {
23318 final int layer = task.mLayerRank;
23319 if (layer >= 0 && minLayer > layer) {
23324 } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) {
23325 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23326 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23327 app.adjType = "pause-activity";
23328 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23329 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23330 "Raise adj to pause-activity: " + app);
23333 if (procState > PROCESS_STATE_CUR_TOP) {
23334 procState = PROCESS_STATE_CUR_TOP;
23335 app.adjType = "pause-activity";
23336 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23337 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23338 "Raise procstate to pause-activity (top): " + app);
23341 if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23342 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23344 app.cached = false;
23346 foregroundActivities = true;
23347 } else if (r.isState(ActivityState.STOPPING)) {
23348 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23349 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23350 app.adjType = "stop-activity";
23351 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23352 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23353 "Raise adj to stop-activity: " + app);
23356 // For the process state, we will at this point consider the
23357 // process to be cached. It will be cached either as an activity
23358 // or empty depending on whether the activity is finishing. We do
23359 // this so that we can treat the process as cached for purposes of
23360 // memory trimming (determing current memory level, trim command to
23361 // send to process) since there can be an arbitrary number of stopping
23362 // processes and they should soon all go into the cached state.
23363 if (!r.finishing) {
23364 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23365 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23366 app.adjType = "stop-activity";
23367 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23368 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23369 "Raise procstate to stop-activity: " + app);
23373 app.cached = false;
23375 foregroundActivities = true;
23377 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23378 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23379 app.adjType = "cch-act";
23380 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23381 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23382 "Raise procstate to cached activity: " + app);
23387 if (adj == ProcessList.VISIBLE_APP_ADJ) {
23391 if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
23392 procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
23393 app.adjType = "cch-rec";
23394 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23395 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app);
23399 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23400 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
23401 if (app.foregroundServices) {
23402 // The user is aware of this app, so make it visible.
23403 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23404 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23405 app.cached = false;
23406 app.adjType = "fg-service";
23407 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23408 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23409 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app);
23411 } else if (app.hasOverlayUi) {
23412 // The process is display an overlay UI.
23413 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23414 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23415 app.cached = false;
23416 app.adjType = "has-overlay-ui";
23417 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23418 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23419 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app);
23424 // If the app was recently in the foreground and moved to a foreground service status,
23425 // allow it to get a higher rank in memory for some time, compared to other foreground
23426 // services so that it can finish performing any persistence/processing of in-memory state.
23427 if (app.foregroundServices && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
23428 && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now
23429 || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) {
23430 adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
23431 app.adjType = "fg-service-act";
23432 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23433 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app);
23437 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23438 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23439 if (app.forcingToImportant != null) {
23440 // This is currently used for toasts... they are not interactive, and
23441 // we don't want them to cause the app to become fully foreground (and
23442 // thus out of background check), so we yes the best background level we can.
23443 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23444 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23445 app.cached = false;
23446 app.adjType = "force-imp";
23447 app.adjSource = app.forcingToImportant;
23448 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23449 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23450 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app);
23455 if (app == mHeavyWeightProcess) {
23456 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
23457 // We don't want to kill the current heavy-weight process.
23458 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
23459 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23460 app.cached = false;
23461 app.adjType = "heavy";
23462 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23463 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app);
23466 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
23467 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
23468 app.adjType = "heavy";
23469 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23470 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app);
23475 if (app == mHomeProcess) {
23476 if (adj > ProcessList.HOME_APP_ADJ) {
23477 // This process is hosting what we currently consider to be the
23478 // home app, so we don't want to let it go into the background.
23479 adj = ProcessList.HOME_APP_ADJ;
23480 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23481 app.cached = false;
23482 app.adjType = "home";
23483 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23484 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app);
23487 if (procState > ActivityManager.PROCESS_STATE_HOME) {
23488 procState = ActivityManager.PROCESS_STATE_HOME;
23489 app.adjType = "home";
23490 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23491 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app);
23496 if (app == mPreviousProcess && app.activities.size() > 0) {
23497 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23498 // This was the previous process that showed UI to the user.
23499 // We want to try to keep it around more aggressively, to give
23500 // a good experience around switching between two apps.
23501 adj = ProcessList.PREVIOUS_APP_ADJ;
23502 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23503 app.cached = false;
23504 app.adjType = "previous";
23505 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23506 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
23509 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23510 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23511 app.adjType = "previous";
23512 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23513 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app);
23518 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
23519 + " reason=" + app.adjType);
23521 // By default, we use the computed adjustment. It may be changed if
23522 // there are applications dependent on our services or providers, but
23523 // this gives us a baseline and makes sure we don't get into an
23524 // infinite recursion.
23525 app.curRawAdj = adj;
23526 app.hasStartedServices = false;
23527 app.adjSeq = mAdjSeq;
23529 if (mBackupTarget != null && app == mBackupTarget.app) {
23530 // If possible we want to avoid killing apps while they're being backed up
23531 if (adj > ProcessList.BACKUP_APP_ADJ) {
23532 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
23533 adj = ProcessList.BACKUP_APP_ADJ;
23534 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23535 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23537 app.adjType = "backup";
23538 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23539 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
23541 app.cached = false;
23543 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
23544 procState = ActivityManager.PROCESS_STATE_BACKUP;
23545 app.adjType = "backup";
23546 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23547 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app);
23552 boolean mayBeTop = false;
23553 String mayBeTopType = null;
23554 Object mayBeTopSource = null;
23555 Object mayBeTopTarget = null;
23557 for (int is = app.services.size()-1;
23558 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23559 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23560 || procState > ActivityManager.PROCESS_STATE_TOP);
23562 ServiceRecord s = app.services.valueAt(is);
23563 if (s.startRequested) {
23564 app.hasStartedServices = true;
23565 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
23566 procState = ActivityManager.PROCESS_STATE_SERVICE;
23567 app.adjType = "started-services";
23568 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23569 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23570 "Raise procstate to started service: " + app);
23573 if (app.hasShownUi && app != mHomeProcess) {
23574 // If this process has shown some UI, let it immediately
23575 // go to the LRU list because it may be pretty heavy with
23576 // UI stuff. We'll tag it with a label just to help
23577 // debug and understand what is going on.
23578 if (adj > ProcessList.SERVICE_ADJ) {
23579 app.adjType = "cch-started-ui-services";
23582 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23583 // This service has seen some activity within
23584 // recent memory, so we will keep its process ahead
23585 // of the background processes.
23586 if (adj > ProcessList.SERVICE_ADJ) {
23587 adj = ProcessList.SERVICE_ADJ;
23588 app.adjType = "started-services";
23589 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23590 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23591 "Raise adj to started service: " + app);
23593 app.cached = false;
23596 // If we have let the service slide into the background
23597 // state, still have some text describing what it is doing
23598 // even though the service no longer has an impact.
23599 if (adj > ProcessList.SERVICE_ADJ) {
23600 app.adjType = "cch-started-services";
23605 for (int conni = s.connections.size()-1;
23606 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23607 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23608 || procState > ActivityManager.PROCESS_STATE_TOP);
23610 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
23612 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
23613 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23614 || procState > ActivityManager.PROCESS_STATE_TOP);
23616 // XXX should compute this based on the max of
23617 // all connected clients.
23618 ConnectionRecord cr = clist.get(i);
23619 if (cr.binding.client == app) {
23620 // Binding to ourself is not interesting.
23624 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
23625 ProcessRecord client = cr.binding.client;
23626 computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23627 if (client.containsCycle) {
23628 // We've detected a cycle. We should retry computeOomAdjLocked later in
23629 // case a later-checked connection from a client would raise its
23630 // priority legitimately.
23631 app.containsCycle = true;
23632 // If the client has not been completely evaluated, skip using its
23633 // priority. Else use the conservative value for now and look for a
23634 // better state in the next iteration.
23635 if (client.completedAdjSeq < mAdjSeq) {
23639 int clientAdj = client.curRawAdj;
23640 int clientProcState = client.curProcState;
23641 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23642 // If the other app is cached for any reason, for purposes here
23643 // we are going to consider it empty. The specific cached state
23644 // doesn't propagate except under certain conditions.
23645 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23647 String adjType = null;
23648 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
23649 // Not doing bind OOM management, so treat
23650 // this guy more like a started service.
23651 if (app.hasShownUi && app != mHomeProcess) {
23652 // If this process has shown some UI, let it immediately
23653 // go to the LRU list because it may be pretty heavy with
23654 // UI stuff. We'll tag it with a label just to help
23655 // debug and understand what is going on.
23656 if (adj > clientAdj) {
23657 adjType = "cch-bound-ui-services";
23659 app.cached = false;
23661 clientProcState = procState;
23663 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23664 // This service has not seen activity within
23665 // recent memory, so allow it to drop to the
23666 // LRU list if there is no other reason to keep
23667 // it around. We'll also tag it with a label just
23668 // to help debug and undertand what is going on.
23669 if (adj > clientAdj) {
23670 adjType = "cch-bound-services";
23676 if (adj > clientAdj) {
23677 // If this process has recently shown UI, and
23678 // the process that is binding to it is less
23679 // important than being visible, then we don't
23680 // care about the binding as much as we care
23681 // about letting this process get into the LRU
23682 // list to be killed and restarted if needed for
23684 if (app.hasShownUi && app != mHomeProcess
23685 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23686 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
23687 adjType = "cch-bound-ui-services";
23691 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
23692 |Context.BIND_IMPORTANT)) != 0) {
23693 if (clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
23694 newAdj = clientAdj;
23696 // make this service persistent
23697 newAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
23698 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23699 procState = ActivityManager.PROCESS_STATE_PERSISTENT;
23701 } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0
23702 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23703 && adj > ProcessList.PERCEPTIBLE_APP_ADJ + 1) {
23704 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ + 1;
23705 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
23706 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23707 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23708 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
23709 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
23710 newAdj = clientAdj;
23712 if (adj > ProcessList.VISIBLE_APP_ADJ) {
23713 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
23718 if (!client.cached) {
23719 app.cached = false;
23721 if (adj > newAdj) {
23723 adjType = "service";
23727 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
23728 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
23729 // This will treat important bound services identically to
23730 // the top app, which may behave differently than generic
23731 // foreground work.
23732 if (client.curSchedGroup > schedGroup) {
23733 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23734 schedGroup = client.curSchedGroup;
23736 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23739 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23740 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23741 // Special handling of clients who are in the top state.
23742 // We *may* want to consider this process to be in the
23743 // top state as well, but only if there is not another
23744 // reason for it to be running. Being on the top is a
23745 // special state, meaning you are specifically running
23746 // for the current top app. If the process is already
23747 // running in the background for some other reason, it
23748 // is more important to continue considering it to be
23749 // in the background state.
23751 mayBeTopType = "service";
23752 mayBeTopSource = cr.binding.client;
23753 mayBeTopTarget = s.name;
23754 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23756 // Special handling for above-top states (persistent
23757 // processes). These should not bring the current process
23758 // into the top state, since they are not on top. Instead
23759 // give them the best state after that.
23760 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
23762 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23763 } else if (mWakefulness
23764 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
23765 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
23768 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23771 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23775 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
23776 if (clientProcState <
23777 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23779 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23782 if (clientProcState <
23783 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
23785 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
23788 if (procState > clientProcState) {
23789 procState = clientProcState;
23790 if (adjType == null) {
23791 adjType = "service";
23794 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23795 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
23796 app.pendingUiClean = true;
23798 if (adjType != null) {
23799 app.adjType = adjType;
23800 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23801 .REASON_SERVICE_IN_USE;
23802 app.adjSource = cr.binding.client;
23803 app.adjSourceProcState = clientProcState;
23804 app.adjTarget = s.name;
23805 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23806 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23807 + ": " + app + ", due to " + cr.binding.client
23808 + " adj=" + adj + " procState="
23809 + ProcessList.makeProcStateString(procState));
23813 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
23814 app.treatLikeActivity = true;
23816 final ActivityRecord a = cr.activity;
23817 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
23818 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
23819 || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
23820 adj = ProcessList.FOREGROUND_APP_ADJ;
23821 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
23822 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23823 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
23825 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23828 app.cached = false;
23829 app.adjType = "service";
23830 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23831 .REASON_SERVICE_IN_USE;
23833 app.adjSourceProcState = procState;
23834 app.adjTarget = s.name;
23835 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23836 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23837 "Raise to service w/activity: " + app);
23845 for (int provi = app.pubProviders.size()-1;
23846 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23847 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23848 || procState > ActivityManager.PROCESS_STATE_TOP);
23850 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
23851 for (int i = cpr.connections.size()-1;
23852 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23853 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23854 || procState > ActivityManager.PROCESS_STATE_TOP);
23856 ContentProviderConnection conn = cpr.connections.get(i);
23857 ProcessRecord client = conn.client;
23858 if (client == app) {
23859 // Being our own client is not interesting.
23862 computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23863 if (client.containsCycle) {
23864 // We've detected a cycle. We should retry computeOomAdjLocked later in
23865 // case a later-checked connection from a client would raise its
23866 // priority legitimately.
23867 app.containsCycle = true;
23868 // If the client has not been completely evaluated, skip using its
23869 // priority. Else use the conservative value for now and look for a
23870 // better state in the next iteration.
23871 if (client.completedAdjSeq < mAdjSeq) {
23875 int clientAdj = client.curRawAdj;
23876 int clientProcState = client.curProcState;
23877 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23878 // If the other app is cached for any reason, for purposes here
23879 // we are going to consider it empty.
23880 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23882 String adjType = null;
23883 if (adj > clientAdj) {
23884 if (app.hasShownUi && app != mHomeProcess
23885 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23886 adjType = "cch-ui-provider";
23888 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23889 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23890 adjType = "provider";
23892 app.cached &= client.cached;
23894 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23895 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23896 // Special handling of clients who are in the top state.
23897 // We *may* want to consider this process to be in the
23898 // top state as well, but only if there is not another
23899 // reason for it to be running. Being on the top is a
23900 // special state, meaning you are specifically running
23901 // for the current top app. If the process is already
23902 // running in the background for some other reason, it
23903 // is more important to continue considering it to be
23904 // in the background state.
23906 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23907 mayBeTopType = adjType = "provider-top";
23908 mayBeTopSource = client;
23909 mayBeTopTarget = cpr.name;
23911 // Special handling for above-top states (persistent
23912 // processes). These should not bring the current process
23913 // into the top state, since they are not on top. Instead
23914 // give them the best state after that.
23916 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23917 if (adjType == null) {
23918 adjType = "provider";
23922 if (procState > clientProcState) {
23923 procState = clientProcState;
23925 if (client.curSchedGroup > schedGroup) {
23926 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23928 if (adjType != null) {
23929 app.adjType = adjType;
23930 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23931 .REASON_PROVIDER_IN_USE;
23932 app.adjSource = client;
23933 app.adjSourceProcState = clientProcState;
23934 app.adjTarget = cpr.name;
23935 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23936 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23937 + ": " + app + ", due to " + client
23938 + " adj=" + adj + " procState="
23939 + ProcessList.makeProcStateString(procState));
23943 // If the provider has external (non-framework) process
23944 // dependencies, ensure that its adjustment is at least
23945 // FOREGROUND_APP_ADJ.
23946 if (cpr.hasExternalProcessHandles()) {
23947 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23948 adj = ProcessList.FOREGROUND_APP_ADJ;
23949 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23950 app.cached = false;
23951 app.adjType = "ext-provider";
23952 app.adjTarget = cpr.name;
23953 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23954 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23955 "Raise adj to external provider: " + app);
23958 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23959 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23960 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23961 "Raise procstate to external provider: " + app);
23966 if (app.lastProviderTime > 0 &&
23967 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
23968 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23969 adj = ProcessList.PREVIOUS_APP_ADJ;
23970 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23971 app.cached = false;
23972 app.adjType = "recent-provider";
23973 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23974 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23975 "Raise adj to recent provider: " + app);
23978 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23979 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23980 app.adjType = "recent-provider";
23981 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23982 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23983 "Raise procstate to recent provider: " + app);
23988 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
23989 // A client of one of our services or providers is in the top state. We
23990 // *may* want to be in the top state, but not if we are already running in
23991 // the background for some other reason. For the decision here, we are going
23992 // to pick out a few specific states that we want to remain in when a client
23993 // is top (states that tend to be longer-term) and otherwise allow it to go
23994 // to the top state.
23995 switch (procState) {
23996 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
23997 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
23998 // Something else is keeping it at this level, just leave it.
24000 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
24001 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
24002 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
24003 case ActivityManager.PROCESS_STATE_SERVICE:
24004 // These all are longer-term states, so pull them up to the top
24005 // of the background states, but not all the way to the top state.
24006 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
24007 app.adjType = mayBeTopType;
24008 app.adjSource = mayBeTopSource;
24009 app.adjTarget = mayBeTopTarget;
24010 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24011 reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
24012 + ": " + app + ", due to " + mayBeTopSource
24013 + " adj=" + adj + " procState="
24014 + ProcessList.makeProcStateString(procState));
24018 // Otherwise, top is a better choice, so take it.
24019 procState = ActivityManager.PROCESS_STATE_TOP;
24020 app.adjType = mayBeTopType;
24021 app.adjSource = mayBeTopSource;
24022 app.adjTarget = mayBeTopTarget;
24023 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24024 reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
24025 + ": " + app + ", due to " + mayBeTopSource
24026 + " adj=" + adj + " procState="
24027 + ProcessList.makeProcStateString(procState));
24033 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
24034 if (app.hasClientActivities) {
24035 // This is a cached process, but with client activities. Mark it so.
24036 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
24037 app.adjType = "cch-client-act";
24038 } else if (app.treatLikeActivity) {
24039 // This is a cached process, but somebody wants us to treat it like it has
24040 // an activity, okay!
24041 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
24042 app.adjType = "cch-as-act";
24046 if (adj == ProcessList.SERVICE_ADJ) {
24048 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
24049 mNewNumServiceProcs++;
24050 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
24051 if (!app.serviceb) {
24052 // This service isn't far enough down on the LRU list to
24053 // normally be a B service, but if we are low on RAM and it
24054 // is large we want to force it down since we would prefer to
24055 // keep launcher over it.
24056 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
24057 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
24058 app.serviceHighRam = true;
24059 app.serviceb = true;
24060 //Slog.i(TAG, "ADJ " + app + " high ram!");
24062 mNewNumAServiceProcs++;
24063 //Slog.i(TAG, "ADJ " + app + " not high ram!");
24066 app.serviceHighRam = false;
24069 if (app.serviceb) {
24070 adj = ProcessList.SERVICE_B_ADJ;
24074 app.curRawAdj = adj;
24076 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
24077 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
24078 if (adj > app.maxAdj) {
24080 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
24081 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
24085 // Put bound foreground services in a special sched group for additional
24086 // restrictions on screen off
24087 if (procState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE &&
24088 mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
24089 if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) {
24090 schedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
24094 // Do final modification to adj. Everything we do between here and applying
24095 // the final setAdj must be done in this function, because we will also use
24096 // it when computing the final cached adj later. Note that we don't need to
24097 // worry about this for max adj above, since max adj will always be used to
24098 // keep it out of the cached vaues.
24099 app.curAdj = app.modifyRawOomAdj(adj);
24100 app.curSchedGroup = schedGroup;
24101 app.curProcState = procState;
24102 app.foregroundActivities = foregroundActivities;
24103 app.completedAdjSeq = mAdjSeq;
24105 // if curAdj or curProcState improved, then this process was promoted
24106 return app.curAdj < prevAppAdj || app.curProcState < prevProcState;
24110 * Record new PSS sample for a process.
24112 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
24113 long rss, int statType, long pssDuration, long now) {
24114 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
24115 swapPss * 1024, rss * 1024, statType, procState, pssDuration);
24116 proc.lastPssTime = now;
24117 proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
24118 if (DEBUG_PSS) Slog.d(TAG_PSS,
24119 "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
24120 + " state=" + ProcessList.makeProcStateString(procState));
24121 if (proc.initialIdlePss == 0) {
24122 proc.initialIdlePss = pss;
24124 proc.lastPss = pss;
24125 proc.lastSwapPss = swapPss;
24126 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
24127 proc.lastCachedPss = pss;
24128 proc.lastCachedSwapPss = swapPss;
24131 final SparseArray<Pair<Long, String>> watchUids
24132 = mMemWatchProcesses.getMap().get(proc.processName);
24134 if (watchUids != null) {
24135 Pair<Long, String> val = watchUids.get(proc.uid);
24137 val = watchUids.get(0);
24143 if (check != null) {
24144 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
24145 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24146 if (!isDebuggable) {
24147 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
24148 isDebuggable = true;
24151 if (isDebuggable) {
24152 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
24153 final ProcessRecord myProc = proc;
24154 final File heapdumpFile = DumpHeapProvider.getJavaFile();
24155 mMemWatchDumpProcName = proc.processName;
24156 mMemWatchDumpFile = heapdumpFile.toString();
24157 mMemWatchDumpPid = proc.pid;
24158 mMemWatchDumpUid = proc.uid;
24159 BackgroundThread.getHandler().post(new Runnable() {
24161 public void run() {
24162 revokeUriPermission(ActivityThread.currentActivityThread()
24163 .getApplicationThread(),
24164 null, DumpHeapActivity.JAVA_URI,
24165 Intent.FLAG_GRANT_READ_URI_PERMISSION
24166 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
24167 UserHandle.myUserId());
24168 ParcelFileDescriptor fd = null;
24170 heapdumpFile.delete();
24171 fd = ParcelFileDescriptor.open(heapdumpFile,
24172 ParcelFileDescriptor.MODE_CREATE |
24173 ParcelFileDescriptor.MODE_TRUNCATE |
24174 ParcelFileDescriptor.MODE_WRITE_ONLY |
24175 ParcelFileDescriptor.MODE_APPEND);
24176 IApplicationThread thread = myProc.thread;
24177 if (thread != null) {
24179 if (DEBUG_PSS) Slog.d(TAG_PSS,
24180 "Requesting dump heap from "
24181 + myProc + " to " + heapdumpFile);
24182 thread.dumpHeap(/* managed= */ true,
24183 /* mallocInfo= */ false, /* runGc= */ false,
24184 heapdumpFile.toString(), fd);
24185 } catch (RemoteException e) {
24188 } catch (FileNotFoundException e) {
24189 e.printStackTrace();
24194 } catch (IOException e) {
24201 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
24202 + ", but debugging not enabled");
24209 * Schedule PSS collection of a process.
24211 boolean requestPssLocked(ProcessRecord proc, int procState) {
24212 if (mPendingPssProcesses.contains(proc)) {
24215 if (mPendingPssProcesses.size() == 0) {
24216 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24218 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
24219 proc.pssProcState = procState;
24220 proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
24221 mPendingPssProcesses.add(proc);
24226 * Schedule PSS collection of all processes.
24228 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
24230 if (now < (mLastFullPssTime +
24231 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
24232 : mConstants.FULL_PSS_MIN_INTERVAL))) {
24236 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs! memLowered=" + memLowered);
24237 mLastFullPssTime = now;
24238 mFullPssPending = true;
24239 for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
24240 ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
24242 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
24243 mPendingPssProcesses.clear();
24244 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24245 ProcessRecord app = mLruProcesses.get(i);
24246 if (app.thread == null
24247 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24250 if (memLowered || (always && now >
24251 app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
24252 || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
24253 app.pssProcState = app.setProcState;
24254 app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
24255 : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
24256 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24257 app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24258 mPendingPssProcesses.add(app);
24261 if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
24262 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24266 public void setTestPssMode(boolean enabled) {
24267 synchronized (this) {
24268 mTestPssMode = enabled;
24270 // Whenever we enable the mode, we want to take a snapshot all of current
24271 // process mem use.
24272 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
24278 * Ask a given process to GC right now.
24280 final void performAppGcLocked(ProcessRecord app) {
24282 app.lastRequestedGc = SystemClock.uptimeMillis();
24283 if (app.thread != null) {
24284 if (app.reportLowMemory) {
24285 app.reportLowMemory = false;
24286 app.thread.scheduleLowMemory();
24288 app.thread.processInBackground();
24291 } catch (Exception e) {
24297 * Returns true if things are idle enough to perform GCs.
24299 private final boolean canGcNowLocked() {
24300 boolean processingBroadcasts = false;
24301 for (BroadcastQueue q : mBroadcastQueues) {
24302 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
24303 processingBroadcasts = true;
24306 return !processingBroadcasts
24307 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
24311 * Perform GCs on all processes that are waiting for it, but only
24312 * if things are idle.
24314 final void performAppGcsLocked() {
24315 final int N = mProcessesToGc.size();
24319 if (canGcNowLocked()) {
24320 while (mProcessesToGc.size() > 0) {
24321 ProcessRecord proc = mProcessesToGc.remove(0);
24322 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
24323 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
24324 <= SystemClock.uptimeMillis()) {
24325 // To avoid spamming the system, we will GC processes one
24326 // at a time, waiting a few seconds between each.
24327 performAppGcLocked(proc);
24328 scheduleAppGcsLocked();
24331 // It hasn't been long enough since we last GCed this
24332 // process... put it in the list to wait for its time.
24333 addProcessToGcListLocked(proc);
24339 scheduleAppGcsLocked();
24344 * If all looks good, perform GCs on all processes waiting for them.
24346 final void performAppGcsIfAppropriateLocked() {
24347 if (canGcNowLocked()) {
24348 performAppGcsLocked();
24351 // Still not idle, wait some more.
24352 scheduleAppGcsLocked();
24356 * Schedule the execution of all pending app GCs.
24358 final void scheduleAppGcsLocked() {
24359 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
24361 if (mProcessesToGc.size() > 0) {
24362 // Schedule a GC for the time to the next process.
24363 ProcessRecord proc = mProcessesToGc.get(0);
24364 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
24366 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
24367 long now = SystemClock.uptimeMillis();
24368 if (when < (now+mConstants.GC_TIMEOUT)) {
24369 when = now + mConstants.GC_TIMEOUT;
24371 mHandler.sendMessageAtTime(msg, when);
24376 * Add a process to the array of processes waiting to be GCed. Keeps the
24377 * list in sorted order by the last GC time. The process can't already be
24380 final void addProcessToGcListLocked(ProcessRecord proc) {
24381 boolean added = false;
24382 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
24383 if (mProcessesToGc.get(i).lastRequestedGc <
24384 proc.lastRequestedGc) {
24386 mProcessesToGc.add(i+1, proc);
24391 mProcessesToGc.add(0, proc);
24396 * Set up to ask a process to GC itself. This will either do it
24397 * immediately, or put it on the list of processes to gc the next
24398 * time things are idle.
24400 final void scheduleAppGcLocked(ProcessRecord app) {
24401 long now = SystemClock.uptimeMillis();
24402 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
24405 if (!mProcessesToGc.contains(app)) {
24406 addProcessToGcListLocked(app);
24407 scheduleAppGcsLocked();
24411 final void checkExcessivePowerUsageLocked() {
24412 updateCpuStatsNow();
24414 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
24415 boolean doCpuKills = true;
24416 if (mLastPowerCheckUptime == 0) {
24417 doCpuKills = false;
24419 final long curUptime = SystemClock.uptimeMillis();
24420 final long uptimeSince = curUptime - mLastPowerCheckUptime;
24421 mLastPowerCheckUptime = curUptime;
24422 int i = mLruProcesses.size();
24425 ProcessRecord app = mLruProcesses.get(i);
24426 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24427 if (app.lastCpuTime <= 0) {
24430 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
24432 StringBuilder sb = new StringBuilder(128);
24433 sb.append("CPU for ");
24434 app.toShortString(sb);
24435 sb.append(": over ");
24436 TimeUtils.formatDuration(uptimeSince, sb);
24437 sb.append(" used ");
24438 TimeUtils.formatDuration(cputimeUsed, sb);
24440 sb.append((cputimeUsed*100)/uptimeSince);
24442 Slog.i(TAG_POWER, sb.toString());
24444 // If the process has used too much CPU over the last duration, the
24445 // user probably doesn't want this, so kill!
24446 if (doCpuKills && uptimeSince > 0) {
24447 // What is the limit for this process?
24449 long checkDur = curUptime - app.whenUnimportant;
24450 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
24451 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
24452 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
24453 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
24454 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
24455 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
24456 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
24458 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
24460 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
24461 synchronized (stats) {
24462 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
24463 uptimeSince, cputimeUsed);
24465 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
24466 + " dur=" + checkDur + " limit=" + cpuLimit, true);
24467 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
24470 app.lastCpuTime = app.curCpuTime;
24475 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
24477 boolean success = true;
24479 if (app.curRawAdj != app.setRawAdj) {
24480 app.setRawAdj = app.curRawAdj;
24485 if (app.curAdj != app.setAdj) {
24486 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
24487 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
24488 String msg = "Set " + app.pid + " " + app.processName + " adj "
24489 + app.curAdj + ": " + app.adjType;
24490 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24492 app.setAdj = app.curAdj;
24493 app.verifiedAdj = ProcessList.INVALID_ADJ;
24496 if (app.setSchedGroup != app.curSchedGroup) {
24497 int oldSchedGroup = app.setSchedGroup;
24498 app.setSchedGroup = app.curSchedGroup;
24499 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24500 String msg = "Setting sched group of " + app.processName
24501 + " to " + app.curSchedGroup + ": " + app.adjType;
24502 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24504 if (app.waitingToKill != null && app.curReceivers.isEmpty()
24505 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
24506 app.kill(app.waitingToKill, true);
24510 switch (app.curSchedGroup) {
24511 case ProcessList.SCHED_GROUP_BACKGROUND:
24512 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
24514 case ProcessList.SCHED_GROUP_TOP_APP:
24515 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
24516 processGroup = THREAD_GROUP_TOP_APP;
24518 case ProcessList.SCHED_GROUP_RESTRICTED:
24519 processGroup = THREAD_GROUP_RESTRICTED;
24522 processGroup = THREAD_GROUP_DEFAULT;
24525 long oldId = Binder.clearCallingIdentity();
24527 setProcessGroup(app.pid, processGroup);
24528 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
24529 // do nothing if we already switched to RT
24530 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24531 mVrController.onTopProcChangedLocked(app);
24532 if (mUseFifoUiScheduling) {
24533 // Switch UI pipeline for app to SCHED_FIFO
24534 app.savedPriority = Process.getThreadPriority(app.pid);
24535 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
24536 if (app.renderThreadTid != 0) {
24537 scheduleAsFifoPriority(app.renderThreadTid,
24538 /* suppressLogs */true);
24539 if (DEBUG_OOM_ADJ) {
24540 Slog.d("UI_FIFO", "Set RenderThread (TID " +
24541 app.renderThreadTid + ") to FIFO");
24544 if (DEBUG_OOM_ADJ) {
24545 Slog.d("UI_FIFO", "Not setting RenderThread TID");
24549 // Boost priority for top app UI and render threads
24550 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
24551 if (app.renderThreadTid != 0) {
24553 setThreadPriority(app.renderThreadTid,
24554 TOP_APP_PRIORITY_BOOST);
24555 } catch (IllegalArgumentException e) {
24556 // thread died, ignore
24561 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
24562 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24563 mVrController.onTopProcChangedLocked(app);
24564 if (mUseFifoUiScheduling) {
24566 // Reset UI pipeline to SCHED_OTHER
24567 setThreadScheduler(app.pid, SCHED_OTHER, 0);
24568 setThreadPriority(app.pid, app.savedPriority);
24569 if (app.renderThreadTid != 0) {
24570 setThreadScheduler(app.renderThreadTid,
24572 setThreadPriority(app.renderThreadTid, -4);
24574 } catch (IllegalArgumentException e) {
24576 "Failed to set scheduling policy, thread does not exist:\n"
24578 } catch (SecurityException e) {
24579 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
24582 // Reset priority for top app UI and render threads
24583 setThreadPriority(app.pid, 0);
24584 if (app.renderThreadTid != 0) {
24585 setThreadPriority(app.renderThreadTid, 0);
24589 } catch (Exception e) {
24591 Slog.w(TAG, "Failed setting process group of " + app.pid
24592 + " to " + app.curSchedGroup);
24593 Slog.w(TAG, "at location", e);
24596 Binder.restoreCallingIdentity(oldId);
24600 if (app.repForegroundActivities != app.foregroundActivities) {
24601 app.repForegroundActivities = app.foregroundActivities;
24602 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
24604 if (app.repProcState != app.curProcState) {
24605 app.repProcState = app.curProcState;
24606 if (app.thread != null) {
24609 //RuntimeException h = new RuntimeException("here");
24610 Slog.i(TAG, "Sending new process state " + app.repProcState
24611 + " to " + app /*, h*/);
24613 app.thread.setProcessState(app.repProcState);
24614 } catch (RemoteException e) {
24618 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
24619 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
24620 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
24621 // Experimental code to more aggressively collect pss while
24622 // running test... the problem is that this tends to collect
24623 // the data right when a process is transitioning between process
24624 // states, which will tend to give noisy data.
24625 long start = SystemClock.uptimeMillis();
24626 long startTime = SystemClock.currentThreadTimeMillis();
24627 long pss = Debug.getPss(app.pid, mTmpLong, null);
24628 long endTime = SystemClock.currentThreadTimeMillis();
24629 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
24630 mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
24631 mPendingPssProcesses.remove(app);
24632 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
24633 + " to " + app.curProcState + ": "
24634 + (SystemClock.uptimeMillis()-start) + "ms");
24636 app.lastStateTime = now;
24637 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24638 app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24639 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
24640 + ProcessList.makeProcStateString(app.setProcState) + " to "
24641 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
24642 + (app.nextPssTime-now) + ": " + app);
24644 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
24645 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
24647 if (requestPssLocked(app, app.setProcState)) {
24648 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24649 app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24651 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
24652 "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
24654 if (app.setProcState != app.curProcState) {
24655 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24656 String msg = "Proc state change of " + app.processName
24657 + " to " + ProcessList.makeProcStateString(app.curProcState)
24658 + " (" + app.curProcState + ")" + ": " + app.adjType;
24659 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24661 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
24662 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
24663 if (setImportant && !curImportant) {
24664 // This app is no longer something we consider important enough to allow to
24665 // use arbitrary amounts of battery power. Note
24666 // its current CPU time to later know to kill it if
24667 // it is not behaving well.
24668 app.whenUnimportant = now;
24669 app.lastCpuTime = 0;
24671 // Inform UsageStats of important process state change
24672 // Must be called before updating setProcState
24673 maybeUpdateUsageStatsLocked(app, nowElapsed);
24675 maybeUpdateLastTopTime(app, now);
24677 app.setProcState = app.curProcState;
24678 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24679 app.notCachedSinceIdle = false;
24682 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
24684 app.procStateChanged = true;
24686 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
24687 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
24688 // For apps that sit around for a long time in the interactive state, we need
24689 // to report this at least once a day so they don't go idle.
24690 maybeUpdateUsageStatsLocked(app, nowElapsed);
24693 if (changes != 0) {
24694 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24695 "Changes in " + app + ": " + changes);
24696 int i = mPendingProcessChanges.size()-1;
24697 ProcessChangeItem item = null;
24699 item = mPendingProcessChanges.get(i);
24700 if (item.pid == app.pid) {
24701 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24702 "Re-using existing item: " + item);
24708 // No existing item in pending changes; need a new one.
24709 final int NA = mAvailProcessChanges.size();
24711 item = mAvailProcessChanges.remove(NA-1);
24712 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24713 "Retrieving available item: " + item);
24715 item = new ProcessChangeItem();
24716 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24717 "Allocating new item: " + item);
24720 item.pid = app.pid;
24721 item.uid = app.info.uid;
24722 if (mPendingProcessChanges.size() == 0) {
24723 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24724 "*** Enqueueing dispatch processes changed!");
24725 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
24727 mPendingProcessChanges.add(item);
24729 item.changes |= changes;
24730 item.foregroundActivities = app.repForegroundActivities;
24731 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24732 "Item " + Integer.toHexString(System.identityHashCode(item))
24733 + " " + app.toShortString() + ": changes=" + item.changes
24734 + " foreground=" + item.foregroundActivities
24735 + " type=" + app.adjType + " source=" + app.adjSource
24736 + " target=" + app.adjTarget);
24742 private boolean isEphemeralLocked(int uid) {
24743 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
24744 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
24747 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
24752 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
24753 final UidRecord.ChangeItem pendingChange;
24754 if (uidRec == null || uidRec.pendingChange == null) {
24755 if (mPendingUidChanges.size() == 0) {
24756 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24757 "*** Enqueueing dispatch uid changed!");
24758 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
24760 final int NA = mAvailUidChanges.size();
24762 pendingChange = mAvailUidChanges.remove(NA-1);
24763 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24764 "Retrieving available item: " + pendingChange);
24766 pendingChange = new UidRecord.ChangeItem();
24767 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24768 "Allocating new item: " + pendingChange);
24770 if (uidRec != null) {
24771 uidRec.pendingChange = pendingChange;
24772 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
24773 // If this uid is going away, and we haven't yet reported it is gone,
24775 change |= UidRecord.CHANGE_IDLE;
24777 } else if (uid < 0) {
24778 throw new IllegalArgumentException("No UidRecord or uid");
24780 pendingChange.uidRecord = uidRec;
24781 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
24782 mPendingUidChanges.add(pendingChange);
24784 pendingChange = uidRec.pendingChange;
24785 // If there is no change in idle or active state, then keep whatever was pending.
24786 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
24787 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
24788 | UidRecord.CHANGE_ACTIVE));
24790 // If there is no change in cached or uncached state, then keep whatever was pending.
24791 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
24792 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
24793 | UidRecord.CHANGE_UNCACHED));
24795 // If this is a report of the UID being gone, then we shouldn't keep any previous
24796 // report of it being active or cached. (That is, a gone uid is never active,
24797 // and never cached.)
24798 if ((change & UidRecord.CHANGE_GONE) != 0) {
24799 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
24800 if (!uidRec.idle) {
24801 // If this uid is going away, and we haven't yet reported it is gone,
24803 change |= UidRecord.CHANGE_IDLE;
24807 pendingChange.change = change;
24808 pendingChange.processState = uidRec != null
24809 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
24810 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
24811 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
24812 if (uidRec != null) {
24813 uidRec.lastReportedChange = change;
24814 uidRec.updateLastDispatchedProcStateSeq(change);
24817 // Directly update the power manager, since we sit on top of it and it is critical
24818 // it be kept in sync (so wake locks will be held as soon as appropriate).
24819 if (mLocalPowerManager != null) {
24820 // TO DO: dispatch cached/uncached changes here, so we don't need to report
24821 // all proc state changes.
24822 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
24823 mLocalPowerManager.uidActive(pendingChange.uid);
24825 if ((change & UidRecord.CHANGE_IDLE) != 0) {
24826 mLocalPowerManager.uidIdle(pendingChange.uid);
24828 if ((change & UidRecord.CHANGE_GONE) != 0) {
24829 mLocalPowerManager.uidGone(pendingChange.uid);
24831 mLocalPowerManager.updateUidProcState(pendingChange.uid,
24832 pendingChange.processState);
24837 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
24838 String authority) {
24839 if (app == null) return;
24840 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
24841 UserState userState = mUserController.getStartedUserState(app.userId);
24842 if (userState == null) return;
24843 final long now = SystemClock.elapsedRealtime();
24844 Long lastReported = userState.mProviderLastReportedFg.get(authority);
24845 if (lastReported == null || lastReported < now - 60 * 1000L) {
24846 if (mSystemReady) {
24847 // Cannot touch the user stats if not system ready
24848 mUsageStatsService.reportContentProviderUsage(
24849 authority, providerPkgName, app.userId);
24851 userState.mProviderLastReportedFg.put(authority, now);
24856 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
24857 if (DEBUG_USAGE_STATS) {
24858 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
24859 + "] state changes: old = " + app.setProcState + ", new = "
24860 + app.curProcState);
24862 if (mUsageStatsService == null) {
24865 boolean isInteraction;
24866 // To avoid some abuse patterns, we are going to be careful about what we consider
24867 // to be an app interaction. Being the top activity doesn't count while the display
24868 // is sleeping, nor do short foreground services.
24869 if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
24870 isInteraction = true;
24871 app.fgInteractionTime = 0;
24872 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
24873 if (app.fgInteractionTime == 0) {
24874 app.fgInteractionTime = nowElapsed;
24875 isInteraction = false;
24877 isInteraction = nowElapsed > app.fgInteractionTime
24878 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
24881 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
24882 app.fgInteractionTime = 0;
24884 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
24885 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
24886 app.interactionEventTime = nowElapsed;
24887 String[] packages = app.getPackageList();
24888 if (packages != null) {
24889 for (int i = 0; i < packages.length; i++) {
24890 mUsageStatsService.reportEvent(packages[i], app.userId,
24891 UsageEvents.Event.SYSTEM_INTERACTION);
24895 app.reportedInteraction = isInteraction;
24896 if (!isInteraction) {
24897 app.interactionEventTime = 0;
24901 private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) {
24902 if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP
24903 && app.curProcState > ActivityManager.PROCESS_STATE_TOP) {
24904 app.lastTopTime = nowUptime;
24908 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
24909 if (proc.thread != null) {
24910 if (proc.baseProcessTracker != null) {
24911 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
24916 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
24917 ProcessRecord TOP_APP, boolean doingAll, long now) {
24918 if (app.thread == null) {
24922 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
24924 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
24928 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
24930 if (isForeground != proc.foregroundServices) {
24931 proc.foregroundServices = isForeground;
24932 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
24934 if (isForeground) {
24935 if (curProcs == null) {
24936 curProcs = new ArrayList<ProcessRecord>();
24937 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24939 if (!curProcs.contains(proc)) {
24940 curProcs.add(proc);
24941 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24942 proc.info.packageName, proc.info.uid);
24945 if (curProcs != null) {
24946 if (curProcs.remove(proc)) {
24947 mBatteryStatsService.noteEvent(
24948 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
24949 proc.info.packageName, proc.info.uid);
24950 if (curProcs.size() <= 0) {
24951 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
24957 updateOomAdjLocked();
24962 private final ActivityRecord resumedAppLocked() {
24963 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
24967 pkg = act.packageName;
24968 uid = act.info.applicationInfo.uid;
24973 // Has the UID or resumed package name changed?
24974 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
24975 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
24976 if (mCurResumedPackage != null) {
24977 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
24978 mCurResumedPackage, mCurResumedUid);
24980 mCurResumedPackage = pkg;
24981 mCurResumedUid = uid;
24982 if (mCurResumedPackage != null) {
24983 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
24984 mCurResumedPackage, mCurResumedUid);
24991 * Update OomAdj for a specific process.
24992 * @param app The process to update
24993 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
24994 * if necessary, or skip.
24995 * @return whether updateOomAdjLocked(app) was successful.
24998 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
24999 final ActivityRecord TOP_ACT = resumedAppLocked();
25000 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
25001 final boolean wasCached = app.cached;
25005 // This is the desired cached adjusment we want to tell it to use.
25006 // If our app is currently cached, we know it, and that is it. Otherwise,
25007 // we don't know it yet, and it needs to now be cached we will then
25008 // need to do a complete oom adj.
25009 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
25010 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
25011 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
25012 SystemClock.uptimeMillis());
25014 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
25015 // Changed to/from cached state, so apps after it in the LRU
25016 // list may also be changed.
25017 updateOomAdjLocked();
25023 final void updateOomAdjLocked() {
25024 final ActivityRecord TOP_ACT = resumedAppLocked();
25025 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
25026 final long now = SystemClock.uptimeMillis();
25027 final long nowElapsed = SystemClock.elapsedRealtime();
25028 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
25029 final int N = mLruProcesses.size();
25032 RuntimeException e = new RuntimeException();
25033 e.fillInStackTrace();
25034 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
25037 // Reset state in all uid records.
25038 for (int i=mActiveUids.size()-1; i>=0; i--) {
25039 final UidRecord uidRec = mActiveUids.valueAt(i);
25040 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
25041 "Starting update of " + uidRec);
25045 mStackSupervisor.rankTaskLayersIfNeeded();
25048 mNewNumServiceProcs = 0;
25049 mNewNumAServiceProcs = 0;
25051 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
25052 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
25054 // Let's determine how many processes we have running vs.
25055 // how many slots we have for background processes; we may want
25056 // to put multiple processes in a slot of there are enough of
25058 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
25059 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
25060 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
25061 if (numEmptyProcs > cachedProcessLimit) {
25062 // If there are more empty processes than our limit on cached
25063 // processes, then use the cached process limit for the factor.
25064 // This ensures that the really old empty processes get pushed
25065 // down to the bottom, so if we are running low on memory we will
25066 // have a better chance at keeping around more cached processes
25067 // instead of a gazillion empty processes.
25068 numEmptyProcs = cachedProcessLimit;
25070 int emptyFactor = numEmptyProcs/numSlots;
25071 if (emptyFactor < 1) emptyFactor = 1;
25072 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
25073 if (cachedFactor < 1) cachedFactor = 1;
25074 int stepCached = 0;
25078 int numTrimming = 0;
25080 mNumNonCachedProcs = 0;
25081 mNumCachedHiddenProcs = 0;
25083 // First update the OOM adjustment for each of the
25084 // application processes based on their current state.
25085 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
25086 int nextCachedAdj = curCachedAdj+1;
25087 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
25088 int nextEmptyAdj = curEmptyAdj+2;
25090 boolean retryCycles = false;
25092 // need to reset cycle state before calling computeOomAdjLocked because of service connections
25093 for (int i=N-1; i>=0; i--) {
25094 ProcessRecord app = mLruProcesses.get(i);
25095 app.containsCycle = false;
25097 for (int i=N-1; i>=0; i--) {
25098 ProcessRecord app = mLruProcesses.get(i);
25099 if (!app.killedByAm && app.thread != null) {
25100 app.procStateChanged = false;
25101 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
25103 // if any app encountered a cycle, we need to perform an additional loop later
25104 retryCycles |= app.containsCycle;
25106 // If we haven't yet assigned the final cached adj
25107 // to the process, do that now.
25108 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
25109 switch (app.curProcState) {
25110 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
25111 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
25112 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
25113 // This process is a cached process holding activities...
25114 // assign it the next cached value for that type, and then
25115 // step that cached level.
25116 app.curRawAdj = curCachedAdj;
25117 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
25118 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
25119 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
25121 if (curCachedAdj != nextCachedAdj) {
25123 if (stepCached >= cachedFactor) {
25125 curCachedAdj = nextCachedAdj;
25126 nextCachedAdj += 2;
25127 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25128 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
25134 // For everything else, assign next empty cached process
25135 // level and bump that up. Note that this means that
25136 // long-running services that have dropped down to the
25137 // cached level will be treated as empty (since their process
25138 // state is still as a service), which is what we want.
25139 app.curRawAdj = curEmptyAdj;
25140 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
25141 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
25142 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
25144 if (curEmptyAdj != nextEmptyAdj) {
25146 if (stepEmpty >= emptyFactor) {
25148 curEmptyAdj = nextEmptyAdj;
25150 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25151 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
25164 // - Retry computing any process that has encountered a cycle.
25165 // - Continue retrying until no process was promoted.
25166 // - Iterate from least important to most important.
25167 int cycleCount = 0;
25168 while (retryCycles && cycleCount < 10) {
25170 retryCycles = false;
25172 for (int i=0; i<N; i++) {
25173 ProcessRecord app = mLruProcesses.get(i);
25174 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25176 app.completedAdjSeq--;
25180 for (int i=0; i<N; i++) {
25181 ProcessRecord app = mLruProcesses.get(i);
25182 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25184 if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) {
25185 retryCycles = true;
25191 for (int i=N-1; i>=0; i--) {
25192 ProcessRecord app = mLruProcesses.get(i);
25193 if (!app.killedByAm && app.thread != null) {
25194 applyOomAdjLocked(app, true, now, nowElapsed);
25196 // Count the number of process types.
25197 switch (app.curProcState) {
25198 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
25199 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
25200 mNumCachedHiddenProcs++;
25202 if (numCached > cachedProcessLimit) {
25203 app.kill("cached #" + numCached, true);
25206 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
25207 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
25208 && app.lastActivityTime < oldTime) {
25209 app.kill("empty for "
25210 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
25211 / 1000) + "s", true);
25214 if (numEmpty > emptyProcessLimit) {
25215 app.kill("empty #" + numEmpty, true);
25220 mNumNonCachedProcs++;
25224 if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
25225 // If this is an isolated process, there are no services
25226 // running in it, and it's not a special process with a
25227 // custom entry point, then the process is no longer
25228 // needed. We agressively kill these because we can by
25229 // definition not re-use the same process again, and it is
25230 // good to avoid having whatever code was running in them
25231 // left sitting around after no longer needed.
25232 app.kill("isolated not needed", true);
25234 // Keeping this process, update its uid.
25235 final UidRecord uidRec = app.uidRecord;
25236 if (uidRec != null) {
25237 uidRec.ephemeral = app.info.isInstantApp();
25238 if (uidRec.curProcState > app.curProcState) {
25239 uidRec.curProcState = app.curProcState;
25241 if (app.foregroundServices) {
25242 uidRec.foregroundServices = true;
25247 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25248 && !app.killedByAm) {
25254 incrementProcStateSeqAndNotifyAppsLocked();
25256 mNumServiceProcs = mNewNumServiceProcs;
25258 // Now determine the memory trimming level of background processes.
25259 // Unfortunately we need to start at the back of the list to do this
25260 // properly. We only do this if the number of background apps we
25261 // are managing to keep around is less than half the maximum we desire;
25262 // if we are keeping a good number around, we'll let them use whatever
25263 // memory they want.
25264 final int numCachedAndEmpty = numCached + numEmpty;
25266 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
25267 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
25268 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
25269 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
25270 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
25271 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
25273 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
25276 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
25278 // We always allow the memory level to go up (better). We only allow it to go
25279 // down if we are in a state where that is allowed, *and* the total number of processes
25280 // has gone down since last time.
25281 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
25282 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
25283 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
25284 if (memFactor > mLastMemoryLevel) {
25285 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
25286 memFactor = mLastMemoryLevel;
25287 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
25290 if (memFactor != mLastMemoryLevel) {
25291 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
25293 mLastMemoryLevel = memFactor;
25294 mLastNumProcesses = mLruProcesses.size();
25295 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
25296 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
25297 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
25298 if (mLowRamStartTime == 0) {
25299 mLowRamStartTime = now;
25303 switch (memFactor) {
25304 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
25305 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
25307 case ProcessStats.ADJ_MEM_FACTOR_LOW:
25308 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
25311 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
25314 int factor = numTrimming/3;
25316 if (mHomeProcess != null) minFactor++;
25317 if (mPreviousProcess != null) minFactor++;
25318 if (factor < minFactor) factor = minFactor;
25319 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
25320 for (int i=N-1; i>=0; i--) {
25321 ProcessRecord app = mLruProcesses.get(i);
25322 if (allChanged || app.procStateChanged) {
25323 setProcessTrackerStateLocked(app, trackerMemFactor, now);
25324 app.procStateChanged = false;
25326 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25327 && !app.killedByAm) {
25328 if (app.trimMemoryLevel < curLevel && app.thread != null) {
25330 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25331 "Trimming memory of " + app.processName + " to " + curLevel);
25332 app.thread.scheduleTrimMemory(curLevel);
25333 } catch (RemoteException e) {
25336 // For now we won't do this; our memory trimming seems
25337 // to be good enough at this point that destroying
25338 // activities causes more harm than good.
25339 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
25340 && app != mHomeProcess && app != mPreviousProcess) {
25341 // Need to do this on its own message because the stack may not
25342 // be in a consistent state at this point.
25343 // For these apps we will also finish their activities
25344 // to help them free memory.
25345 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
25349 app.trimMemoryLevel = curLevel;
25351 if (step >= factor) {
25353 switch (curLevel) {
25354 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
25355 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
25357 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
25358 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25362 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
25363 && !app.killedByAm) {
25364 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
25365 && app.thread != null) {
25367 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25368 "Trimming memory of heavy-weight " + app.processName
25369 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25370 app.thread.scheduleTrimMemory(
25371 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25372 } catch (RemoteException e) {
25375 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25377 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25378 || app.systemNoUi) && app.pendingUiClean) {
25379 // If this application is now in the background and it
25380 // had done UI, then give it the special trim level to
25381 // have it free UI resources.
25382 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
25383 if (app.trimMemoryLevel < level && app.thread != null) {
25385 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25386 "Trimming memory of bg-ui " + app.processName
25388 app.thread.scheduleTrimMemory(level);
25389 } catch (RemoteException e) {
25392 app.pendingUiClean = false;
25394 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
25396 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25397 "Trimming memory of fg " + app.processName
25398 + " to " + fgTrimLevel);
25399 app.thread.scheduleTrimMemory(fgTrimLevel);
25400 } catch (RemoteException e) {
25403 app.trimMemoryLevel = fgTrimLevel;
25407 if (mLowRamStartTime != 0) {
25408 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
25409 mLowRamStartTime = 0;
25411 for (int i=N-1; i>=0; i--) {
25412 ProcessRecord app = mLruProcesses.get(i);
25413 if (allChanged || app.procStateChanged) {
25414 setProcessTrackerStateLocked(app, trackerMemFactor, now);
25415 app.procStateChanged = false;
25417 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25418 || app.systemNoUi) && app.pendingUiClean) {
25419 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
25420 && app.thread != null) {
25422 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25423 "Trimming memory of ui hidden " + app.processName
25424 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25425 app.thread.scheduleTrimMemory(
25426 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25427 } catch (RemoteException e) {
25430 app.pendingUiClean = false;
25432 app.trimMemoryLevel = 0;
25436 if (mAlwaysFinishActivities) {
25437 // Need to do this on its own message because the stack may not
25438 // be in a consistent state at this point.
25439 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
25443 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
25446 ArrayList<UidRecord> becameIdle = null;
25448 // Update from any uid changes.
25449 if (mLocalPowerManager != null) {
25450 mLocalPowerManager.startUidChanges();
25452 for (int i=mActiveUids.size()-1; i>=0; i--) {
25453 final UidRecord uidRec = mActiveUids.valueAt(i);
25454 int uidChange = UidRecord.CHANGE_PROCSTATE;
25455 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
25456 && (uidRec.setProcState != uidRec.curProcState
25457 || uidRec.setWhitelist != uidRec.curWhitelist)) {
25458 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
25459 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
25460 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
25461 + " to " + uidRec.curWhitelist);
25462 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
25463 && !uidRec.curWhitelist) {
25464 // UID is now in the background (and not on the temp whitelist). Was it
25465 // previously in the foreground (or on the temp whitelist)?
25466 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
25467 || uidRec.setWhitelist) {
25468 uidRec.lastBackgroundTime = nowElapsed;
25469 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
25470 // Note: the background settle time is in elapsed realtime, while
25471 // the handler time base is uptime. All this means is that we may
25472 // stop background uids later than we had intended, but that only
25473 // happens because the device was sleeping so we are okay anyway.
25474 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25475 mConstants.BACKGROUND_SETTLE_TIME);
25478 if (uidRec.idle && !uidRec.setIdle) {
25479 uidChange = UidRecord.CHANGE_IDLE;
25480 if (becameIdle == null) {
25481 becameIdle = new ArrayList<>();
25483 becameIdle.add(uidRec);
25487 uidChange = UidRecord.CHANGE_ACTIVE;
25488 EventLogTags.writeAmUidActive(uidRec.uid);
25489 uidRec.idle = false;
25491 uidRec.lastBackgroundTime = 0;
25493 final boolean wasCached = uidRec.setProcState
25494 > ActivityManager.PROCESS_STATE_RECEIVER;
25495 final boolean isCached = uidRec.curProcState
25496 > ActivityManager.PROCESS_STATE_RECEIVER;
25497 if (wasCached != isCached ||
25498 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
25499 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
25501 uidRec.setProcState = uidRec.curProcState;
25502 uidRec.setWhitelist = uidRec.curWhitelist;
25503 uidRec.setIdle = uidRec.idle;
25504 enqueueUidChangeLocked(uidRec, -1, uidChange);
25505 noteUidProcessState(uidRec.uid, uidRec.curProcState);
25506 if (uidRec.foregroundServices) {
25507 mServices.foregroundServiceProcStateChangedLocked(uidRec);
25511 if (mLocalPowerManager != null) {
25512 mLocalPowerManager.finishUidChanges();
25515 if (becameIdle != null) {
25516 // If we have any new uids that became idle this time, we need to make sure
25517 // they aren't left with running services.
25518 for (int i = becameIdle.size() - 1; i >= 0; i--) {
25519 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
25523 if (mProcessStats.shouldWriteNowLocked(now)) {
25524 mHandler.post(new Runnable() {
25525 @Override public void run() {
25526 synchronized (ActivityManagerService.this) {
25527 mProcessStats.writeStateAsyncLocked();
25533 if (DEBUG_OOM_ADJ) {
25534 final long duration = SystemClock.uptimeMillis() - now;
25536 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
25537 new RuntimeException("here").fillInStackTrace());
25539 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
25545 public void makePackageIdle(String packageName, int userId) {
25546 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
25547 != PackageManager.PERMISSION_GRANTED) {
25548 String msg = "Permission Denial: makePackageIdle() from pid="
25549 + Binder.getCallingPid()
25550 + ", uid=" + Binder.getCallingUid()
25551 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
25553 throw new SecurityException(msg);
25555 final int callingPid = Binder.getCallingPid();
25556 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
25557 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
25558 long callingId = Binder.clearCallingIdentity();
25559 synchronized(this) {
25561 IPackageManager pm = AppGlobals.getPackageManager();
25564 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
25565 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
25566 } catch (RemoteException e) {
25568 if (pkgUid == -1) {
25569 throw new IllegalArgumentException("Unknown package name " + packageName);
25572 if (mLocalPowerManager != null) {
25573 mLocalPowerManager.startUidChanges();
25575 final int appId = UserHandle.getAppId(pkgUid);
25576 final int N = mActiveUids.size();
25577 for (int i=N-1; i>=0; i--) {
25578 final UidRecord uidRec = mActiveUids.valueAt(i);
25579 final long bgTime = uidRec.lastBackgroundTime;
25580 if (bgTime > 0 && !uidRec.idle) {
25581 if (UserHandle.getAppId(uidRec.uid) == appId) {
25582 if (userId == UserHandle.USER_ALL ||
25583 userId == UserHandle.getUserId(uidRec.uid)) {
25584 EventLogTags.writeAmUidIdle(uidRec.uid);
25585 uidRec.idle = true;
25586 uidRec.setIdle = true;
25587 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
25588 + " from package " + packageName + " user " + userId);
25589 doStopUidLocked(uidRec.uid, uidRec);
25595 if (mLocalPowerManager != null) {
25596 mLocalPowerManager.finishUidChanges();
25598 Binder.restoreCallingIdentity(callingId);
25603 final void idleUids() {
25604 synchronized (this) {
25605 final int N = mActiveUids.size();
25609 final long nowElapsed = SystemClock.elapsedRealtime();
25610 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
25612 if (mLocalPowerManager != null) {
25613 mLocalPowerManager.startUidChanges();
25615 for (int i=N-1; i>=0; i--) {
25616 final UidRecord uidRec = mActiveUids.valueAt(i);
25617 final long bgTime = uidRec.lastBackgroundTime;
25618 if (bgTime > 0 && !uidRec.idle) {
25619 if (bgTime <= maxBgTime) {
25620 EventLogTags.writeAmUidIdle(uidRec.uid);
25621 uidRec.idle = true;
25622 uidRec.setIdle = true;
25623 doStopUidLocked(uidRec.uid, uidRec);
25625 if (nextTime == 0 || nextTime > bgTime) {
25631 if (mLocalPowerManager != null) {
25632 mLocalPowerManager.finishUidChanges();
25634 if (nextTime > 0) {
25635 mHandler.removeMessages(IDLE_UIDS_MSG);
25636 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25637 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
25643 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
25644 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
25645 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
25649 void incrementProcStateSeqAndNotifyAppsLocked() {
25650 if (mWaitForNetworkTimeoutMs <= 0) {
25653 // Used for identifying which uids need to block for network.
25654 ArrayList<Integer> blockingUids = null;
25655 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
25656 final UidRecord uidRec = mActiveUids.valueAt(i);
25657 // If the network is not restricted for uid, then nothing to do here.
25658 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
25661 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
25664 // If process state is not changed, then there's nothing to do.
25665 if (uidRec.setProcState == uidRec.curProcState) {
25668 final int blockState = getBlockStateForUid(uidRec);
25669 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
25670 // there's nothing the app needs to do in this scenario.
25671 if (blockState == NETWORK_STATE_NO_CHANGE) {
25674 synchronized (uidRec.networkStateLock) {
25675 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
25676 if (blockState == NETWORK_STATE_BLOCK) {
25677 if (blockingUids == null) {
25678 blockingUids = new ArrayList<>();
25680 blockingUids.add(uidRec.uid);
25682 if (DEBUG_NETWORK) {
25683 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
25684 + " threads for uid: " + uidRec);
25686 if (uidRec.waitingForNetwork) {
25687 uidRec.networkStateLock.notifyAll();
25693 // There are no uids that need to block, so nothing more to do.
25694 if (blockingUids == null) {
25698 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
25699 final ProcessRecord app = mLruProcesses.get(i);
25700 if (!blockingUids.contains(app.uid)) {
25703 if (!app.killedByAm && app.thread != null) {
25704 final UidRecord uidRec = mActiveUids.get(app.uid);
25706 if (DEBUG_NETWORK) {
25707 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
25710 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
25711 } catch (RemoteException ignored) {
25718 * Checks if the uid is coming from background to foreground or vice versa and returns
25719 * appropriate block state based on this.
25721 * @return blockState based on whether the uid is coming from background to foreground or
25722 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
25723 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
25724 * {@link #NETWORK_STATE_NO_CHANGE}.
25727 int getBlockStateForUid(UidRecord uidRec) {
25728 // Denotes whether uid's process state is currently allowed network access.
25729 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
25730 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
25731 // Denotes whether uid's process state was previously allowed network access.
25732 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
25733 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
25735 // When the uid is coming to foreground, AMS should inform the app thread that it should
25736 // block for the network rules to get updated before launching an activity.
25737 if (!wasAllowed && isAllowed) {
25738 return NETWORK_STATE_BLOCK;
25740 // When the uid is going to background, AMS should inform the app thread that if an
25741 // activity launch is blocked for the network rules to get updated, it should be unblocked.
25742 if (wasAllowed && !isAllowed) {
25743 return NETWORK_STATE_UNBLOCK;
25745 return NETWORK_STATE_NO_CHANGE;
25748 final void runInBackgroundDisabled(int uid) {
25749 synchronized (this) {
25750 UidRecord uidRec = mActiveUids.get(uid);
25751 if (uidRec != null) {
25752 // This uid is actually running... should it be considered background now?
25754 doStopUidLocked(uidRec.uid, uidRec);
25757 // This uid isn't actually running... still send a report about it being "stopped".
25758 doStopUidLocked(uid, null);
25764 * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
25766 void doStopUidForIdleUidsLocked() {
25767 final int size = mActiveUids.size();
25768 for (int i = 0; i < size; i++) {
25769 final int uid = mActiveUids.keyAt(i);
25770 if (UserHandle.isCore(uid)) {
25773 final UidRecord uidRec = mActiveUids.valueAt(i);
25774 if (!uidRec.idle) {
25777 doStopUidLocked(uidRec.uid, uidRec);
25781 final void doStopUidLocked(int uid, final UidRecord uidRec) {
25782 mServices.stopInBackgroundLocked(uid);
25783 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
25787 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25790 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
25791 long duration, String tag) {
25792 if (DEBUG_WHITELISTS) {
25793 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
25794 + targetUid + ", " + duration + ")");
25797 synchronized (mPidsSelfLocked) {
25798 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
25800 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
25804 if (!pr.whitelistManager) {
25805 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
25806 != PackageManager.PERMISSION_GRANTED) {
25807 if (DEBUG_WHITELISTS) {
25808 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
25809 + ": pid " + callerPid + " is not allowed");
25816 tempWhitelistUidLocked(targetUid, duration, tag);
25820 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25823 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
25824 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
25825 setUidTempWhitelistStateLocked(targetUid, true);
25826 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
25829 void pushTempWhitelist() {
25831 final PendingTempWhitelist[] list;
25833 // First copy out the pending changes... we need to leave them in the map for now,
25834 // in case someone needs to check what is coming up while we don't have the lock held.
25835 synchronized(this) {
25836 N = mPendingTempWhitelist.size();
25837 list = new PendingTempWhitelist[N];
25838 for (int i = 0; i < N; i++) {
25839 list[i] = mPendingTempWhitelist.valueAt(i);
25843 // Now safely dispatch changes to device idle controller.
25844 for (int i = 0; i < N; i++) {
25845 PendingTempWhitelist ptw = list[i];
25846 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
25847 ptw.duration, true, ptw.tag);
25850 // And now we can safely remove them from the map.
25851 synchronized(this) {
25852 for (int i = 0; i < N; i++) {
25853 PendingTempWhitelist ptw = list[i];
25854 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
25855 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
25856 mPendingTempWhitelist.removeAt(index);
25863 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
25864 boolean changed = false;
25865 for (int i=mActiveUids.size()-1; i>=0; i--) {
25866 final UidRecord uidRec = mActiveUids.valueAt(i);
25867 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
25868 uidRec.curWhitelist = onWhitelist;
25873 updateOomAdjLocked();
25878 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
25879 boolean changed = false;
25880 final UidRecord uidRec = mActiveUids.get(uid);
25881 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
25882 uidRec.curWhitelist = onWhitelist;
25883 updateOomAdjLocked();
25887 final void trimApplications() {
25888 synchronized (this) {
25889 trimApplicationsLocked();
25893 final void trimApplicationsLocked() {
25894 // First remove any unused application processes whose package
25895 // has been removed.
25896 for (int i=mRemovedProcesses.size()-1; i>=0; i--) {
25897 final ProcessRecord app = mRemovedProcesses.get(i);
25898 if (app.activities.size() == 0 && app.recentTasks.size() == 0
25899 && app.curReceivers.isEmpty() && app.services.size() == 0) {
25901 TAG, "Exiting empty application process "
25902 + app.toShortString() + " ("
25903 + (app.thread != null ? app.thread.asBinder() : null)
25905 if (app.pid > 0 && app.pid != MY_PID) {
25906 app.kill("empty", false);
25907 } else if (app.thread != null) {
25909 app.thread.scheduleExit();
25910 } catch (Exception e) {
25911 // Ignore exceptions.
25914 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
25915 mRemovedProcesses.remove(i);
25917 if (app.persistent) {
25918 addAppLocked(app.info, null, false, null /* ABI override */);
25923 // Now update the oom adj for all processes. Don't skip this, since other callers
25924 // might be depending on it.
25925 updateOomAdjLocked();
25928 /** This method sends the specified signal to each of the persistent apps */
25929 public void signalPersistentProcesses(int sig) throws RemoteException {
25930 if (sig != SIGNAL_USR1) {
25931 throw new SecurityException("Only SIGNAL_USR1 is allowed");
25934 synchronized (this) {
25935 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
25936 != PackageManager.PERMISSION_GRANTED) {
25937 throw new SecurityException("Requires permission "
25938 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
25941 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
25942 ProcessRecord r = mLruProcesses.get(i);
25943 if (r.thread != null && r.persistent) {
25944 sendSignal(r.pid, sig);
25950 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
25951 if (proc == null || proc == mProfileProc) {
25952 proc = mProfileProc;
25953 profileType = mProfileType;
25954 clearProfilerLocked();
25956 if (proc == null) {
25960 proc.thread.profilerControl(false, null, profileType);
25961 } catch (RemoteException e) {
25962 throw new IllegalStateException("Process disappeared");
25966 private void clearProfilerLocked() {
25967 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
25969 mProfilerInfo.profileFd.close();
25970 } catch (IOException e) {
25973 mProfileApp = null;
25974 mProfileProc = null;
25975 mProfilerInfo = null;
25978 public boolean profileControl(String process, int userId, boolean start,
25979 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
25982 synchronized (this) {
25983 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25984 // its own permission.
25985 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25986 != PackageManager.PERMISSION_GRANTED) {
25987 throw new SecurityException("Requires permission "
25988 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25991 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
25992 throw new IllegalArgumentException("null profile info or fd");
25995 ProcessRecord proc = null;
25996 if (process != null) {
25997 proc = findProcessLocked(process, userId, "profileControl");
26000 if (start && (proc == null || proc.thread == null)) {
26001 throw new IllegalArgumentException("Unknown process: " + process);
26005 stopProfilerLocked(null, 0);
26006 setProfileApp(proc.info, proc.processName, profilerInfo);
26007 mProfileProc = proc;
26008 mProfileType = profileType;
26009 ParcelFileDescriptor fd = profilerInfo.profileFd;
26012 } catch (IOException e) {
26015 profilerInfo.profileFd = fd;
26016 proc.thread.profilerControl(start, profilerInfo, profileType);
26019 mProfilerInfo.profileFd.close();
26020 } catch (IOException e) {
26022 mProfilerInfo.profileFd = null;
26024 if (proc.pid == MY_PID) {
26025 // When profiling the system server itself, avoid closing the file
26026 // descriptor, as profilerControl will not create a copy.
26027 // Note: it is also not correct to just set profileFd to null, as the
26028 // whole ProfilerInfo instance is passed down!
26029 profilerInfo = null;
26032 stopProfilerLocked(proc, profileType);
26033 if (profilerInfo != null && profilerInfo.profileFd != null) {
26035 profilerInfo.profileFd.close();
26036 } catch (IOException e) {
26043 } catch (RemoteException e) {
26044 throw new IllegalStateException("Process disappeared");
26046 if (profilerInfo != null && profilerInfo.profileFd != null) {
26048 profilerInfo.profileFd.close();
26049 } catch (IOException e) {
26055 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
26056 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
26057 userId, true, ALLOW_FULL_ONLY, callName, null);
26058 ProcessRecord proc = null;
26060 int pid = Integer.parseInt(process);
26061 synchronized (mPidsSelfLocked) {
26062 proc = mPidsSelfLocked.get(pid);
26064 } catch (NumberFormatException e) {
26067 if (proc == null) {
26068 ArrayMap<String, SparseArray<ProcessRecord>> all
26069 = mProcessNames.getMap();
26070 SparseArray<ProcessRecord> procs = all.get(process);
26071 if (procs != null && procs.size() > 0) {
26072 proc = procs.valueAt(0);
26073 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
26074 for (int i=1; i<procs.size(); i++) {
26075 ProcessRecord thisProc = procs.valueAt(i);
26076 if (thisProc.userId == userId) {
26088 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
26089 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
26092 synchronized (this) {
26093 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
26094 // its own permission (same as profileControl).
26095 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26096 != PackageManager.PERMISSION_GRANTED) {
26097 throw new SecurityException("Requires permission "
26098 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26102 throw new IllegalArgumentException("null fd");
26105 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
26106 if (proc == null || proc.thread == null) {
26107 throw new IllegalArgumentException("Unknown process: " + process);
26110 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26111 if (!isDebuggable) {
26112 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26113 throw new SecurityException("Process not debuggable: " + proc);
26117 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
26121 } catch (RemoteException e) {
26122 throw new IllegalStateException("Process disappeared");
26127 } catch (IOException e) {
26134 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
26135 String reportPackage) {
26136 if (processName != null) {
26137 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
26138 "setDumpHeapDebugLimit()");
26140 synchronized (mPidsSelfLocked) {
26141 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
26142 if (proc == null) {
26143 throw new SecurityException("No process found for calling pid "
26144 + Binder.getCallingPid());
26146 if (!Build.IS_DEBUGGABLE
26147 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26148 throw new SecurityException("Not running a debuggable build");
26150 processName = proc.processName;
26152 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
26153 throw new SecurityException("Package " + reportPackage + " is not running in "
26158 synchronized (this) {
26159 if (maxMemSize > 0) {
26160 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
26163 mMemWatchProcesses.remove(processName, uid);
26165 mMemWatchProcesses.getMap().remove(processName);
26172 public void dumpHeapFinished(String path) {
26173 synchronized (this) {
26174 if (Binder.getCallingPid() != mMemWatchDumpPid) {
26175 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
26176 + " does not match last pid " + mMemWatchDumpPid);
26179 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
26180 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
26181 + " does not match last path " + mMemWatchDumpFile);
26184 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
26185 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
26187 // Forced gc to clean up the remnant hprof fd.
26188 Runtime.getRuntime().gc();
26192 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
26193 public void monitor() {
26194 synchronized (this) { }
26197 void onCoreSettingsChange(Bundle settings) {
26198 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26199 ProcessRecord processRecord = mLruProcesses.get(i);
26201 if (processRecord.thread != null) {
26202 processRecord.thread.setCoreSettings(settings);
26204 } catch (RemoteException re) {
26210 // Multi-user methods
26213 * Start user, if its not already running, but don't bring it to foreground.
26216 public boolean startUserInBackground(final int userId) {
26217 return startUserInBackgroundWithListener(userId, null);
26221 public boolean startUserInBackgroundWithListener(final int userId,
26222 @Nullable IProgressListener unlockListener) {
26223 return mUserController.startUser(userId, /* foreground */ false, unlockListener);
26227 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
26228 return mUserController.unlockUser(userId, token, secret, listener);
26232 public boolean switchUser(final int targetUserId) {
26233 return mUserController.switchUser(targetUserId);
26237 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
26238 return mUserController.stopUser(userId, force, callback);
26242 public UserInfo getCurrentUser() {
26243 return mUserController.getCurrentUser();
26246 String getStartedUserState(int userId) {
26247 final UserState userState = mUserController.getStartedUserState(userId);
26248 return UserState.stateToString(userState.state);
26252 public boolean isUserRunning(int userId, int flags) {
26253 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
26254 && checkCallingPermission(INTERACT_ACROSS_USERS)
26255 != PackageManager.PERMISSION_GRANTED) {
26256 String msg = "Permission Denial: isUserRunning() from pid="
26257 + Binder.getCallingPid()
26258 + ", uid=" + Binder.getCallingUid()
26259 + " requires " + INTERACT_ACROSS_USERS;
26261 throw new SecurityException(msg);
26263 return mUserController.isUserRunning(userId, flags);
26267 public int[] getRunningUserIds() {
26268 if (checkCallingPermission(INTERACT_ACROSS_USERS)
26269 != PackageManager.PERMISSION_GRANTED) {
26270 String msg = "Permission Denial: isUserRunning() from pid="
26271 + Binder.getCallingPid()
26272 + ", uid=" + Binder.getCallingUid()
26273 + " requires " + INTERACT_ACROSS_USERS;
26275 throw new SecurityException(msg);
26277 return mUserController.getStartedUserArray();
26281 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
26282 mUserController.registerUserSwitchObserver(observer, name);
26286 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
26287 mUserController.unregisterUserSwitchObserver(observer);
26290 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
26291 if (info == null) return null;
26292 ApplicationInfo newInfo = new ApplicationInfo(info);
26293 newInfo.initForUser(userId);
26297 public boolean isUserStopped(int userId) {
26298 return mUserController.getStartedUserState(userId) == null;
26301 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
26303 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
26307 ActivityInfo info = new ActivityInfo(aInfo);
26308 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
26312 private boolean processSanityChecksLocked(ProcessRecord process) {
26313 if (process == null || process.thread == null) {
26317 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26318 if (!isDebuggable) {
26319 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26327 public boolean startBinderTracking() throws RemoteException {
26328 synchronized (this) {
26329 mBinderTransactionTrackingEnabled = true;
26330 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26331 // permission (same as profileControl).
26332 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26333 != PackageManager.PERMISSION_GRANTED) {
26334 throw new SecurityException("Requires permission "
26335 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26338 for (int i = 0; i < mLruProcesses.size(); i++) {
26339 ProcessRecord process = mLruProcesses.get(i);
26340 if (!processSanityChecksLocked(process)) {
26344 process.thread.startBinderTracking();
26345 } catch (RemoteException e) {
26346 Log.v(TAG, "Process disappared");
26353 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
26355 synchronized (this) {
26356 mBinderTransactionTrackingEnabled = false;
26357 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26358 // permission (same as profileControl).
26359 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26360 != PackageManager.PERMISSION_GRANTED) {
26361 throw new SecurityException("Requires permission "
26362 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26366 throw new IllegalArgumentException("null fd");
26369 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
26370 pw.println("Binder transaction traces for all processes.\n");
26371 for (ProcessRecord process : mLruProcesses) {
26372 if (!processSanityChecksLocked(process)) {
26376 pw.println("Traces for process: " + process.processName);
26379 TransferPipe tp = new TransferPipe();
26381 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
26382 tp.go(fd.getFileDescriptor());
26386 } catch (IOException e) {
26387 pw.println("Failure while dumping IPC traces from " + process +
26388 ". Exception: " + e);
26390 } catch (RemoteException e) {
26391 pw.println("Got a RemoteException while dumping IPC traces from " +
26392 process + ". Exception: " + e);
26403 } catch (IOException e) {
26410 final class LocalService extends ActivityManagerInternal {
26412 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
26413 int targetUserId) {
26414 synchronized (ActivityManagerService.this) {
26415 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
26416 targetPkg, intent, null, targetUserId);
26421 public String checkContentProviderAccess(String authority, int userId) {
26422 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
26426 public void onWakefulnessChanged(int wakefulness) {
26427 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
26431 public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
26432 String processName, String abiOverride, int uid, Runnable crashHandler) {
26433 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
26434 processName, abiOverride, uid, crashHandler);
26438 public SleepToken acquireSleepToken(String tag, int displayId) {
26439 Preconditions.checkNotNull(tag);
26440 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
26444 public ComponentName getHomeActivityForUser(int userId) {
26445 synchronized (ActivityManagerService.this) {
26446 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
26447 return homeActivity == null ? null : homeActivity.realActivity;
26452 public void onUserRemoved(int userId) {
26453 synchronized (ActivityManagerService.this) {
26454 ActivityManagerService.this.onUserStoppedLocked(userId);
26456 mBatteryStatsService.onUserRemoved(userId);
26457 mUserController.onUserRemoved(userId);
26461 public void onLocalVoiceInteractionStarted(IBinder activity,
26462 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
26463 synchronized (ActivityManagerService.this) {
26464 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
26465 voiceSession, voiceInteractor);
26470 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
26471 synchronized (ActivityManagerService.this) {
26472 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
26473 reasons, timestamp);
26478 public void notifyAppTransitionFinished() {
26479 synchronized (ActivityManagerService.this) {
26480 mStackSupervisor.notifyAppTransitionDone();
26485 public void notifyAppTransitionCancelled() {
26486 synchronized (ActivityManagerService.this) {
26487 mStackSupervisor.notifyAppTransitionDone();
26492 public List<IBinder> getTopVisibleActivities() {
26493 synchronized (ActivityManagerService.this) {
26494 return mStackSupervisor.getTopVisibleActivities();
26499 public void notifyDockedStackMinimizedChanged(boolean minimized) {
26500 synchronized (ActivityManagerService.this) {
26501 mStackSupervisor.setDockedStackMinimized(minimized);
26506 public void killForegroundAppsForUser(int userHandle) {
26507 synchronized (ActivityManagerService.this) {
26508 final ArrayList<ProcessRecord> procs = new ArrayList<>();
26509 final int NP = mProcessNames.getMap().size();
26510 for (int ip = 0; ip < NP; ip++) {
26511 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
26512 final int NA = apps.size();
26513 for (int ia = 0; ia < NA; ia++) {
26514 final ProcessRecord app = apps.valueAt(ia);
26515 if (app.persistent) {
26516 // We don't kill persistent processes.
26521 } else if (app.userId == userHandle && app.foregroundActivities) {
26522 app.removed = true;
26528 final int N = procs.size();
26529 for (int i = 0; i < N; i++) {
26530 removeProcessLocked(procs.get(i), false, true, "kill all fg");
26536 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
26538 if (!(target instanceof PendingIntentRecord)) {
26539 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
26542 synchronized (ActivityManagerService.this) {
26543 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
26548 public void setDeviceIdleWhitelist(int[] allAppids, int[] exceptIdleAppids) {
26549 synchronized (ActivityManagerService.this) {
26550 mDeviceIdleWhitelist = allAppids;
26551 mDeviceIdleExceptIdleWhitelist = exceptIdleAppids;
26556 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
26557 synchronized (ActivityManagerService.this) {
26558 mDeviceIdleTempWhitelist = appids;
26559 setAppIdTempWhitelistStateLocked(changingAppId, adding);
26564 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
26566 Preconditions.checkNotNull(values, "Configuration must not be null");
26567 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
26568 synchronized (ActivityManagerService.this) {
26569 updateConfigurationLocked(values, null, false, true, userId,
26570 false /* deferResume */);
26575 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
26577 Preconditions.checkNotNull(intents, "intents");
26578 final String[] resolvedTypes = new String[intents.length];
26580 // UID of the package on user userId.
26581 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
26582 // packageUid may not be initialized.
26583 int packageUid = 0;
26584 final long ident = Binder.clearCallingIdentity();
26587 for (int i = 0; i < intents.length; i++) {
26589 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
26592 packageUid = AppGlobals.getPackageManager().getPackageUid(
26593 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
26594 } catch (RemoteException e) {
26595 // Shouldn't happen.
26597 Binder.restoreCallingIdentity(ident);
26600 synchronized (ActivityManagerService.this) {
26601 return mActivityStartController.startActivitiesInPackage(
26602 packageUid, packageName,
26603 intents, resolvedTypes, null /* resultTo */,
26604 SafeActivityOptions.fromBundle(bOptions), userId,
26605 false /* validateIncomingUser */, null /* originatingPendingIntent */);
26610 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
26611 Intent intent, Bundle options, int userId) {
26612 return ActivityManagerService.this.startActivityAsUser(
26613 caller, callerPacakge, intent,
26614 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
26615 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
26616 false /*validateIncomingUser*/);
26620 public int getUidProcessState(int uid) {
26621 return getUidState(uid);
26625 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
26626 synchronized (ActivityManagerService.this) {
26628 // We might change the visibilities here, so prepare an empty app transition which
26629 // might be overridden later if we actually change visibilities.
26630 final boolean wasTransitionSet =
26631 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
26632 if (!wasTransitionSet) {
26633 mWindowManager.prepareAppTransition(TRANSIT_NONE,
26634 false /* alwaysKeepCurrent */);
26636 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26638 // If there was a transition set already we don't want to interfere with it as we
26639 // might be starting it too early.
26640 if (!wasTransitionSet) {
26641 mWindowManager.executeAppTransition();
26644 if (callback != null) {
26650 public boolean isSystemReady() {
26651 // no need to synchronize(this) just to read & return the value
26652 return mSystemReady;
26656 public void notifyKeyguardTrustedChanged() {
26657 synchronized (ActivityManagerService.this) {
26658 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
26659 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26665 * Sets if the given pid has an overlay UI or not.
26667 * @param pid The pid we are setting overlay UI for.
26668 * @param hasOverlayUi True if the process has overlay UI.
26669 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
26672 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
26673 synchronized (ActivityManagerService.this) {
26674 final ProcessRecord pr;
26675 synchronized (mPidsSelfLocked) {
26676 pr = mPidsSelfLocked.get(pid);
26678 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
26682 if (pr.hasOverlayUi == hasOverlayUi) {
26685 pr.hasOverlayUi = hasOverlayUi;
26686 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
26687 updateOomAdjLocked(pr, true);
26692 public void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
26693 ActivityManagerService.this.setRunningRemoteAnimation(pid, runningRemoteAnimation);
26697 * Called after the network policy rules are updated by
26698 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
26699 * and {@param procStateSeq}.
26702 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
26703 if (DEBUG_NETWORK) {
26704 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
26705 + uid + " seq: " + procStateSeq);
26708 synchronized (ActivityManagerService.this) {
26709 record = mActiveUids.get(uid);
26710 if (record == null) {
26711 if (DEBUG_NETWORK) {
26712 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
26713 + " procStateSeq: " + procStateSeq);
26718 synchronized (record.networkStateLock) {
26719 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26720 if (DEBUG_NETWORK) {
26721 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
26722 + " been handled for uid: " + uid);
26726 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
26727 if (record.curProcStateSeq > procStateSeq) {
26728 if (DEBUG_NETWORK) {
26729 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
26730 + ", curProcstateSeq: " + record.curProcStateSeq
26731 + ", procStateSeq: " + procStateSeq);
26735 if (record.waitingForNetwork) {
26736 if (DEBUG_NETWORK) {
26737 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
26738 + ", procStateSeq: " + procStateSeq);
26740 record.networkStateLock.notifyAll();
26746 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
26747 synchronized (ActivityManagerService.this) {
26748 mActiveVoiceInteractionServiceComponent = component;
26753 * Called after virtual display Id is updated by
26754 * {@link com.android.server.vr.Vr2dDisplay} with a specific
26755 * {@param vrVr2dDisplayId}.
26758 public void setVr2dDisplayId(int vr2dDisplayId) {
26760 Slog.d(TAG, "setVr2dDisplayId called for: " +
26763 synchronized (ActivityManagerService.this) {
26764 mVr2dDisplayId = vr2dDisplayId;
26769 public void saveANRState(String reason) {
26770 synchronized (ActivityManagerService.this) {
26771 final StringWriter sw = new StringWriter();
26772 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
26773 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
26774 if (reason != null) {
26775 pw.println(" Reason: " + reason);
26778 mActivityStartController.dump(pw, " ", null);
26780 pw.println("-------------------------------------------------------------------------------");
26781 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
26782 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
26787 mLastANRState = sw.toString();
26792 public void clearSavedANRState() {
26793 synchronized (ActivityManagerService.this) {
26794 mLastANRState = null;
26799 public void setFocusedActivity(IBinder token) {
26800 synchronized (ActivityManagerService.this) {
26801 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
26803 throw new IllegalArgumentException(
26804 "setFocusedActivity: No activity record matching token=" + token);
26806 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
26807 r, "setFocusedActivity")) {
26808 mStackSupervisor.resumeFocusedStackTopActivityLocked();
26814 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
26815 synchronized (ActivityManagerService.this) {
26816 if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
26817 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
26818 if (types == null) {
26822 types = new ArrayMap<>();
26823 mAllowAppSwitchUids.put(userId, types);
26826 types.remove(type);
26828 types.put(type, uid);
26835 public boolean isRuntimeRestarted() {
26836 return mSystemServiceManager.isRuntimeRestarted();
26840 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
26841 if (packageName == null) return false;
26843 synchronized (ActivityManagerService.this) {
26844 for (int i = 0; i < mLruProcesses.size(); i++) {
26845 final ProcessRecord processRecord = mLruProcesses.get(i);
26846 if (processRecord.uid == uid) {
26847 for (int j = 0; j < processRecord.activities.size(); j++) {
26848 final ActivityRecord activityRecord = processRecord.activities.get(j);
26849 if (packageName.equals(activityRecord.packageName)) {
26860 public void registerScreenObserver(ScreenObserver observer) {
26861 mScreenObservers.add(observer);
26865 public boolean canStartMoreUsers() {
26866 return mUserController.canStartMoreUsers();
26870 public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
26871 mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
26875 public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
26876 mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
26880 public int getMaxRunningUsers() {
26881 return mUserController.mMaxRunningUsers;
26885 public boolean isCallerRecents(int callingUid) {
26886 return getRecentTasks().isCallerRecents(callingUid);
26890 public boolean isRecentsComponentHomeActivity(int userId) {
26891 return getRecentTasks().isRecentsComponentHomeActivity(userId);
26895 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
26896 ActivityManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
26900 public boolean isUidActive(int uid) {
26901 synchronized (ActivityManagerService.this) {
26902 return isUidActiveLocked(uid);
26907 public List<ProcessMemoryState> getMemoryStateForProcesses() {
26908 List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
26909 synchronized (mPidsSelfLocked) {
26910 for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
26911 final ProcessRecord r = mPidsSelfLocked.valueAt(i);
26912 final int pid = r.pid;
26913 final int uid = r.uid;
26914 final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
26915 if (memoryStat == null) {
26918 ProcessMemoryState processMemoryState =
26919 new ProcessMemoryState(uid,
26922 memoryStat.pgfault,
26923 memoryStat.pgmajfault,
26924 memoryStat.rssInBytes,
26925 memoryStat.cacheInBytes,
26926 memoryStat.swapInBytes);
26927 processMemoryStates.add(processMemoryState);
26930 return processMemoryStates;
26934 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
26935 ActivityManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
26939 public Intent getHomeIntent() {
26940 synchronized (ActivityManagerService.this) {
26941 return ActivityManagerService.this.getHomeIntent();
26946 public void notifyDefaultDisplaySizeChanged() {
26947 synchronized (ActivityManagerService.this) {
26948 if (mSystemServiceManager.isBootCompleted() && mHomeProcess != null) {
26950 // TODO: Ugly hack to unblock the release
26951 Slog.i(TAG, "Killing home process because of display size change");
26952 removeProcessLocked(mHomeProcess, false, true, "kill home screen size");
26959 * Called by app main thread to wait for the network policy rules to get updated.
26961 * @param procStateSeq The sequence number indicating the process state change that the main
26962 * thread is interested in.
26965 public void waitForNetworkStateUpdate(long procStateSeq) {
26966 final int callingUid = Binder.getCallingUid();
26967 if (DEBUG_NETWORK) {
26968 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
26971 synchronized (this) {
26972 record = mActiveUids.get(callingUid);
26973 if (record == null) {
26977 synchronized (record.networkStateLock) {
26978 if (record.lastDispatchedProcStateSeq < procStateSeq) {
26979 if (DEBUG_NETWORK) {
26980 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
26981 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
26982 + " lastProcStateSeqDispatchedToObservers: "
26983 + record.lastDispatchedProcStateSeq);
26987 if (record.curProcStateSeq > procStateSeq) {
26988 if (DEBUG_NETWORK) {
26989 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
26990 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
26991 + ", procStateSeq: " + procStateSeq);
26995 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26996 if (DEBUG_NETWORK) {
26997 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
26998 + procStateSeq + ", so no need to wait. Uid: "
26999 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
27000 + record.lastNetworkUpdatedProcStateSeq);
27005 if (DEBUG_NETWORK) {
27006 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
27007 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
27009 final long startTime = SystemClock.uptimeMillis();
27010 record.waitingForNetwork = true;
27011 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
27012 record.waitingForNetwork = false;
27013 final long totalTime = SystemClock.uptimeMillis() - startTime;
27014 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
27015 Slog.w(TAG_NETWORK, "Total time waited for network rules to get updated: "
27016 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
27017 + procStateSeq + " UidRec: " + record
27018 + " validateUidRec: " + mValidateUids.get(callingUid));
27020 } catch (InterruptedException e) {
27021 Thread.currentThread().interrupt();
27026 public void waitForBroadcastIdle(PrintWriter pw) {
27027 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
27029 boolean idle = true;
27030 synchronized (this) {
27031 for (BroadcastQueue queue : mBroadcastQueues) {
27032 if (!queue.isIdle()) {
27033 final String msg = "Waiting for queue " + queue + " to become idle...";
27043 final String msg = "All broadcast queues are idle!";
27049 SystemClock.sleep(1000);
27055 * Return the user id of the last resumed activity.
27058 public @UserIdInt int getLastResumedActivityUserId() {
27059 enforceCallingPermission(
27060 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
27061 synchronized (this) {
27062 if (mLastResumedActivity == null) {
27063 return mUserController.getCurrentUserId();
27065 return mLastResumedActivity.userId;
27070 * Kill processes for the user with id userId and that depend on the package named packageName
27073 public void killPackageDependents(String packageName, int userId) {
27074 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
27075 if (packageName == null) {
27076 throw new NullPointerException(
27077 "Cannot kill the dependents of a package without its name.");
27080 long callingId = Binder.clearCallingIdentity();
27081 IPackageManager pm = AppGlobals.getPackageManager();
27084 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
27085 } catch (RemoteException e) {
27087 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
27088 throw new IllegalArgumentException(
27089 "Cannot kill dependents of non-existing package " + packageName);
27092 synchronized(this) {
27093 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
27094 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
27095 "dep: " + packageName);
27098 Binder.restoreCallingIdentity(callingId);
27103 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
27104 CharSequence message) throws RemoteException {
27105 if (message != null) {
27106 enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
27107 "dismissKeyguard()");
27109 final long callingId = Binder.clearCallingIdentity();
27111 mKeyguardController.dismissKeyguard(token, callback, message);
27113 Binder.restoreCallingIdentity(callingId);
27118 public int restartUserInBackground(final int userId) {
27119 return mUserController.restartUser(userId, /* foreground */ false);
27123 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
27124 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
27125 "scheduleApplicationInfoChanged()");
27127 synchronized (this) {
27128 final long origId = Binder.clearCallingIdentity();
27130 updateApplicationInfoLocked(packageNames, userId);
27132 Binder.restoreCallingIdentity(origId);
27137 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
27138 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
27139 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
27140 final ProcessRecord app = mLruProcesses.get(i);
27141 if (app.thread == null) {
27145 if (userId != UserHandle.USER_ALL && app.userId != userId) {
27149 final int packageCount = app.pkgList.size();
27150 for (int j = 0; j < packageCount; j++) {
27151 final String packageName = app.pkgList.keyAt(j);
27152 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
27154 final ApplicationInfo ai = AppGlobals.getPackageManager()
27155 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
27157 app.thread.scheduleApplicationInfoChanged(ai);
27159 } catch (RemoteException e) {
27160 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
27161 packageName, app));
27166 if (updateFrameworkRes) {
27167 // Update system server components that need to know about changed overlays. Because the
27168 // overlay is applied in ActivityThread, we need to serialize through its thread too.
27169 final Executor executor = ActivityThread.currentActivityThread().getExecutor();
27170 final DisplayManagerInternal display =
27171 LocalServices.getService(DisplayManagerInternal.class);
27172 if (display != null) {
27173 executor.execute(display::onOverlayChanged);
27175 if (mWindowManager != null) {
27176 executor.execute(mWindowManager::onOverlayChanged);
27182 * Attach an agent to the specified process (proces name or PID)
27184 public void attachAgent(String process, String path) {
27186 synchronized (this) {
27187 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
27188 if (proc == null || proc.thread == null) {
27189 throw new IllegalArgumentException("Unknown process: " + process);
27192 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
27193 if (!isDebuggable) {
27194 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
27195 throw new SecurityException("Process not debuggable: " + proc);
27199 proc.thread.attachAgent(path);
27201 } catch (RemoteException e) {
27202 throw new IllegalStateException("Process disappeared");
27207 public static class Injector {
27208 private NetworkManagementInternal mNmi;
27210 public Context getContext() {
27214 public AppOpsService getAppOpsService(File file, Handler handler) {
27215 return new AppOpsService(file, handler);
27218 public Handler getUiHandler(ActivityManagerService service) {
27219 return service.new UiHandler();
27222 public boolean isNetworkRestrictedForUid(int uid) {
27223 if (ensureHasNetworkManagementInternal()) {
27224 return mNmi.isNetworkRestrictedForUid(uid);
27229 private boolean ensureHasNetworkManagementInternal() {
27230 if (mNmi == null) {
27231 mNmi = LocalServices.getService(NetworkManagementInternal.class);
27233 return mNmi != null;
27238 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
27239 throws RemoteException {
27240 synchronized (this) {
27241 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27245 final long origId = Binder.clearCallingIdentity();
27247 r.setShowWhenLocked(showWhenLocked);
27249 Binder.restoreCallingIdentity(origId);
27255 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
27256 synchronized (this) {
27257 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27261 final long origId = Binder.clearCallingIdentity();
27263 r.setTurnScreenOn(turnScreenOn);
27265 Binder.restoreCallingIdentity(origId);
27271 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
27272 throws RemoteException {
27273 enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
27274 "registerRemoteAnimations");
27275 definition.setCallingPid(Binder.getCallingPid());
27276 synchronized (this) {
27277 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27281 final long origId = Binder.clearCallingIdentity();
27283 r.registerRemoteAnimations(definition);
27285 Binder.restoreCallingIdentity(origId);
27291 public void registerRemoteAnimationForNextActivityStart(String packageName,
27292 RemoteAnimationAdapter adapter) throws RemoteException {
27293 enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
27294 "registerRemoteAnimationForNextActivityStart");
27295 adapter.setCallingPid(Binder.getCallingPid());
27296 synchronized (this) {
27297 final long origId = Binder.clearCallingIdentity();
27299 mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
27302 Binder.restoreCallingIdentity(origId);
27307 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
27309 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
27310 synchronized (this) {
27311 final long origId = Binder.clearCallingIdentity();
27313 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
27315 Binder.restoreCallingIdentity(origId);