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.CHANGE_CONFIGURATION;
20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
24 import static android.Manifest.permission.READ_FRAME_BUFFER;
25 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
26 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
27 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
28 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
29 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
30 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
32 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
33 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
34 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
35 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
36 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
37 import static android.content.pm.PackageManager.GET_PROVIDERS;
38 import static android.content.pm.PackageManager.MATCH_ANY_USER;
39 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
40 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
41 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
42 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
43 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
44 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
45 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
46 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
47 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
48 import static android.os.Build.VERSION_CODES.N;
49 import static android.os.Process.BLUETOOTH_UID;
50 import static android.os.Process.FIRST_APPLICATION_UID;
51 import static android.os.Process.FIRST_ISOLATED_UID;
52 import static android.os.Process.LAST_ISOLATED_UID;
53 import static android.os.Process.NFC_UID;
54 import static android.os.Process.PHONE_UID;
55 import static android.os.Process.PROC_CHAR;
56 import static android.os.Process.PROC_OUT_LONG;
57 import static android.os.Process.PROC_PARENS;
58 import static android.os.Process.PROC_SPACE_TERM;
59 import static android.os.Process.ProcessStartResult;
60 import static android.os.Process.ROOT_UID;
61 import static android.os.Process.SCHED_FIFO;
62 import static android.os.Process.SCHED_OTHER;
63 import static android.os.Process.SCHED_RESET_ON_FORK;
64 import static android.os.Process.SHELL_UID;
65 import static android.os.Process.SIGNAL_QUIT;
66 import static android.os.Process.SIGNAL_USR1;
67 import static android.os.Process.SYSTEM_UID;
68 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
69 import static android.os.Process.THREAD_GROUP_DEFAULT;
70 import static android.os.Process.THREAD_GROUP_TOP_APP;
71 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
72 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
73 import static android.os.Process.getFreeMemory;
74 import static android.os.Process.getTotalMemory;
75 import static android.os.Process.isThreadInProcess;
76 import static android.os.Process.killProcess;
77 import static android.os.Process.killProcessQuiet;
78 import static android.os.Process.myPid;
79 import static android.os.Process.myUid;
80 import static android.os.Process.readProcFile;
81 import static android.os.Process.removeAllProcessGroups;
82 import static android.os.Process.sendSignal;
83 import static android.os.Process.setProcessGroup;
84 import static android.os.Process.setThreadPriority;
85 import static android.os.Process.setThreadScheduler;
86 import static android.os.Process.startWebView;
87 import static android.os.Process.zygoteProcess;
88 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
89 import static android.provider.Settings.Global.DEBUG_APP;
90 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
91 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
92 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
93 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
94 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
95 import static android.provider.Settings.System.FONT_SCALE;
96 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
97 import static android.view.Display.DEFAULT_DISPLAY;
98 import static android.view.Display.INVALID_DISPLAY;
99 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
100 import static com.android.internal.util.XmlUtils.readIntAttribute;
101 import static com.android.internal.util.XmlUtils.readLongAttribute;
102 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
103 import static com.android.internal.util.XmlUtils.writeIntAttribute;
104 import static com.android.internal.util.XmlUtils.writeLongAttribute;
105 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
106 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
107 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
139 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
140 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
164 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
165 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
166 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
167 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
168 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
169 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
171 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
172 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
173 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
174 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
175 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
178 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
179 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
180 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
182 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
183 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
186 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
187 import static org.xmlpull.v1.XmlPullParser.START_TAG;
189 import android.Manifest;
190 import android.Manifest.permission;
191 import android.annotation.NonNull;
192 import android.annotation.Nullable;
193 import android.annotation.UserIdInt;
194 import android.app.Activity;
195 import android.app.ActivityManager;
196 import android.app.ActivityManager.RunningTaskInfo;
197 import android.app.ActivityManager.StackId;
198 import android.app.ActivityManager.StackInfo;
199 import android.app.ActivityManager.TaskSnapshot;
200 import android.app.ActivityManager.TaskThumbnailInfo;
201 import android.app.ActivityManagerInternal;
202 import android.app.ActivityManagerInternal.SleepToken;
203 import android.app.ActivityOptions;
204 import android.app.ActivityThread;
205 import android.app.AlertDialog;
206 import android.app.AppGlobals;
207 import android.app.AppOpsManager;
208 import android.app.ApplicationErrorReport;
209 import android.app.ApplicationThreadConstants;
210 import android.app.BroadcastOptions;
211 import android.app.ContentProviderHolder;
212 import android.app.Dialog;
213 import android.app.IActivityContainer;
214 import android.app.IActivityContainerCallback;
215 import android.app.IActivityController;
216 import android.app.IActivityManager;
217 import android.app.IAppTask;
218 import android.app.IApplicationThread;
219 import android.app.IInstrumentationWatcher;
220 import android.app.INotificationManager;
221 import android.app.IProcessObserver;
222 import android.app.IServiceConnection;
223 import android.app.IStopUserCallback;
224 import android.app.ITaskStackListener;
225 import android.app.IUiAutomationConnection;
226 import android.app.IUidObserver;
227 import android.app.IUserSwitchObserver;
228 import android.app.Instrumentation;
229 import android.app.Notification;
230 import android.app.NotificationManager;
231 import android.app.PendingIntent;
232 import android.app.PictureInPictureParams;
233 import android.app.ProfilerInfo;
234 import android.app.RemoteAction;
235 import android.app.WaitResult;
236 import android.app.admin.DevicePolicyManager;
237 import android.app.assist.AssistContent;
238 import android.app.assist.AssistStructure;
239 import android.app.backup.IBackupManager;
240 import android.app.usage.UsageEvents;
241 import android.app.usage.UsageStatsManagerInternal;
242 import android.appwidget.AppWidgetManager;
243 import android.content.ActivityNotFoundException;
244 import android.content.BroadcastReceiver;
245 import android.content.ClipData;
246 import android.content.ComponentCallbacks2;
247 import android.content.ComponentName;
248 import android.content.ContentProvider;
249 import android.content.ContentResolver;
250 import android.content.Context;
251 import android.content.DialogInterface;
252 import android.content.IContentProvider;
253 import android.content.IIntentReceiver;
254 import android.content.IIntentSender;
255 import android.content.Intent;
256 import android.content.IntentFilter;
257 import android.content.IntentSender;
258 import android.content.pm.ActivityInfo;
259 import android.content.pm.ApplicationInfo;
260 import android.content.pm.ConfigurationInfo;
261 import android.content.pm.IPackageDataObserver;
262 import android.content.pm.IPackageManager;
263 import android.content.pm.InstrumentationInfo;
264 import android.content.pm.PackageInfo;
265 import android.content.pm.PackageManager;
266 import android.content.pm.PackageManager.NameNotFoundException;
267 import android.content.pm.PackageManagerInternal;
268 import android.content.pm.ParceledListSlice;
269 import android.content.pm.PathPermission;
270 import android.content.pm.PermissionInfo;
271 import android.content.pm.ProviderInfo;
272 import android.content.pm.ResolveInfo;
273 import android.content.pm.SELinuxUtil;
274 import android.content.pm.ServiceInfo;
275 import android.content.pm.UserInfo;
276 import android.content.res.CompatibilityInfo;
277 import android.content.res.Configuration;
278 import android.content.res.Resources;
279 import android.database.ContentObserver;
280 import android.graphics.Bitmap;
281 import android.graphics.Point;
282 import android.graphics.Rect;
283 import android.location.LocationManager;
284 import android.media.audiofx.AudioEffect;
285 import android.metrics.LogMaker;
286 import android.net.Proxy;
287 import android.net.ProxyInfo;
288 import android.net.Uri;
289 import android.os.BatteryStats;
290 import android.os.Binder;
291 import android.os.Build;
292 import android.os.Bundle;
293 import android.os.Debug;
294 import android.os.DropBoxManager;
295 import android.os.Environment;
296 import android.os.FactoryTest;
297 import android.os.FileObserver;
298 import android.os.FileUtils;
299 import android.os.Handler;
300 import android.os.IBinder;
301 import android.os.IDeviceIdentifiersPolicyService;
302 import android.os.IPermissionController;
303 import android.os.IProcessInfoService;
304 import android.os.IProgressListener;
305 import android.os.LocaleList;
306 import android.os.Looper;
307 import android.os.Message;
308 import android.os.Parcel;
309 import android.os.ParcelFileDescriptor;
310 import android.os.PersistableBundle;
311 import android.os.PowerManager;
312 import android.os.PowerManagerInternal;
313 import android.os.Process;
314 import android.os.RemoteCallbackList;
315 import android.os.RemoteException;
316 import android.os.ResultReceiver;
317 import android.os.ServiceManager;
318 import android.os.ShellCallback;
319 import android.os.StrictMode;
320 import android.os.SystemClock;
321 import android.os.SystemProperties;
322 import android.os.Trace;
323 import android.os.TransactionTooLargeException;
324 import android.os.UpdateLock;
325 import android.os.UserHandle;
326 import android.os.UserManager;
327 import android.os.WorkSource;
328 import android.os.storage.IStorageManager;
329 import android.os.storage.StorageManager;
330 import android.os.storage.StorageManagerInternal;
331 import android.provider.Downloads;
332 import android.provider.Settings;
333 import android.service.voice.IVoiceInteractionSession;
334 import android.service.voice.VoiceInteractionManagerInternal;
335 import android.service.voice.VoiceInteractionSession;
336 import android.telecom.TelecomManager;
337 import android.text.TextUtils;
338 import android.text.format.DateUtils;
339 import android.text.format.Time;
340 import android.text.style.SuggestionSpan;
341 import android.util.ArrayMap;
342 import android.util.ArraySet;
343 import android.util.AtomicFile;
344 import android.util.BootTimingsTraceLog;
345 import android.util.DebugUtils;
346 import android.util.DisplayMetrics;
347 import android.util.EventLog;
348 import android.util.Log;
349 import android.util.Pair;
350 import android.util.PrintWriterPrinter;
351 import android.util.Slog;
352 import android.util.SparseArray;
353 import android.util.SparseIntArray;
354 import android.util.TimeUtils;
355 import android.util.Xml;
356 import android.view.Gravity;
357 import android.view.LayoutInflater;
358 import android.view.View;
359 import android.view.WindowManager;
361 import com.android.server.job.JobSchedulerInternal;
362 import com.google.android.collect.Lists;
363 import com.google.android.collect.Maps;
365 import com.android.internal.R;
366 import com.android.internal.annotations.GuardedBy;
367 import com.android.internal.annotations.VisibleForTesting;
368 import com.android.internal.app.AssistUtils;
369 import com.android.internal.app.DumpHeapActivity;
370 import com.android.internal.app.IAppOpsCallback;
371 import com.android.internal.app.IAppOpsService;
372 import com.android.internal.app.IVoiceInteractor;
373 import com.android.internal.app.ProcessMap;
374 import com.android.internal.app.SystemUserHomeActivity;
375 import com.android.internal.app.procstats.ProcessStats;
376 import com.android.internal.logging.MetricsLogger;
377 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
378 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
379 import com.android.internal.notification.SystemNotificationChannels;
380 import com.android.internal.os.BackgroundThread;
381 import com.android.internal.os.BatteryStatsImpl;
382 import com.android.internal.os.IResultReceiver;
383 import com.android.internal.os.ProcessCpuTracker;
384 import com.android.internal.os.TransferPipe;
385 import com.android.internal.os.Zygote;
386 import com.android.internal.policy.IKeyguardDismissCallback;
387 import com.android.internal.telephony.TelephonyIntents;
388 import com.android.internal.util.ArrayUtils;
389 import com.android.internal.util.DumpUtils;
390 import com.android.internal.util.FastPrintWriter;
391 import com.android.internal.util.FastXmlSerializer;
392 import com.android.internal.util.MemInfoReader;
393 import com.android.internal.util.Preconditions;
394 import com.android.server.AppOpsService;
395 import com.android.server.AttributeCache;
396 import com.android.server.DeviceIdleController;
397 import com.android.server.IntentResolver;
398 import com.android.server.LocalServices;
399 import com.android.server.LockGuard;
400 import com.android.server.NetworkManagementInternal;
401 import com.android.server.RescueParty;
402 import com.android.server.ServiceThread;
403 import com.android.server.SystemConfig;
404 import com.android.server.SystemService;
405 import com.android.server.SystemServiceManager;
406 import com.android.server.ThreadPriorityBooster;
407 import com.android.server.Watchdog;
408 import com.android.server.am.ActivityStack.ActivityState;
409 import com.android.server.firewall.IntentFirewall;
410 import com.android.server.pm.Installer;
411 import com.android.server.pm.Installer.InstallerException;
412 import com.android.server.statusbar.StatusBarManagerInternal;
413 import com.android.server.vr.VrManagerInternal;
414 import com.android.server.wm.PinnedStackWindowController;
415 import com.android.server.wm.WindowManagerService;
417 import org.xmlpull.v1.XmlPullParser;
418 import org.xmlpull.v1.XmlPullParserException;
419 import org.xmlpull.v1.XmlSerializer;
422 import java.io.FileDescriptor;
423 import java.io.FileInputStream;
424 import java.io.FileNotFoundException;
425 import java.io.FileOutputStream;
426 import java.io.IOException;
427 import java.io.InputStreamReader;
428 import java.io.PrintWriter;
429 import java.io.StringWriter;
430 import java.io.UnsupportedEncodingException;
431 import java.lang.ref.WeakReference;
432 import java.nio.charset.StandardCharsets;
433 import java.text.DateFormat;
434 import java.util.ArrayList;
435 import java.util.Arrays;
436 import java.util.Collections;
437 import java.util.Comparator;
438 import java.util.Date;
439 import java.util.HashMap;
440 import java.util.HashSet;
441 import java.util.Iterator;
442 import java.util.List;
443 import java.util.Locale;
444 import java.util.Map;
445 import java.util.Objects;
446 import java.util.Set;
447 import java.util.concurrent.CountDownLatch;
448 import java.util.concurrent.atomic.AtomicBoolean;
449 import java.util.concurrent.atomic.AtomicLong;
451 import dalvik.system.VMRuntime;
452 import libcore.io.IoUtils;
453 import libcore.util.EmptyArray;
455 public class ActivityManagerService extends IActivityManager.Stub
456 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
459 * Priority we boost main thread and RT of top app to.
461 public static final int TOP_APP_PRIORITY_BOOST = -10;
463 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
464 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
465 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
466 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
467 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
468 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
469 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
470 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
471 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
472 private static final String TAG_LRU = TAG + POSTFIX_LRU;
473 private static final String TAG_MU = TAG + POSTFIX_MU;
474 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
475 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
476 private static final String TAG_POWER = TAG + POSTFIX_POWER;
477 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
478 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
479 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
480 private static final String TAG_PSS = TAG + POSTFIX_PSS;
481 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
482 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
483 private static final String TAG_STACK = TAG + POSTFIX_STACK;
484 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
485 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
486 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
487 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
488 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
490 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
491 // here so that while the job scheduler can depend on AMS, the other way around
492 // need not be the case.
493 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
495 /** Control over CPU and battery monitoring */
496 // write battery stats every 30 minutes.
497 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
498 static final boolean MONITOR_CPU_USAGE = true;
499 // don't sample cpu less than every 5 seconds.
500 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
501 // wait possibly forever for next cpu sample.
502 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
503 static final boolean MONITOR_THREAD_CPU_USAGE = false;
505 // The flags that are set for all calls we make to the package manager.
506 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
508 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
510 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
512 // Amount of time after a call to stopAppSwitches() during which we will
513 // prevent further untrusted switches from happening.
514 static final long APP_SWITCH_DELAY_TIME = 5*1000;
516 // How long we wait for a launched process to attach to the activity manager
517 // before we decide it's never going to come up for real.
518 static final int PROC_START_TIMEOUT = 10*1000;
519 // How long we wait for an attached process to publish its content providers
520 // before we decide it must be hung.
521 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
523 // How long we wait for a launched process to attach to the activity manager
524 // before we decide it's never going to come up for real, when the process was
525 // started with a wrapper for instrumentation (such as Valgrind) because it
526 // could take much longer than usual.
527 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
529 // How long we allow a receiver to run before giving up on it.
530 static final int BROADCAST_FG_TIMEOUT = 10*1000;
531 static final int BROADCAST_BG_TIMEOUT = 60*1000;
533 // How long we wait until we timeout on key dispatching.
534 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
536 // How long we wait until we timeout on key dispatching during instrumentation.
537 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
539 // How long to wait in getAssistContextExtras for the activity and foreground services
540 // to respond with the result.
541 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
543 // How long top wait when going through the modern assist (which doesn't need to block
544 // on getting this result before starting to launch its UI).
545 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
547 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
548 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
550 // Maximum number of persisted Uri grants a package is allowed
551 static final int MAX_PERSISTED_URI_GRANTS = 128;
553 static final int MY_PID = myPid();
555 static final String[] EMPTY_STRING_ARRAY = new String[0];
557 // How many bytes to write into the dropbox log before truncating
558 static final int DROPBOX_MAX_SIZE = 192 * 1024;
559 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
560 // as one line, but close enough for now.
561 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
563 // Access modes for handleIncomingUser.
564 static final int ALLOW_NON_FULL = 0;
565 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
566 static final int ALLOW_FULL_ONLY = 2;
568 // Necessary ApplicationInfo flags to mark an app as persistent
569 private static final int PERSISTENT_MASK =
570 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
572 // Intent sent when remote bugreport collection has been completed
573 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
574 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
576 // Used to indicate that an app transition should be animated.
577 static final boolean ANIMATE = true;
579 // Determines whether to take full screen screenshots
580 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
583 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
585 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
588 * State indicating that there is no need for any blocking for network.
591 static final int NETWORK_STATE_NO_CHANGE = 0;
594 * State indicating that the main thread needs to be informed about the network wait.
597 static final int NETWORK_STATE_BLOCK = 1;
600 * State indicating that any threads waiting for network state to get updated can be unblocked.
603 static final int NETWORK_STATE_UNBLOCK = 2;
605 // Max character limit for a notification title. If the notification title is larger than this
606 // the notification will not be legible to the user.
607 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
609 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
611 /** All system services */
612 SystemServiceManager mSystemServiceManager;
613 AssistUtils mAssistUtils;
615 private Installer mInstaller;
617 /** Run all ActivityStacks through this */
618 final ActivityStackSupervisor mStackSupervisor;
619 private final KeyguardController mKeyguardController;
621 final ActivityStarter mActivityStarter;
623 final TaskChangeNotificationController mTaskChangeNotificationController;
625 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
627 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
629 public final IntentFirewall mIntentFirewall;
631 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
632 // default action automatically. Important for devices without direct input
634 private boolean mShowDialogs = true;
636 private final VrController mVrController;
638 // VR Vr2d Display Id.
639 int mVr2dDisplayId = INVALID_DISPLAY;
641 // Whether we should use SCHED_FIFO for UI and RenderThreads.
642 private boolean mUseFifoUiScheduling = false;
644 BroadcastQueue mFgBroadcastQueue;
645 BroadcastQueue mBgBroadcastQueue;
646 // Convenient for easy iteration over the queues. Foreground is first
647 // so that dispatch of foreground broadcasts gets precedence.
648 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
650 BroadcastStats mLastBroadcastStats;
651 BroadcastStats mCurBroadcastStats;
653 BroadcastQueue broadcastQueueForIntent(Intent intent) {
654 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
655 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
656 "Broadcast intent " + intent + " on "
657 + (isFg ? "foreground" : "background") + " queue");
658 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
662 * The last resumed activity. This is identical to the current resumed activity most
663 * of the time but could be different when we're pausing one activity before we resume
666 private ActivityRecord mLastResumedActivity;
669 * If non-null, we are tracking the time the user spends in the currently focused app.
671 private AppTimeTracker mCurAppTimeTracker;
674 * List of intents that were used to start the most recent tasks.
676 final RecentTasks mRecentTasks;
679 * For addAppTask: cached of the last activity component that was added.
681 ComponentName mLastAddedTaskComponent;
684 * For addAppTask: cached of the last activity uid that was added.
686 int mLastAddedTaskUid;
689 * For addAppTask: cached of the last ActivityInfo that was added.
691 ActivityInfo mLastAddedTaskActivity;
694 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
696 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
699 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
701 String mDeviceOwnerName;
703 final UserController mUserController;
705 final AppErrors mAppErrors;
708 * Dump of the activity state at the time of the last ANR. Cleared after
709 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
711 String mLastANRState;
714 * Indicates the maximum time spent waiting for the network rules to get updated.
717 long mWaitForNetworkTimeoutMs;
719 public boolean canShowErrorDialogs() {
720 return mShowDialogs && !mSleeping && !mShuttingDown
721 && !mKeyguardController.isKeyguardShowing();
724 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
725 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
727 static void boostPriorityForLockedSection() {
728 sThreadPriorityBooster.boost();
731 static void resetPriorityAfterLockedSection() {
732 sThreadPriorityBooster.reset();
735 public class PendingAssistExtras extends Binder implements Runnable {
736 public final ActivityRecord activity;
737 public boolean isHome;
738 public final Bundle extras;
739 public final Intent intent;
740 public final String hint;
741 public final IResultReceiver receiver;
742 public final int userHandle;
743 public boolean haveResult = false;
744 public Bundle result = null;
745 public AssistStructure structure = null;
746 public AssistContent content = null;
747 public Bundle receiverExtras;
749 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
750 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
751 activity = _activity;
755 receiver = _receiver;
756 receiverExtras = _receiverExtras;
757 userHandle = _userHandle;
762 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
763 synchronized (this) {
767 pendingAssistExtrasTimedOut(this);
771 final ArrayList<PendingAssistExtras> mPendingAssistExtras
772 = new ArrayList<PendingAssistExtras>();
775 * Process management.
777 final ProcessList mProcessList = new ProcessList();
780 * All of the applications we currently have running organized by name.
781 * The keys are strings of the application package name (as
782 * returned by the package manager), and the keys are ApplicationRecord
785 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
788 * Tracking long-term execution of processes to look for abuse and other
791 final ProcessStatsService mProcessStats;
794 * The currently running isolated processes.
796 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
799 * Counter for assigning isolated process uids, to avoid frequently reusing the
802 int mNextIsolatedProcessUid = 0;
805 * The currently running heavy-weight process, if any.
807 ProcessRecord mHeavyWeightProcess = null;
810 * Non-persistent appId whitelist for background restrictions
812 int[] mBackgroundAppIdWhitelist = new int[] {
817 * Broadcast actions that will always be deliverable to unlaunched/background apps
819 ArraySet<String> mBackgroundLaunchBroadcasts;
822 * All of the processes we currently have running organized by pid.
823 * The keys are the pid running the application.
825 * <p>NOTE: This object is protected by its own lock, NOT the global
826 * activity manager lock!
828 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
831 * All of the processes that have been forced to be important. The key
832 * is the pid of the caller who requested it (we hold a death
835 abstract class ImportanceToken implements IBinder.DeathRecipient {
840 ImportanceToken(int _pid, IBinder _token, String _reason) {
847 public String toString() {
848 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
849 + " " + reason + " " + pid + " " + token + " }";
852 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
855 * List of records for processes that someone had tried to start before the
856 * system was ready. We don't start them at that point, but ensure they
857 * are started by the time booting is complete.
859 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
862 * List of persistent applications that are in the process
865 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
868 * Processes that are being forcibly torn down.
870 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
873 * List of running applications, sorted by recent usage.
874 * The first entry in the list is the least recently used.
876 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
879 * Where in mLruProcesses that the processes hosting activities start.
881 int mLruProcessActivityStart = 0;
884 * Where in mLruProcesses that the processes hosting services start.
885 * This is after (lower index) than mLruProcessesActivityStart.
887 int mLruProcessServiceStart = 0;
890 * List of processes that should gc as soon as things are idle.
892 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
895 * Processes we want to collect PSS data from.
897 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
899 private boolean mBinderTransactionTrackingEnabled = false;
902 * Last time we requested PSS data of all processes.
904 long mLastFullPssTime = SystemClock.uptimeMillis();
907 * If set, the next time we collect PSS data we should do a full collection
908 * with data from native processes and the kernel.
910 boolean mFullPssPending = false;
913 * This is the process holding what we currently consider to be
914 * the "home" activity.
916 ProcessRecord mHomeProcess;
919 * This is the process holding the activity the user last visited that
920 * is in a different process from the one they are currently in.
922 ProcessRecord mPreviousProcess;
925 * The time at which the previous process was last visible.
927 long mPreviousProcessVisibleTime;
930 * Track all uids that have actively running processes.
932 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
935 * This is for verifying the UID report flow.
937 static final boolean VALIDATE_UID_STATES = true;
938 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
941 * Packages that the user has asked to have run in screen size
942 * compatibility mode instead of filling the screen.
944 final CompatModePackages mCompatModePackages;
947 * Set of IntentSenderRecord objects that are currently active.
949 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
950 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
953 * Fingerprints (hashCode()) of stack traces that we've
954 * already logged DropBox entries for. Guarded by itself. If
955 * something (rogue user app) forces this over
956 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
958 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
959 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
962 * Strict Mode background batched logging state.
964 * The string buffer is guarded by itself, and its lock is also
965 * used to determine if another batched write is already
968 private final StringBuilder mStrictModeBuffer = new StringBuilder();
971 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
972 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
974 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
977 * Resolver for broadcast intents to registered receivers.
978 * Holds BroadcastFilter (subclass of IntentFilter).
980 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
981 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
983 protected boolean allowFilterResult(
984 BroadcastFilter filter, List<BroadcastFilter> dest) {
985 IBinder target = filter.receiverList.receiver.asBinder();
986 for (int i = dest.size() - 1; i >= 0; i--) {
987 if (dest.get(i).receiverList.receiver.asBinder() == target) {
995 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
996 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
997 || userId == filter.owningUserId) {
998 return super.newResult(filter, match, userId);
1004 protected BroadcastFilter[] newArray(int size) {
1005 return new BroadcastFilter[size];
1009 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1010 return packageName.equals(filter.packageName);
1015 * State of all active sticky broadcasts per user. Keys are the action of the
1016 * sticky Intent, values are an ArrayList of all broadcasted intents with
1017 * that action (which should usually be one). The SparseArray is keyed
1018 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1019 * for stickies that are sent to all users.
1021 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1022 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1024 final ActiveServices mServices;
1026 final static class Association {
1027 final int mSourceUid;
1028 final String mSourceProcess;
1029 final int mTargetUid;
1030 final ComponentName mTargetComponent;
1031 final String mTargetProcess;
1039 // states of the source process when the bind occurred.
1040 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1041 long mLastStateUptime;
1042 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1043 - ActivityManager.MIN_PROCESS_STATE+1];
1045 Association(int sourceUid, String sourceProcess, int targetUid,
1046 ComponentName targetComponent, String targetProcess) {
1047 mSourceUid = sourceUid;
1048 mSourceProcess = sourceProcess;
1049 mTargetUid = targetUid;
1050 mTargetComponent = targetComponent;
1051 mTargetProcess = targetProcess;
1056 * When service association tracking is enabled, this is all of the associations we
1057 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1058 * -> association data.
1060 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1061 mAssociations = new SparseArray<>();
1062 boolean mTrackingAssociations;
1065 * Backup/restore process management
1067 String mBackupAppName = null;
1068 BackupRecord mBackupTarget = null;
1070 final ProviderMap mProviderMap;
1073 * List of content providers who have clients waiting for them. The
1074 * application is currently being launched and the provider will be
1075 * removed from this list once it is published.
1077 final ArrayList<ContentProviderRecord> mLaunchingProviders
1078 = new ArrayList<ContentProviderRecord>();
1081 * File storing persisted {@link #mGrantedUriPermissions}.
1083 private final AtomicFile mGrantFile;
1085 /** XML constants used in {@link #mGrantFile} */
1086 private static final String TAG_URI_GRANTS = "uri-grants";
1087 private static final String TAG_URI_GRANT = "uri-grant";
1088 private static final String ATTR_USER_HANDLE = "userHandle";
1089 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1090 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1091 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1092 private static final String ATTR_TARGET_PKG = "targetPkg";
1093 private static final String ATTR_URI = "uri";
1094 private static final String ATTR_MODE_FLAGS = "modeFlags";
1095 private static final String ATTR_CREATED_TIME = "createdTime";
1096 private static final String ATTR_PREFIX = "prefix";
1099 * Global set of specific {@link Uri} permissions that have been granted.
1100 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1101 * to {@link UriPermission#uri} to {@link UriPermission}.
1104 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1105 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1107 public static class GrantUri {
1108 public final int sourceUserId;
1109 public final Uri uri;
1110 public boolean prefix;
1112 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1113 this.sourceUserId = sourceUserId;
1115 this.prefix = prefix;
1119 public int hashCode() {
1121 hashCode = 31 * hashCode + sourceUserId;
1122 hashCode = 31 * hashCode + uri.hashCode();
1123 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1128 public boolean equals(Object o) {
1129 if (o instanceof GrantUri) {
1130 GrantUri other = (GrantUri) o;
1131 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1132 && prefix == other.prefix;
1138 public String toString() {
1139 String result = uri.toString() + " [user " + sourceUserId + "]";
1140 if (prefix) result += " [prefix]";
1144 public String toSafeString() {
1145 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1146 if (prefix) result += " [prefix]";
1150 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1151 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1152 ContentProvider.getUriWithoutUserId(uri), false);
1156 CoreSettingsObserver mCoreSettingsObserver;
1158 FontScaleSettingObserver mFontScaleSettingObserver;
1160 private final class FontScaleSettingObserver extends ContentObserver {
1161 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1163 public FontScaleSettingObserver() {
1165 ContentResolver resolver = mContext.getContentResolver();
1166 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1170 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1171 if (mFontScaleUri.equals(uri)) {
1172 updateFontScaleIfNeeded(userId);
1178 * Thread-local storage used to carry caller permissions over through
1179 * indirect content-provider access.
1181 private class Identity {
1182 public final IBinder token;
1183 public final int pid;
1184 public final int uid;
1186 Identity(IBinder _token, int _pid, int _uid) {
1193 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1196 * All information we have collected about the runtime performance of
1197 * any user id that can impact battery performance.
1199 final BatteryStatsService mBatteryStatsService;
1202 * Information about component usage
1204 UsageStatsManagerInternal mUsageStatsService;
1207 * Access to DeviceIdleController service.
1209 DeviceIdleController.LocalService mLocalDeviceIdleController;
1212 * Set of app ids that are whitelisted for device idle and thus background check.
1214 int[] mDeviceIdleWhitelist = new int[0];
1217 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1219 int[] mDeviceIdleTempWhitelist = new int[0];
1221 static final class PendingTempWhitelist {
1222 final int targetUid;
1223 final long duration;
1226 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1227 targetUid = _targetUid;
1228 duration = _duration;
1233 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1236 * Information about and control over application operations
1238 final AppOpsService mAppOpsService;
1240 /** Current sequencing integer of the configuration, for skipping old configurations. */
1241 private int mConfigurationSeq;
1244 * Temp object used when global and/or display override configuration is updated. It is also
1245 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1248 private Configuration mTempConfig = new Configuration();
1250 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1251 new UpdateConfigurationResult();
1252 private static final class UpdateConfigurationResult {
1253 // Configuration changes that were updated.
1255 // If the activity was relaunched to match the new configuration.
1256 boolean activityRelaunched;
1260 activityRelaunched = false;
1264 boolean mSuppressResizeConfigChanges;
1267 * Hardware-reported OpenGLES version.
1269 final int GL_ES_VERSION;
1272 * List of initialization arguments to pass to all processes when binding applications to them.
1273 * For example, references to the commonly used services.
1275 HashMap<String, IBinder> mAppBindArgs;
1276 HashMap<String, IBinder> mIsolatedAppBindArgs;
1279 * Temporary to avoid allocations. Protected by main lock.
1281 final StringBuilder mStringBuilder = new StringBuilder(256);
1284 * Used to control how we initialize the service.
1286 ComponentName mTopComponent;
1287 String mTopAction = Intent.ACTION_MAIN;
1290 volatile boolean mProcessesReady = false;
1291 volatile boolean mSystemReady = false;
1292 volatile boolean mOnBattery = false;
1293 volatile int mFactoryTest;
1295 @GuardedBy("this") boolean mBooting = false;
1296 @GuardedBy("this") boolean mCallFinishBooting = false;
1297 @GuardedBy("this") boolean mBootAnimationComplete = false;
1298 @GuardedBy("this") boolean mLaunchWarningShown = false;
1299 @GuardedBy("this") boolean mCheckedForSetup = false;
1301 final Context mContext;
1304 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1305 * change at runtime. Use mContext for non-UI purposes.
1307 final Context mUiContext;
1310 * The time at which we will allow normal application switches again,
1311 * after a call to {@link #stopAppSwitches()}.
1313 long mAppSwitchesAllowedTime;
1316 * This is set to true after the first switch after mAppSwitchesAllowedTime
1317 * is set; any switches after that will clear the time.
1319 boolean mDidAppSwitch;
1322 * Last time (in realtime) at which we checked for power usage.
1324 long mLastPowerCheckRealtime;
1327 * Last time (in uptime) at which we checked for power usage.
1329 long mLastPowerCheckUptime;
1332 * Set while we are wanting to sleep, to prevent any
1333 * activities from being started/resumed.
1335 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1337 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1338 * while in the sleep state until there is a pending transition out of sleep, in which case
1339 * mSleeping is set to false, and remains false while awake.
1341 * Whether mSleeping can quickly toggled between true/false without the device actually
1342 * display changing states is undefined.
1344 private boolean mSleeping = false;
1347 * The process state used for processes that are running the top activities.
1348 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1350 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1353 * Set while we are running a voice interaction. This overrides
1354 * sleeping while it is active.
1356 private IVoiceInteractionSession mRunningVoice;
1359 * For some direct access we need to power manager.
1361 PowerManagerInternal mLocalPowerManager;
1364 * We want to hold a wake lock while running a voice interaction session, since
1365 * this may happen with the screen off and we need to keep the CPU running to
1366 * be able to continue to interact with the user.
1368 PowerManager.WakeLock mVoiceWakeLock;
1371 * State of external calls telling us if the device is awake or asleep.
1373 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1376 * A list of tokens that cause the top activity to be put to sleep.
1377 * They are used by components that may hide and block interaction with underlying
1380 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1383 * Set if we are shutting down the system, similar to sleeping.
1385 boolean mShuttingDown = false;
1388 * Current sequence id for oom_adj computation traversal.
1393 * Current sequence id for process LRU updating.
1398 * Keep track of the non-cached/empty process we last found, to help
1399 * determine how to distribute cached/empty processes next time.
1401 int mNumNonCachedProcs = 0;
1404 * Keep track of the number of cached hidden procs, to balance oom adj
1405 * distribution between those and empty procs.
1407 int mNumCachedHiddenProcs = 0;
1410 * Keep track of the number of service processes we last found, to
1411 * determine on the next iteration which should be B services.
1413 int mNumServiceProcs = 0;
1414 int mNewNumAServiceProcs = 0;
1415 int mNewNumServiceProcs = 0;
1418 * Allow the current computed overall memory level of the system to go down?
1419 * This is set to false when we are killing processes for reasons other than
1420 * memory management, so that the now smaller process list will not be taken as
1421 * an indication that memory is tighter.
1423 boolean mAllowLowerMemLevel = false;
1426 * The last computed memory level, for holding when we are in a state that
1427 * processes are going away for other reasons.
1429 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1432 * The last total number of process we have, to determine if changes actually look
1433 * like a shrinking number of process due to lower RAM.
1435 int mLastNumProcesses;
1438 * The uptime of the last time we performed idle maintenance.
1440 long mLastIdleTime = SystemClock.uptimeMillis();
1443 * Total time spent with RAM that has been added in the past since the last idle time.
1445 long mLowRamTimeSinceLastIdle = 0;
1448 * If RAM is currently low, when that horrible situation started.
1450 long mLowRamStartTime = 0;
1453 * For reporting to battery stats the current top application.
1455 private String mCurResumedPackage = null;
1456 private int mCurResumedUid = -1;
1459 * For reporting to battery stats the apps currently running foreground
1460 * service. The ProcessMap is package/uid tuples; each of these contain
1461 * an array of the currently foreground processes.
1463 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1464 = new ProcessMap<ArrayList<ProcessRecord>>();
1467 * Set if the systemServer made a call to enterSafeMode.
1472 * If true, we are running under a test environment so will sample PSS from processes
1473 * much more rapidly to try to collect better data when the tests are rapidly
1474 * running through apps.
1476 boolean mTestPssMode = false;
1478 String mDebugApp = null;
1479 boolean mWaitForDebugger = false;
1480 boolean mDebugTransient = false;
1481 String mOrigDebugApp = null;
1482 boolean mOrigWaitForDebugger = false;
1483 boolean mAlwaysFinishActivities = false;
1484 boolean mForceResizableActivities;
1486 * Flag that indicates if multi-window is enabled.
1488 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1489 * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
1490 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1491 * At least one of the forms of multi-window must be enabled in order for this flag to be
1492 * initialized to 'true'.
1494 * @see #mSupportsSplitScreenMultiWindow
1495 * @see #mSupportsFreeformWindowManagement
1496 * @see #mSupportsPictureInPicture
1497 * @see #mSupportsMultiDisplay
1499 boolean mSupportsMultiWindow;
1500 boolean mSupportsSplitScreenMultiWindow;
1501 boolean mSupportsFreeformWindowManagement;
1502 boolean mSupportsPictureInPicture;
1503 boolean mSupportsMultiDisplay;
1504 boolean mSupportsLeanbackOnly;
1505 IActivityController mController = null;
1506 boolean mControllerIsAMonkey = false;
1507 String mProfileApp = null;
1508 ProcessRecord mProfileProc = null;
1509 String mProfileFile;
1510 ParcelFileDescriptor mProfileFd;
1511 int mSamplingInterval = 0;
1512 boolean mAutoStopProfiler = false;
1513 boolean mStreamingOutput = false;
1514 int mProfileType = 0;
1515 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1516 String mMemWatchDumpProcName;
1517 String mMemWatchDumpFile;
1518 int mMemWatchDumpPid;
1519 int mMemWatchDumpUid;
1520 String mTrackAllocationApp = null;
1521 String mNativeDebuggingApp = null;
1523 final long[] mTmpLong = new long[2];
1525 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1528 * A global counter for generating sequence numbers.
1529 * This value will be used when incrementing sequence numbers in individual uidRecords.
1531 * Having a global counter ensures that seq numbers are monotonically increasing for a
1532 * particular uid even when the uidRecord is re-created.
1536 long mProcStateSeqCounter = 0;
1538 private final Injector mInjector;
1540 static final class ProcessChangeItem {
1541 static final int CHANGE_ACTIVITIES = 1<<0;
1546 boolean foregroundActivities;
1549 static final class UidObserverRegistration {
1555 final SparseIntArray lastProcStates;
1557 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1561 cutpoint = _cutpoint;
1562 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1563 lastProcStates = new SparseIntArray();
1565 lastProcStates = null;
1570 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1571 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1573 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1574 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1576 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1577 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1579 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1580 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1583 * Runtime CPU use collection thread. This object's lock is used to
1584 * perform synchronization with the thread (notifying it to run).
1586 final Thread mProcessCpuThread;
1589 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1590 * Must acquire this object's lock when accessing it.
1591 * NOTE: this lock will be held while doing long operations (trawling
1592 * through all processes in /proc), so it should never be acquired by
1593 * any critical paths such as when holding the main activity manager lock.
1595 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1596 MONITOR_THREAD_CPU_USAGE);
1597 final AtomicLong mLastCpuTime = new AtomicLong(0);
1598 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1599 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1601 long mLastWriteTime = 0;
1604 * Used to retain an update lock when the foreground activity is in
1607 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1610 * Set to true after the system has finished booting.
1612 boolean mBooted = false;
1614 WindowManagerService mWindowManager;
1615 final ActivityThread mSystemThread;
1617 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1618 final ProcessRecord mApp;
1620 final IApplicationThread mAppThread;
1622 AppDeathRecipient(ProcessRecord app, int pid,
1623 IApplicationThread thread) {
1624 if (DEBUG_ALL) Slog.v(
1625 TAG, "New death recipient " + this
1626 + " for thread " + thread.asBinder());
1629 mAppThread = thread;
1633 public void binderDied() {
1634 if (DEBUG_ALL) Slog.v(
1635 TAG, "Death received in " + this
1636 + " for thread " + mAppThread.asBinder());
1637 synchronized(ActivityManagerService.this) {
1638 appDiedLocked(mApp, mPid, mAppThread, true);
1643 static final int SHOW_ERROR_UI_MSG = 1;
1644 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1645 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1646 static final int UPDATE_CONFIGURATION_MSG = 4;
1647 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1648 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1649 static final int SERVICE_TIMEOUT_MSG = 12;
1650 static final int UPDATE_TIME_ZONE = 13;
1651 static final int SHOW_UID_ERROR_UI_MSG = 14;
1652 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1653 static final int PROC_START_TIMEOUT_MSG = 20;
1654 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1655 static final int KILL_APPLICATION_MSG = 22;
1656 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1657 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1658 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1659 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1660 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1661 static final int CLEAR_DNS_CACHE_MSG = 28;
1662 static final int UPDATE_HTTP_PROXY_MSG = 29;
1663 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1664 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1665 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1666 static final int REPORT_MEM_USAGE_MSG = 33;
1667 static final int REPORT_USER_SWITCH_MSG = 34;
1668 static final int CONTINUE_USER_SWITCH_MSG = 35;
1669 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1670 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1671 static final int PERSIST_URI_GRANTS_MSG = 38;
1672 static final int REQUEST_ALL_PSS_MSG = 39;
1673 static final int START_PROFILES_MSG = 40;
1674 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1675 static final int SYSTEM_USER_START_MSG = 42;
1676 static final int SYSTEM_USER_CURRENT_MSG = 43;
1677 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1678 static final int FINISH_BOOTING_MSG = 45;
1679 static final int START_USER_SWITCH_UI_MSG = 46;
1680 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1681 static final int DISMISS_DIALOG_UI_MSG = 48;
1682 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1683 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1684 static final int DELETE_DUMPHEAP_MSG = 51;
1685 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1686 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1687 static final int REPORT_TIME_TRACKER_MSG = 54;
1688 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1689 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1690 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1691 static final int IDLE_UIDS_MSG = 58;
1692 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1693 static final int LOG_STACK_STATE = 60;
1694 static final int VR_MODE_CHANGE_MSG = 61;
1695 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1696 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1697 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1698 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1699 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1700 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1701 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1702 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1703 static final int START_USER_SWITCH_FG_MSG = 712;
1705 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1706 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1707 static final int FIRST_COMPAT_MODE_MSG = 300;
1708 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1710 static ServiceThread sKillThread = null;
1711 static KillHandler sKillHandler = null;
1713 CompatModeDialog mCompatModeDialog;
1714 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1715 long mLastMemUsageReportTime = 0;
1718 * Flag whether the current user is a "monkey", i.e. whether
1719 * the UI is driven by a UI automation tool.
1721 private boolean mUserIsMonkey;
1723 /** Flag whether the device has a Recents UI */
1724 boolean mHasRecents;
1726 /** The dimensions of the thumbnails in the Recents UI. */
1727 int mThumbnailWidth;
1728 int mThumbnailHeight;
1729 float mFullscreenThumbnailScale;
1731 final ServiceThread mHandlerThread;
1732 final MainHandler mHandler;
1733 final Handler mUiHandler;
1735 final ActivityManagerConstants mConstants;
1737 PackageManagerInternal mPackageManagerInt;
1739 // VoiceInteraction session ID that changes for each new request except when
1740 // being called for multiwindow assist in a single session.
1741 private int mViSessionId = 1000;
1743 final boolean mPermissionReviewRequired;
1746 * Current global configuration information. Contains general settings for the entire system,
1747 * also corresponds to the merged configuration of the default display.
1749 Configuration getGlobalConfiguration() {
1750 return mStackSupervisor.getConfiguration();
1753 final class KillHandler extends Handler {
1754 static final int KILL_PROCESS_GROUP_MSG = 4000;
1756 public KillHandler(Looper looper) {
1757 super(looper, null, true);
1761 public void handleMessage(Message msg) {
1763 case KILL_PROCESS_GROUP_MSG:
1765 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1766 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1767 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1772 super.handleMessage(msg);
1777 final class UiHandler extends Handler {
1778 public UiHandler() {
1779 super(com.android.server.UiThread.get().getLooper(), null, true);
1783 public void handleMessage(Message msg) {
1785 case SHOW_ERROR_UI_MSG: {
1786 mAppErrors.handleShowAppErrorUi(msg);
1787 ensureBootCompleted();
1789 case SHOW_NOT_RESPONDING_UI_MSG: {
1790 mAppErrors.handleShowAnrUi(msg);
1791 ensureBootCompleted();
1793 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1794 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1795 synchronized (ActivityManagerService.this) {
1796 ProcessRecord proc = (ProcessRecord) data.get("app");
1798 Slog.e(TAG, "App not found when showing strict mode dialog.");
1801 if (proc.crashDialog != null) {
1802 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1805 AppErrorResult res = (AppErrorResult) data.get("result");
1806 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1807 Dialog d = new StrictModeViolationDialog(mUiContext,
1808 ActivityManagerService.this, res, proc);
1810 proc.crashDialog = d;
1812 // The device is asleep, so just pretend that the user
1813 // saw a crash dialog and hit "force quit".
1817 ensureBootCompleted();
1819 case SHOW_FACTORY_ERROR_UI_MSG: {
1820 Dialog d = new FactoryErrorDialog(
1821 mUiContext, msg.getData().getCharSequence("msg"));
1823 ensureBootCompleted();
1825 case WAIT_FOR_DEBUGGER_UI_MSG: {
1826 synchronized (ActivityManagerService.this) {
1827 ProcessRecord app = (ProcessRecord)msg.obj;
1828 if (msg.arg1 != 0) {
1829 if (!app.waitedForDebugger) {
1830 Dialog d = new AppWaitingForDebuggerDialog(
1831 ActivityManagerService.this,
1834 app.waitedForDebugger = true;
1838 if (app.waitDialog != null) {
1839 app.waitDialog.dismiss();
1840 app.waitDialog = null;
1845 case SHOW_UID_ERROR_UI_MSG: {
1847 AlertDialog d = new BaseErrorDialog(mUiContext);
1848 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1849 d.setCancelable(false);
1850 d.setTitle(mUiContext.getText(R.string.android_system_label));
1851 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1852 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1853 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1857 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1859 AlertDialog d = new BaseErrorDialog(mUiContext);
1860 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1861 d.setCancelable(false);
1862 d.setTitle(mUiContext.getText(R.string.android_system_label));
1863 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1864 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1865 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1869 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1870 synchronized (ActivityManagerService.this) {
1871 ActivityRecord ar = (ActivityRecord) msg.obj;
1872 if (mCompatModeDialog != null) {
1873 if (mCompatModeDialog.mAppInfo.packageName.equals(
1874 ar.info.applicationInfo.packageName)) {
1877 mCompatModeDialog.dismiss();
1878 mCompatModeDialog = null;
1880 if (ar != null && false) {
1881 if (mCompatModePackages.getPackageAskCompatModeLocked(
1883 int mode = mCompatModePackages.computeCompatModeLocked(
1884 ar.info.applicationInfo);
1885 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1886 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1887 mCompatModeDialog = new CompatModeDialog(
1888 ActivityManagerService.this, mUiContext,
1889 ar.info.applicationInfo);
1890 mCompatModeDialog.show();
1897 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1898 synchronized (ActivityManagerService.this) {
1899 final ActivityRecord ar = (ActivityRecord) msg.obj;
1900 if (mUnsupportedDisplaySizeDialog != null) {
1901 mUnsupportedDisplaySizeDialog.dismiss();
1902 mUnsupportedDisplaySizeDialog = null;
1904 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1906 // TODO(multi-display): Show dialog on appropriate display.
1907 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1908 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1909 mUnsupportedDisplaySizeDialog.show();
1914 case START_USER_SWITCH_UI_MSG: {
1915 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1918 case DISMISS_DIALOG_UI_MSG: {
1919 final Dialog d = (Dialog) msg.obj;
1923 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1924 dispatchProcessesChanged();
1927 case DISPATCH_PROCESS_DIED_UI_MSG: {
1928 final int pid = msg.arg1;
1929 final int uid = msg.arg2;
1930 dispatchProcessDied(pid, uid);
1933 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1934 dispatchUidsChanged();
1936 case PUSH_TEMP_WHITELIST_UI_MSG: {
1937 pushTempWhitelist();
1943 final class MainHandler extends Handler {
1944 public MainHandler(Looper looper) {
1945 super(looper, null, true);
1949 public void handleMessage(Message msg) {
1951 case UPDATE_CONFIGURATION_MSG: {
1952 final ContentResolver resolver = mContext.getContentResolver();
1953 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1956 case GC_BACKGROUND_PROCESSES_MSG: {
1957 synchronized (ActivityManagerService.this) {
1958 performAppGcsIfAppropriateLocked();
1961 case SERVICE_TIMEOUT_MSG: {
1962 mServices.serviceTimeout((ProcessRecord)msg.obj);
1964 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1965 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1967 case SERVICE_FOREGROUND_CRASH_MSG: {
1968 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1970 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1971 RemoteCallbackList<IResultReceiver> callbacks
1972 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1973 int N = callbacks.beginBroadcast();
1974 for (int i = 0; i < N; i++) {
1976 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1977 } catch (RemoteException e) {
1980 callbacks.finishBroadcast();
1982 case UPDATE_TIME_ZONE: {
1983 synchronized (ActivityManagerService.this) {
1984 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1985 ProcessRecord r = mLruProcesses.get(i);
1986 if (r.thread != null) {
1988 r.thread.updateTimeZone();
1989 } catch (RemoteException ex) {
1990 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1996 case CLEAR_DNS_CACHE_MSG: {
1997 synchronized (ActivityManagerService.this) {
1998 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1999 ProcessRecord r = mLruProcesses.get(i);
2000 if (r.thread != null) {
2002 r.thread.clearDnsCache();
2003 } catch (RemoteException ex) {
2004 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2010 case UPDATE_HTTP_PROXY_MSG: {
2011 ProxyInfo proxy = (ProxyInfo)msg.obj;
2014 String exclList = "";
2015 Uri pacFileUrl = Uri.EMPTY;
2016 if (proxy != null) {
2017 host = proxy.getHost();
2018 port = Integer.toString(proxy.getPort());
2019 exclList = proxy.getExclusionListAsString();
2020 pacFileUrl = proxy.getPacFileUrl();
2022 synchronized (ActivityManagerService.this) {
2023 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2024 ProcessRecord r = mLruProcesses.get(i);
2025 if (r.thread != null) {
2027 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2028 } catch (RemoteException ex) {
2029 Slog.w(TAG, "Failed to update http proxy for: " +
2030 r.info.processName);
2036 case PROC_START_TIMEOUT_MSG: {
2037 ProcessRecord app = (ProcessRecord)msg.obj;
2038 synchronized (ActivityManagerService.this) {
2039 processStartTimedOutLocked(app);
2042 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2043 ProcessRecord app = (ProcessRecord)msg.obj;
2044 synchronized (ActivityManagerService.this) {
2045 processContentProviderPublishTimedOutLocked(app);
2048 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2049 synchronized (ActivityManagerService.this) {
2050 mActivityStarter.doPendingActivityLaunchesLocked(true);
2053 case KILL_APPLICATION_MSG: {
2054 synchronized (ActivityManagerService.this) {
2055 final int appId = msg.arg1;
2056 final int userId = msg.arg2;
2057 Bundle bundle = (Bundle)msg.obj;
2058 String pkg = bundle.getString("pkg");
2059 String reason = bundle.getString("reason");
2060 forceStopPackageLocked(pkg, appId, false, false, true, false,
2061 false, userId, reason);
2064 case FINALIZE_PENDING_INTENT_MSG: {
2065 ((PendingIntentRecord)msg.obj).completeFinalize();
2067 case POST_HEAVY_NOTIFICATION_MSG: {
2068 INotificationManager inm = NotificationManager.getService();
2073 ActivityRecord root = (ActivityRecord)msg.obj;
2074 ProcessRecord process = root.app;
2075 if (process == null) {
2080 Context context = mContext.createPackageContext(process.info.packageName, 0);
2081 String text = mContext.getString(R.string.heavy_weight_notification,
2082 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2083 Notification notification =
2084 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2085 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2089 .setColor(mContext.getColor(
2090 com.android.internal.R.color.system_notification_accent_color))
2091 .setContentTitle(text)
2093 mContext.getText(R.string.heavy_weight_notification_detail))
2094 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2095 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2096 new UserHandle(root.userId)))
2099 inm.enqueueNotificationWithTag("android", "android", null,
2100 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2101 notification, root.userId);
2102 } catch (RuntimeException e) {
2103 Slog.w(ActivityManagerService.TAG,
2104 "Error showing notification for heavy-weight app", e);
2105 } catch (RemoteException e) {
2107 } catch (NameNotFoundException e) {
2108 Slog.w(TAG, "Unable to create context for heavy notification", e);
2111 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2112 INotificationManager inm = NotificationManager.getService();
2117 inm.cancelNotificationWithTag("android", null,
2118 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2119 } catch (RuntimeException e) {
2120 Slog.w(ActivityManagerService.TAG,
2121 "Error canceling notification for service", e);
2122 } catch (RemoteException e) {
2125 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2126 synchronized (ActivityManagerService.this) {
2127 checkExcessivePowerUsageLocked(true);
2128 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2129 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2130 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2133 case REPORT_MEM_USAGE_MSG: {
2134 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2135 Thread thread = new Thread() {
2136 @Override public void run() {
2137 reportMemUsage(memInfos);
2143 case START_USER_SWITCH_FG_MSG: {
2144 mUserController.startUserInForeground(msg.arg1);
2147 case REPORT_USER_SWITCH_MSG: {
2148 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2151 case CONTINUE_USER_SWITCH_MSG: {
2152 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2155 case USER_SWITCH_TIMEOUT_MSG: {
2156 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2159 case IMMERSIVE_MODE_LOCK_MSG: {
2160 final boolean nextState = (msg.arg1 != 0);
2161 if (mUpdateLock.isHeld() != nextState) {
2162 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2163 "Applying new update lock state '" + nextState
2164 + "' for " + (ActivityRecord)msg.obj);
2166 mUpdateLock.acquire();
2168 mUpdateLock.release();
2173 case PERSIST_URI_GRANTS_MSG: {
2174 writeGrantedUriPermissions();
2177 case REQUEST_ALL_PSS_MSG: {
2178 synchronized (ActivityManagerService.this) {
2179 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2183 case START_PROFILES_MSG: {
2184 synchronized (ActivityManagerService.this) {
2185 mUserController.startProfilesLocked();
2189 case UPDATE_TIME_PREFERENCE_MSG: {
2190 // The user's time format preference might have changed.
2191 // For convenience we re-use the Intent extra values.
2192 synchronized (ActivityManagerService.this) {
2193 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2194 ProcessRecord r = mLruProcesses.get(i);
2195 if (r.thread != null) {
2197 r.thread.updateTimePrefs(msg.arg1);
2198 } catch (RemoteException ex) {
2199 Slog.w(TAG, "Failed to update preferences for: "
2200 + r.info.processName);
2207 case SYSTEM_USER_START_MSG: {
2208 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2209 Integer.toString(msg.arg1), msg.arg1);
2210 mSystemServiceManager.startUser(msg.arg1);
2213 case SYSTEM_USER_UNLOCK_MSG: {
2214 final int userId = msg.arg1;
2215 mSystemServiceManager.unlockUser(userId);
2216 synchronized (ActivityManagerService.this) {
2217 mRecentTasks.loadUserRecentsLocked(userId);
2219 if (userId == UserHandle.USER_SYSTEM) {
2220 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2222 installEncryptionUnawareProviders(userId);
2223 mUserController.finishUserUnlocked((UserState) msg.obj);
2226 case SYSTEM_USER_CURRENT_MSG: {
2227 mBatteryStatsService.noteEvent(
2228 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2229 Integer.toString(msg.arg2), msg.arg2);
2230 mBatteryStatsService.noteEvent(
2231 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2232 Integer.toString(msg.arg1), msg.arg1);
2233 mSystemServiceManager.switchUser(msg.arg1);
2236 case ENTER_ANIMATION_COMPLETE_MSG: {
2237 synchronized (ActivityManagerService.this) {
2238 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2239 if (r != null && r.app != null && r.app.thread != null) {
2241 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2242 } catch (RemoteException e) {
2248 case FINISH_BOOTING_MSG: {
2249 if (msg.arg1 != 0) {
2250 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2252 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2254 if (msg.arg2 != 0) {
2255 enableScreenAfterBoot();
2259 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2261 Locale l = (Locale) msg.obj;
2262 IBinder service = ServiceManager.getService("mount");
2263 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2264 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2265 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2266 } catch (RemoteException e) {
2267 Log.e(TAG, "Error storing locale for decryption UI", e);
2271 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2272 final int uid = msg.arg1;
2273 final byte[] firstPacket = (byte[]) msg.obj;
2275 synchronized (mPidsSelfLocked) {
2276 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2277 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2280 p.thread.notifyCleartextNetwork(firstPacket);
2281 } catch (RemoteException ignored) {
2288 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2289 final String procName;
2291 final long memLimit;
2292 final String reportPackage;
2293 synchronized (ActivityManagerService.this) {
2294 procName = mMemWatchDumpProcName;
2295 uid = mMemWatchDumpUid;
2296 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2298 val = mMemWatchProcesses.get(procName, 0);
2301 memLimit = val.first;
2302 reportPackage = val.second;
2305 reportPackage = null;
2308 if (procName == null) {
2312 if (DEBUG_PSS) Slog.d(TAG_PSS,
2313 "Showing dump heap notification from " + procName + "/" + uid);
2315 INotificationManager inm = NotificationManager.getService();
2320 String text = mContext.getString(R.string.dump_heap_notification, procName);
2323 Intent deleteIntent = new Intent();
2324 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2325 Intent intent = new Intent();
2326 intent.setClassName("android", DumpHeapActivity.class.getName());
2327 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2328 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2329 if (reportPackage != null) {
2330 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2332 int userId = UserHandle.getUserId(uid);
2333 Notification notification =
2334 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2335 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2338 .setAutoCancel(true)
2340 .setColor(mContext.getColor(
2341 com.android.internal.R.color.system_notification_accent_color))
2342 .setContentTitle(text)
2344 mContext.getText(R.string.dump_heap_notification_detail))
2345 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2346 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2347 new UserHandle(userId)))
2348 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2349 deleteIntent, 0, UserHandle.SYSTEM))
2353 inm.enqueueNotificationWithTag("android", "android", null,
2354 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2355 notification, userId);
2356 } catch (RuntimeException e) {
2357 Slog.w(ActivityManagerService.TAG,
2358 "Error showing notification for dump heap", e);
2359 } catch (RemoteException e) {
2362 case DELETE_DUMPHEAP_MSG: {
2363 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2364 null, DumpHeapActivity.JAVA_URI,
2365 Intent.FLAG_GRANT_READ_URI_PERMISSION
2366 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2367 UserHandle.myUserId());
2368 synchronized (ActivityManagerService.this) {
2369 mMemWatchDumpFile = null;
2370 mMemWatchDumpProcName = null;
2371 mMemWatchDumpPid = -1;
2372 mMemWatchDumpUid = -1;
2375 case FOREGROUND_PROFILE_CHANGED_MSG: {
2376 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2378 case REPORT_TIME_TRACKER_MSG: {
2379 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2380 tracker.deliverResult(mContext);
2382 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2383 mUserController.dispatchUserSwitchComplete(msg.arg1);
2385 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2386 mUserController.dispatchLockedBootComplete(msg.arg1);
2388 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2389 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2391 connection.shutdown();
2392 } catch (RemoteException e) {
2393 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2395 // Only a UiAutomation can set this flag and now that
2396 // it is finished we make sure it is reset to its default.
2397 mUserIsMonkey = false;
2399 case IDLE_UIDS_MSG: {
2402 case VR_MODE_CHANGE_MSG: {
2403 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2406 synchronized (ActivityManagerService.this) {
2407 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2408 mWindowManager.disableNonVrUi(disableNonVrUi);
2409 if (disableNonVrUi) {
2410 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2411 // then remove the pinned stack.
2412 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2414 if (pinnedStack != null) {
2415 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2420 case NOTIFY_VR_SLEEPING_MSG: {
2421 notifyVrManagerOfSleepState(msg.arg1 != 0);
2423 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2424 synchronized (ActivityManagerService.this) {
2425 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2426 ProcessRecord r = mLruProcesses.get(i);
2427 if (r.thread != null) {
2429 r.thread.handleTrustStorageUpdate();
2430 } catch (RemoteException ex) {
2431 Slog.w(TAG, "Failed to handle trust storage update for: " +
2432 r.info.processName);
2442 static final int COLLECT_PSS_BG_MSG = 1;
2444 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2446 public void handleMessage(Message msg) {
2448 case COLLECT_PSS_BG_MSG: {
2449 long start = SystemClock.uptimeMillis();
2450 MemInfoReader memInfo = null;
2451 synchronized (ActivityManagerService.this) {
2452 if (mFullPssPending) {
2453 mFullPssPending = false;
2454 memInfo = new MemInfoReader();
2457 if (memInfo != null) {
2458 updateCpuStatsNow();
2459 long nativeTotalPss = 0;
2460 final List<ProcessCpuTracker.Stats> stats;
2461 synchronized (mProcessCpuTracker) {
2462 stats = mProcessCpuTracker.getStats( (st)-> {
2463 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2466 final int N = stats.size();
2467 for (int j = 0; j < N; j++) {
2468 synchronized (mPidsSelfLocked) {
2469 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2470 // This is one of our own processes; skip it.
2474 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2476 memInfo.readMemInfo();
2477 synchronized (ActivityManagerService.this) {
2478 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2479 + (SystemClock.uptimeMillis()-start) + "ms");
2480 final long cachedKb = memInfo.getCachedSizeKb();
2481 final long freeKb = memInfo.getFreeSizeKb();
2482 final long zramKb = memInfo.getZramTotalSizeKb();
2483 final long kernelKb = memInfo.getKernelUsedSizeKb();
2484 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2485 kernelKb*1024, nativeTotalPss*1024);
2486 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2492 long[] tmp = new long[2];
2498 synchronized (ActivityManagerService.this) {
2499 if (mPendingPssProcesses.size() <= 0) {
2500 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2501 "Collected PSS of " + num + " processes in "
2502 + (SystemClock.uptimeMillis() - start) + "ms");
2503 mPendingPssProcesses.clear();
2506 proc = mPendingPssProcesses.remove(0);
2507 procState = proc.pssProcState;
2508 lastPssTime = proc.lastPssTime;
2509 if (proc.thread != null && procState == proc.setProcState
2510 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2511 < SystemClock.uptimeMillis()) {
2519 long pss = Debug.getPss(pid, tmp, null);
2520 synchronized (ActivityManagerService.this) {
2521 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2522 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2524 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2525 SystemClock.uptimeMillis());
2535 public void setSystemProcess() {
2537 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2538 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2539 ServiceManager.addService("meminfo", new MemBinder(this));
2540 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2541 ServiceManager.addService("dbinfo", new DbBinder(this));
2542 if (MONITOR_CPU_USAGE) {
2543 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2545 ServiceManager.addService("permission", new PermissionController(this));
2546 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2548 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2549 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2550 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2552 synchronized (this) {
2553 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2554 app.persistent = true;
2556 app.maxAdj = ProcessList.SYSTEM_ADJ;
2557 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2558 synchronized (mPidsSelfLocked) {
2559 mPidsSelfLocked.put(app.pid, app);
2561 updateLruProcessLocked(app, false, null);
2562 updateOomAdjLocked();
2564 } catch (PackageManager.NameNotFoundException e) {
2565 throw new RuntimeException(
2566 "Unable to find android system package", e);
2570 public void setWindowManager(WindowManagerService wm) {
2571 mWindowManager = wm;
2572 mStackSupervisor.setWindowManager(wm);
2573 mActivityStarter.setWindowManager(wm);
2576 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2577 mUsageStatsService = usageStatsManager;
2580 public void startObservingNativeCrashes() {
2581 final NativeCrashListener ncl = new NativeCrashListener(this);
2585 public IAppOpsService getAppOpsService() {
2586 return mAppOpsService;
2589 static class MemBinder extends Binder {
2590 ActivityManagerService mActivityManagerService;
2591 MemBinder(ActivityManagerService activityManagerService) {
2592 mActivityManagerService = activityManagerService;
2596 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2597 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2598 "meminfo", pw)) return;
2599 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2603 static class GraphicsBinder extends Binder {
2604 ActivityManagerService mActivityManagerService;
2605 GraphicsBinder(ActivityManagerService activityManagerService) {
2606 mActivityManagerService = activityManagerService;
2610 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2611 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2612 "gfxinfo", pw)) return;
2613 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2617 static class DbBinder extends Binder {
2618 ActivityManagerService mActivityManagerService;
2619 DbBinder(ActivityManagerService activityManagerService) {
2620 mActivityManagerService = activityManagerService;
2624 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2625 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2626 "dbinfo", pw)) return;
2627 mActivityManagerService.dumpDbInfo(fd, pw, args);
2631 static class CpuBinder extends Binder {
2632 ActivityManagerService mActivityManagerService;
2633 CpuBinder(ActivityManagerService activityManagerService) {
2634 mActivityManagerService = activityManagerService;
2638 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2639 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2640 "cpuinfo", pw)) return;
2641 synchronized (mActivityManagerService.mProcessCpuTracker) {
2642 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2643 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2644 SystemClock.uptimeMillis()));
2649 public static final class Lifecycle extends SystemService {
2650 private final ActivityManagerService mService;
2652 public Lifecycle(Context context) {
2654 mService = new ActivityManagerService(context);
2658 public void onStart() {
2662 public ActivityManagerService getService() {
2668 public ActivityManagerService(Injector injector) {
2669 mInjector = injector;
2670 mContext = mInjector.getContext();
2673 mActivityStarter = null;
2675 mAppOpsService = mInjector.getAppOpsService(null, null);
2676 mBatteryStatsService = null;
2677 mCompatModePackages = null;
2681 mHandlerThread = null;
2682 mIntentFirewall = null;
2683 mKeyguardController = null;
2684 mPermissionReviewRequired = false;
2685 mProcessCpuThread = null;
2686 mProcessStats = null;
2687 mProviderMap = null;
2688 mRecentTasks = null;
2690 mStackSupervisor = null;
2691 mSystemThread = null;
2692 mTaskChangeNotificationController = null;
2693 mUiHandler = injector.getUiHandler(null);
2694 mUserController = null;
2695 mVrController = null;
2698 // Note: This method is invoked on the main thread but may need to attach various
2699 // handlers to other threads. So take care to be explicit about the looper.
2700 public ActivityManagerService(Context systemContext) {
2701 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2702 mInjector = new Injector();
2703 mContext = systemContext;
2705 mFactoryTest = FactoryTest.getMode();
2706 mSystemThread = ActivityThread.currentActivityThread();
2707 mUiContext = mSystemThread.getSystemUiContext();
2709 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2711 mPermissionReviewRequired = mContext.getResources().getBoolean(
2712 com.android.internal.R.bool.config_permissionReviewRequired);
2714 mHandlerThread = new ServiceThread(TAG,
2715 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2716 mHandlerThread.start();
2717 mHandler = new MainHandler(mHandlerThread.getLooper());
2718 mUiHandler = mInjector.getUiHandler(this);
2720 mConstants = new ActivityManagerConstants(this, mHandler);
2722 /* static; one-time init here */
2723 if (sKillHandler == null) {
2724 sKillThread = new ServiceThread(TAG + ":kill",
2725 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2726 sKillThread.start();
2727 sKillHandler = new KillHandler(sKillThread.getLooper());
2730 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2731 "foreground", BROADCAST_FG_TIMEOUT, false);
2732 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2733 "background", BROADCAST_BG_TIMEOUT, true);
2734 mBroadcastQueues[0] = mFgBroadcastQueue;
2735 mBroadcastQueues[1] = mBgBroadcastQueue;
2737 mServices = new ActiveServices(this);
2738 mProviderMap = new ProviderMap(this);
2739 mAppErrors = new AppErrors(mUiContext, this);
2741 // TODO: Move creation of battery stats service outside of activity manager service.
2742 File dataDir = Environment.getDataDirectory();
2743 File systemDir = new File(dataDir, "system");
2745 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2746 mBatteryStatsService.getActiveStatistics().readLocked();
2747 mBatteryStatsService.scheduleWriteToDisk();
2748 mOnBattery = DEBUG_POWER ? true
2749 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2750 mBatteryStatsService.getActiveStatistics().setCallback(this);
2752 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2754 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2755 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2756 new IAppOpsCallback.Stub() {
2757 @Override public void opChanged(int op, int uid, String packageName) {
2758 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2759 if (mAppOpsService.checkOperation(op, uid, packageName)
2760 != AppOpsManager.MODE_ALLOWED) {
2761 runInBackgroundDisabled(uid);
2767 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2769 mUserController = new UserController(this);
2771 mVrController = new VrController(this);
2773 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2774 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2776 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2777 mUseFifoUiScheduling = true;
2780 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2781 mTempConfig.setToDefaults();
2782 mTempConfig.setLocales(LocaleList.getDefault());
2783 mConfigurationSeq = mTempConfig.seq = 1;
2784 mStackSupervisor = createStackSupervisor();
2785 mStackSupervisor.onConfigurationChanged(mTempConfig);
2786 mKeyguardController = mStackSupervisor.mKeyguardController;
2787 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2788 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2789 mTaskChangeNotificationController =
2790 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2791 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2792 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2794 mProcessCpuThread = new Thread("CpuTracker") {
2797 synchronized (mProcessCpuTracker) {
2798 mProcessCpuInitLatch.countDown();
2799 mProcessCpuTracker.init();
2804 synchronized(this) {
2805 final long now = SystemClock.uptimeMillis();
2806 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2807 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2808 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2809 // + ", write delay=" + nextWriteDelay);
2810 if (nextWriteDelay < nextCpuDelay) {
2811 nextCpuDelay = nextWriteDelay;
2813 if (nextCpuDelay > 0) {
2814 mProcessCpuMutexFree.set(true);
2815 this.wait(nextCpuDelay);
2818 } catch (InterruptedException e) {
2820 updateCpuStatsNow();
2821 } catch (Exception e) {
2822 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2828 Watchdog.getInstance().addMonitor(this);
2829 Watchdog.getInstance().addThread(mHandler);
2832 protected ActivityStackSupervisor createStackSupervisor() {
2833 return new ActivityStackSupervisor(this, mHandler.getLooper());
2836 public void setSystemServiceManager(SystemServiceManager mgr) {
2837 mSystemServiceManager = mgr;
2840 public void setInstaller(Installer installer) {
2841 mInstaller = installer;
2844 private void start() {
2845 removeAllProcessGroups();
2846 mProcessCpuThread.start();
2848 mBatteryStatsService.publish(mContext);
2849 mAppOpsService.publish(mContext);
2850 Slog.d("AppOps", "AppOpsService published");
2851 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2852 // Wait for the synchronized block started in mProcessCpuThread,
2853 // so that any other acccess to mProcessCpuTracker from main thread
2854 // will be blocked during mProcessCpuTracker initialization.
2856 mProcessCpuInitLatch.await();
2857 } catch (InterruptedException e) {
2858 Slog.wtf(TAG, "Interrupted wait during start", e);
2859 Thread.currentThread().interrupt();
2860 throw new IllegalStateException("Interrupted wait during start");
2864 void onUserStoppedLocked(int userId) {
2865 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2868 public void initPowerManagement() {
2869 mStackSupervisor.initPowerManagement();
2870 mBatteryStatsService.initPowerManagement();
2871 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2872 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2873 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2874 mVoiceWakeLock.setReferenceCounted(false);
2877 private ArraySet<String> getBackgroundLaunchBroadcasts() {
2878 if (mBackgroundLaunchBroadcasts == null) {
2879 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2881 return mBackgroundLaunchBroadcasts;
2885 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2886 throws RemoteException {
2887 if (code == SYSPROPS_TRANSACTION) {
2888 // We need to tell all apps about the system property change.
2889 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2890 synchronized(this) {
2891 final int NP = mProcessNames.getMap().size();
2892 for (int ip=0; ip<NP; ip++) {
2893 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2894 final int NA = apps.size();
2895 for (int ia=0; ia<NA; ia++) {
2896 ProcessRecord app = apps.valueAt(ia);
2897 if (app.thread != null) {
2898 procs.add(app.thread.asBinder());
2904 int N = procs.size();
2905 for (int i=0; i<N; i++) {
2906 Parcel data2 = Parcel.obtain();
2908 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2909 Binder.FLAG_ONEWAY);
2910 } catch (RemoteException e) {
2916 return super.onTransact(code, data, reply, flags);
2917 } catch (RuntimeException e) {
2918 // The activity manager only throws security exceptions, so let's
2920 if (!(e instanceof SecurityException)) {
2921 Slog.wtf(TAG, "Activity Manager Crash."
2922 + " UID:" + Binder.getCallingUid()
2923 + " PID:" + Binder.getCallingPid()
2924 + " TRANS:" + code, e);
2930 void updateCpuStats() {
2931 final long now = SystemClock.uptimeMillis();
2932 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2935 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2936 synchronized (mProcessCpuThread) {
2937 mProcessCpuThread.notify();
2942 void updateCpuStatsNow() {
2943 synchronized (mProcessCpuTracker) {
2944 mProcessCpuMutexFree.set(false);
2945 final long now = SystemClock.uptimeMillis();
2946 boolean haveNewCpuStats = false;
2948 if (MONITOR_CPU_USAGE &&
2949 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2950 mLastCpuTime.set(now);
2951 mProcessCpuTracker.update();
2952 if (mProcessCpuTracker.hasGoodLastStats()) {
2953 haveNewCpuStats = true;
2954 //Slog.i(TAG, mProcessCpu.printCurrentState());
2955 //Slog.i(TAG, "Total CPU usage: "
2956 // + mProcessCpu.getTotalCpuPercent() + "%");
2958 // Slog the cpu usage if the property is set.
2959 if ("true".equals(SystemProperties.get("events.cpu"))) {
2960 int user = mProcessCpuTracker.getLastUserTime();
2961 int system = mProcessCpuTracker.getLastSystemTime();
2962 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2963 int irq = mProcessCpuTracker.getLastIrqTime();
2964 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2965 int idle = mProcessCpuTracker.getLastIdleTime();
2967 int total = user + system + iowait + irq + softIrq + idle;
2968 if (total == 0) total = 1;
2970 EventLog.writeEvent(EventLogTags.CPU,
2971 ((user+system+iowait+irq+softIrq) * 100) / total,
2972 (user * 100) / total,
2973 (system * 100) / total,
2974 (iowait * 100) / total,
2975 (irq * 100) / total,
2976 (softIrq * 100) / total);
2981 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2982 synchronized(bstats) {
2983 synchronized(mPidsSelfLocked) {
2984 if (haveNewCpuStats) {
2985 if (bstats.startAddingCpuLocked()) {
2988 final int N = mProcessCpuTracker.countStats();
2989 for (int i=0; i<N; i++) {
2990 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2994 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2995 totalUTime += st.rel_utime;
2996 totalSTime += st.rel_stime;
2998 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2999 if (ps == null || !ps.isActive()) {
3000 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3001 pr.info.uid, pr.processName);
3003 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3004 pr.curCpuTime += st.rel_utime + st.rel_stime;
3006 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3007 if (ps == null || !ps.isActive()) {
3008 st.batteryStats = ps = bstats.getProcessStatsLocked(
3009 bstats.mapUid(st.uid), st.name);
3011 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3014 final int userTime = mProcessCpuTracker.getLastUserTime();
3015 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3016 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3017 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3018 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3019 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3020 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3021 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3026 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3027 mLastWriteTime = now;
3028 mBatteryStatsService.scheduleWriteToDisk();
3035 public void batteryNeedsCpuUpdate() {
3036 updateCpuStatsNow();
3040 public void batteryPowerChanged(boolean onBattery) {
3041 // When plugging in, update the CPU stats first before changing
3043 updateCpuStatsNow();
3044 synchronized (this) {
3045 synchronized(mPidsSelfLocked) {
3046 mOnBattery = DEBUG_POWER ? true : onBattery;
3052 public void batterySendBroadcast(Intent intent) {
3053 synchronized (this) {
3054 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3055 AppOpsManager.OP_NONE, null, false, false,
3056 -1, SYSTEM_UID, UserHandle.USER_ALL);
3061 * Initialize the application bind args. These are passed to each
3062 * process when the bindApplication() IPC is sent to the process. They're
3063 * lazily setup to make sure the services are running when they're asked for.
3065 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3066 // Isolated processes won't get this optimization, so that we don't
3067 // violate the rules about which services they have access to.
3069 if (mIsolatedAppBindArgs == null) {
3070 mIsolatedAppBindArgs = new HashMap<>();
3071 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3073 return mIsolatedAppBindArgs;
3076 if (mAppBindArgs == null) {
3077 mAppBindArgs = new HashMap<>();
3079 // Setup the application init args
3080 mAppBindArgs.put("package", ServiceManager.getService("package"));
3081 mAppBindArgs.put("window", ServiceManager.getService("window"));
3082 mAppBindArgs.put(Context.ALARM_SERVICE,
3083 ServiceManager.getService(Context.ALARM_SERVICE));
3085 return mAppBindArgs;
3089 * Update AMS states when an activity is resumed. This should only be called by
3090 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3092 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3093 final TaskRecord task = r.getTask();
3094 if (task.isApplicationTask()) {
3095 if (mCurAppTimeTracker != r.appTimeTracker) {
3096 // We are switching app tracking. Complete the current one.
3097 if (mCurAppTimeTracker != null) {
3098 mCurAppTimeTracker.stop();
3099 mHandler.obtainMessage(
3100 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3101 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3102 mCurAppTimeTracker = null;
3104 if (r.appTimeTracker != null) {
3105 mCurAppTimeTracker = r.appTimeTracker;
3106 startTimeTrackingFocusedActivityLocked();
3109 startTimeTrackingFocusedActivityLocked();
3112 r.appTimeTracker = null;
3114 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3115 // TODO: Probably not, because we don't want to resume voice on switching
3116 // back to this activity
3117 if (task.voiceInteractor != null) {
3118 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3120 finishRunningVoiceLocked();
3122 if (mLastResumedActivity != null) {
3123 final IVoiceInteractionSession session;
3125 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3126 if (lastResumedActivityTask != null
3127 && lastResumedActivityTask.voiceSession != null) {
3128 session = lastResumedActivityTask.voiceSession;
3130 session = mLastResumedActivity.voiceSession;
3133 if (session != null) {
3134 // We had been in a voice interaction session, but now focused has
3135 // move to something different. Just finish the session, we can't
3136 // return to it and retain the proper state and synchronization with
3137 // the voice interaction service.
3138 finishVoiceTask(session);
3143 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3144 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3145 mHandler.obtainMessage(
3146 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3148 mLastResumedActivity = r;
3150 mWindowManager.setFocusedApp(r.appToken, true);
3152 applyUpdateLockStateLocked(r);
3153 applyUpdateVrModeLocked(r);
3155 EventLogTags.writeAmSetResumedActivity(
3156 r == null ? -1 : r.userId,
3157 r == null ? "NULL" : r.shortComponentName,
3162 public void setFocusedStack(int stackId) {
3163 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3164 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3165 final long callingId = Binder.clearCallingIdentity();
3167 synchronized (this) {
3168 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3169 if (stack == null) {
3172 final ActivityRecord r = stack.topRunningActivityLocked();
3173 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3174 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3178 Binder.restoreCallingIdentity(callingId);
3183 public void setFocusedTask(int taskId) {
3184 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3185 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3186 final long callingId = Binder.clearCallingIdentity();
3188 synchronized (this) {
3189 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3193 final ActivityRecord r = task.topRunningActivityLocked();
3194 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3195 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3199 Binder.restoreCallingIdentity(callingId);
3203 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3205 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3206 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3207 mTaskChangeNotificationController.registerTaskStackListener(listener);
3211 * Unregister a task stack listener so that it stops receiving callbacks.
3214 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3215 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3216 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3220 public void notifyActivityDrawn(IBinder token) {
3221 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3222 synchronized (this) {
3223 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3225 r.getStack().notifyActivityDrawnLocked(r);
3230 final void applyUpdateLockStateLocked(ActivityRecord r) {
3231 // Modifications to the UpdateLock state are done on our handler, outside
3232 // the activity manager's locks. The new state is determined based on the
3233 // state *now* of the relevant activity record. The object is passed to
3234 // the handler solely for logging detail, not to be consulted/modified.
3235 final boolean nextState = r != null && r.immersive;
3236 mHandler.sendMessage(
3237 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3240 final void applyUpdateVrModeLocked(ActivityRecord r) {
3241 mHandler.sendMessage(
3242 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3245 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3246 mHandler.sendMessage(
3247 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3250 private void notifyVrManagerOfSleepState(boolean isSleeping) {
3251 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3252 if (vrService == null) {
3255 vrService.onSleepStateChanged(isSleeping);
3258 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3259 Message msg = Message.obtain();
3260 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3261 msg.obj = r.getTask().askedCompatMode ? null : r;
3262 mUiHandler.sendMessage(msg);
3265 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3266 final Configuration globalConfig = getGlobalConfiguration();
3267 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3268 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3269 final Message msg = Message.obtain();
3270 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3272 mUiHandler.sendMessage(msg);
3276 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3277 String what, Object obj, ProcessRecord srcApp) {
3278 app.lastActivityTime = now;
3280 if (app.activities.size() > 0) {
3281 // Don't want to touch dependent processes that are hosting activities.
3285 int lrui = mLruProcesses.lastIndexOf(app);
3287 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3288 + what + " " + obj + " from " + srcApp);
3292 if (lrui >= index) {
3293 // Don't want to cause this to move dependent processes *back* in the
3294 // list as if they were less frequently used.
3298 if (lrui >= mLruProcessActivityStart) {
3299 // Don't want to touch dependent processes that are hosting activities.
3303 mLruProcesses.remove(lrui);
3307 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3308 + " in LRU list: " + app);
3309 mLruProcesses.add(index, app);
3313 static void killProcessGroup(int uid, int pid) {
3314 if (sKillHandler != null) {
3315 sKillHandler.sendMessage(
3316 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3318 Slog.w(TAG, "Asked to kill process group before system bringup!");
3319 Process.killProcessGroup(uid, pid);
3323 final void removeLruProcessLocked(ProcessRecord app) {
3324 int lrui = mLruProcesses.lastIndexOf(app);
3327 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3328 killProcessQuiet(app.pid);
3329 killProcessGroup(app.uid, app.pid);
3331 if (lrui <= mLruProcessActivityStart) {
3332 mLruProcessActivityStart--;
3334 if (lrui <= mLruProcessServiceStart) {
3335 mLruProcessServiceStart--;
3337 mLruProcesses.remove(lrui);
3341 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3342 ProcessRecord client) {
3343 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3344 || app.treatLikeActivity;
3345 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3346 if (!activityChange && hasActivity) {
3347 // The process has activities, so we are only allowing activity-based adjustments
3348 // to move it. It should be kept in the front of the list with other
3349 // processes that have activities, and we don't want those to change their
3350 // order except due to activity operations.
3355 final long now = SystemClock.uptimeMillis();
3356 app.lastActivityTime = now;
3358 // First a quick reject: if the app is already at the position we will
3359 // put it, then there is nothing to do.
3361 final int N = mLruProcesses.size();
3362 if (N > 0 && mLruProcesses.get(N-1) == app) {
3363 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3367 if (mLruProcessServiceStart > 0
3368 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3369 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3374 int lrui = mLruProcesses.lastIndexOf(app);
3376 if (app.persistent && lrui >= 0) {
3377 // We don't care about the position of persistent processes, as long as
3378 // they are in the list.
3379 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3383 /* In progress: compute new position first, so we can avoid doing work
3384 if the process is not actually going to move. Not yet working.
3387 boolean inActivity = false, inService = false;
3389 // Process has activities, put it at the very tipsy-top.
3390 addIndex = mLruProcesses.size();
3391 nextIndex = mLruProcessServiceStart;
3393 } else if (hasService) {
3394 // Process has services, put it at the top of the service list.
3395 addIndex = mLruProcessActivityStart;
3396 nextIndex = mLruProcessServiceStart;
3400 // Process not otherwise of interest, it goes to the top of the non-service area.
3401 addIndex = mLruProcessServiceStart;
3402 if (client != null) {
3403 int clientIndex = mLruProcesses.lastIndexOf(client);
3404 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3406 if (clientIndex >= 0 && addIndex > clientIndex) {
3407 addIndex = clientIndex;
3410 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3413 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3414 + mLruProcessActivityStart + "): " + app);
3418 if (lrui < mLruProcessActivityStart) {
3419 mLruProcessActivityStart--;
3421 if (lrui < mLruProcessServiceStart) {
3422 mLruProcessServiceStart--;
3425 if (addIndex > lrui) {
3428 if (nextIndex > lrui) {
3432 mLruProcesses.remove(lrui);
3436 mLruProcesses.add(addIndex, app);
3438 mLruProcessActivityStart++;
3441 mLruProcessActivityStart++;
3447 final int N = mLruProcesses.size();
3448 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3449 // Process doesn't have activities, but has clients with
3450 // activities... move it up, but one below the top (the top
3451 // should always have a real activity).
3452 if (DEBUG_LRU) Slog.d(TAG_LRU,
3453 "Adding to second-top of LRU activity list: " + app);
3454 mLruProcesses.add(N - 1, app);
3455 // To keep it from spamming the LRU list (by making a bunch of clients),
3456 // we will push down any other entries owned by the app.
3457 final int uid = app.info.uid;
3458 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3459 ProcessRecord subProc = mLruProcesses.get(i);
3460 if (subProc.info.uid == uid) {
3461 // We want to push this one down the list. If the process after
3462 // it is for the same uid, however, don't do so, because we don't
3463 // want them internally to be re-ordered.
3464 if (mLruProcesses.get(i - 1).info.uid != uid) {
3465 if (DEBUG_LRU) Slog.d(TAG_LRU,
3466 "Pushing uid " + uid + " swapping at " + i + ": "
3467 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3468 ProcessRecord tmp = mLruProcesses.get(i);
3469 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3470 mLruProcesses.set(i - 1, tmp);
3474 // A gap, we can stop here.
3479 // Process has activities, put it at the very tipsy-top.
3480 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3481 mLruProcesses.add(app);
3483 nextIndex = mLruProcessServiceStart;
3484 } else if (hasService) {
3485 // Process has services, put it at the top of the service list.
3486 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3487 mLruProcesses.add(mLruProcessActivityStart, app);
3488 nextIndex = mLruProcessServiceStart;
3489 mLruProcessActivityStart++;
3491 // Process not otherwise of interest, it goes to the top of the non-service area.
3492 int index = mLruProcessServiceStart;
3493 if (client != null) {
3494 // If there is a client, don't allow the process to be moved up higher
3495 // in the list than that client.
3496 int clientIndex = mLruProcesses.lastIndexOf(client);
3497 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3498 + " when updating " + app);
3499 if (clientIndex <= lrui) {
3500 // Don't allow the client index restriction to push it down farther in the
3501 // list than it already is.
3504 if (clientIndex >= 0 && index > clientIndex) {
3505 index = clientIndex;
3508 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3509 mLruProcesses.add(index, app);
3510 nextIndex = index-1;
3511 mLruProcessActivityStart++;
3512 mLruProcessServiceStart++;
3515 // If the app is currently using a content provider or service,
3516 // bump those processes as well.
3517 for (int j=app.connections.size()-1; j>=0; j--) {
3518 ConnectionRecord cr = app.connections.valueAt(j);
3519 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3520 && cr.binding.service.app != null
3521 && cr.binding.service.app.lruSeq != mLruSeq
3522 && !cr.binding.service.app.persistent) {
3523 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3524 "service connection", cr, app);
3527 for (int j=app.conProviders.size()-1; j>=0; j--) {
3528 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3529 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3530 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3531 "provider reference", cpr, app);
3536 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3537 if (uid == SYSTEM_UID) {
3538 // The system gets to run in any process. If there are multiple
3539 // processes with the same uid, just pick the first (this
3540 // should never happen).
3541 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3542 if (procs == null) return null;
3543 final int procCount = procs.size();
3544 for (int i = 0; i < procCount; i++) {
3545 final int procUid = procs.keyAt(i);
3546 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3547 // Don't use an app process or different user process for system component.
3550 return procs.valueAt(i);
3553 ProcessRecord proc = mProcessNames.get(processName, uid);
3554 if (false && proc != null && !keepIfLarge
3555 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3556 && proc.lastCachedPss >= 4000) {
3557 // Turn this condition on to cause killing to happen regularly, for testing.
3558 if (proc.baseProcessTracker != null) {
3559 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3561 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3562 } else if (proc != null && !keepIfLarge
3563 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3564 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3565 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3566 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3567 if (proc.baseProcessTracker != null) {
3568 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3570 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3576 void notifyPackageUse(String packageName, int reason) {
3577 IPackageManager pm = AppGlobals.getPackageManager();
3579 pm.notifyPackageUse(packageName, reason);
3580 } catch (RemoteException e) {
3584 boolean isNextTransitionForward() {
3585 int transit = mWindowManager.getPendingAppTransition();
3586 return transit == TRANSIT_ACTIVITY_OPEN
3587 || transit == TRANSIT_TASK_OPEN
3588 || transit == TRANSIT_TASK_TO_FRONT;
3591 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3592 String processName, String abiOverride, int uid, Runnable crashHandler) {
3593 synchronized(this) {
3594 ApplicationInfo info = new ApplicationInfo();
3595 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3596 // For isolated processes, the former contains the parent's uid and the latter the
3597 // actual uid of the isolated process.
3598 // In the special case introduced by this method (which is, starting an isolated
3599 // process directly from the SystemServer without an actual parent app process) the
3600 // closest thing to a parent's uid is SYSTEM_UID.
3601 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3602 // the |isolated| logic in the ProcessRecord constructor.
3603 info.uid = SYSTEM_UID;
3604 info.processName = processName;
3605 info.className = entryPoint;
3606 info.packageName = "android";
3607 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3608 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3609 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3610 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3611 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3613 return proc != null ? proc.pid : 0;
3617 final ProcessRecord startProcessLocked(String processName,
3618 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3619 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3620 boolean isolated, boolean keepIfLarge) {
3621 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3622 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3623 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3624 null /* crashHandler */);
3627 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3628 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3629 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3630 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3631 long startTime = SystemClock.elapsedRealtime();
3634 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3635 checkTime(startTime, "startProcess: after getProcessRecord");
3637 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3638 // If we are in the background, then check to see if this process
3639 // is bad. If so, we will just silently fail.
3640 if (mAppErrors.isBadProcessLocked(info)) {
3641 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3642 + "/" + info.processName);
3646 // When the user is explicitly starting a process, then clear its
3647 // crash count so that we won't make it bad until they see at
3648 // least one crash dialog again, and make the process good again
3649 // if it had been bad.
3650 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3651 + "/" + info.processName);
3652 mAppErrors.resetProcessCrashTimeLocked(info);
3653 if (mAppErrors.isBadProcessLocked(info)) {
3654 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3655 UserHandle.getUserId(info.uid), info.uid,
3657 mAppErrors.clearBadProcessLocked(info);
3664 // If this is an isolated process, it can't re-use an existing process.
3668 // We don't have to do anything more if:
3669 // (1) There is an existing application record; and
3670 // (2) The caller doesn't think it is dead, OR there is no thread
3671 // object attached to it so we know it couldn't have crashed; and
3672 // (3) There is a pid assigned to it, so it is either starting or
3674 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3675 + " app=" + app + " knownToBeDead=" + knownToBeDead
3676 + " thread=" + (app != null ? app.thread : null)
3677 + " pid=" + (app != null ? app.pid : -1));
3678 if (app != null && app.pid > 0) {
3679 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3680 // We already have the app running, or are waiting for it to
3681 // come up (we have a pid but not yet its thread), so keep it.
3682 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3683 // If this is a new package in the process, add the package to the list
3684 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3685 checkTime(startTime, "startProcess: done, added package to proc");
3689 // An application record is attached to a previous process,
3691 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3692 checkTime(startTime, "startProcess: bad proc running, killing");
3693 killProcessGroup(app.uid, app.pid);
3694 handleAppDiedLocked(app, true, true);
3695 checkTime(startTime, "startProcess: done killing old proc");
3698 String hostingNameStr = hostingName != null
3699 ? hostingName.flattenToShortString() : null;
3702 checkTime(startTime, "startProcess: creating new process record");
3703 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3705 Slog.w(TAG, "Failed making new process record for "
3706 + processName + "/" + info.uid + " isolated=" + isolated);
3709 app.crashHandler = crashHandler;
3710 checkTime(startTime, "startProcess: done creating new process record");
3712 // If this is a new package in the process, add the package to the list
3713 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3714 checkTime(startTime, "startProcess: added package to existing proc");
3717 // If the system is not ready yet, then hold off on starting this
3718 // process until it is.
3719 if (!mProcessesReady
3720 && !isAllowedWhileBooting(info)
3721 && !allowWhileBooting) {
3722 if (!mProcessesOnHold.contains(app)) {
3723 mProcessesOnHold.add(app);
3725 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3726 "System not ready, putting on hold: " + app);
3727 checkTime(startTime, "startProcess: returning with proc on hold");
3731 checkTime(startTime, "startProcess: stepping in to startProcess");
3733 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3734 checkTime(startTime, "startProcess: done starting proc!");
3735 return (app.pid != 0) ? app : null;
3738 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3739 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3742 private final void startProcessLocked(ProcessRecord app,
3743 String hostingType, String hostingNameStr) {
3744 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3745 null /* entryPoint */, null /* entryPointArgs */);
3748 private final void startProcessLocked(ProcessRecord app, String hostingType,
3749 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3750 long startTime = SystemClock.elapsedRealtime();
3751 if (app.pid > 0 && app.pid != MY_PID) {
3752 checkTime(startTime, "startProcess: removing from pids map");
3753 synchronized (mPidsSelfLocked) {
3754 mPidsSelfLocked.remove(app.pid);
3755 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3757 checkTime(startTime, "startProcess: done removing from pids map");
3761 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3762 "startProcessLocked removing on hold: " + app);
3763 mProcessesOnHold.remove(app);
3765 checkTime(startTime, "startProcess: starting to update cpu stats");
3767 checkTime(startTime, "startProcess: done updating cpu stats");
3771 final int userId = UserHandle.getUserId(app.uid);
3772 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3773 } catch (RemoteException e) {
3774 throw e.rethrowAsRuntimeException();
3779 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3780 if (!app.isolated) {
3781 int[] permGids = null;
3783 checkTime(startTime, "startProcess: getting gids from package manager");
3784 final IPackageManager pm = AppGlobals.getPackageManager();
3785 permGids = pm.getPackageGids(app.info.packageName,
3786 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3787 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3788 StorageManagerInternal.class);
3789 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3790 app.info.packageName);
3791 } catch (RemoteException e) {
3792 throw e.rethrowAsRuntimeException();
3796 * Add shared application and profile GIDs so applications can share some
3797 * resources like shared libraries and access user-wide resources
3799 if (ArrayUtils.isEmpty(permGids)) {
3802 gids = new int[permGids.length + 3];
3803 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3805 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3806 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3807 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3809 checkTime(startTime, "startProcess: building args");
3810 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3811 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3812 && mTopComponent != null
3813 && app.processName.equals(mTopComponent.getPackageName())) {
3816 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3817 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3822 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3823 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3824 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3825 // Also turn on CheckJNI for debuggable apps. It's quite
3826 // awkward to turn on otherwise.
3827 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3829 // Run the app in safe mode if its manifest requests so or the
3830 // system is booted in safe mode.
3831 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3832 mSafeMode == true) {
3833 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3835 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3836 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3838 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3839 if ("true".equals(genDebugInfoProperty)) {
3840 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3842 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3843 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3845 if ("1".equals(SystemProperties.get("debug.assert"))) {
3846 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3848 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3849 // Enable all debug flags required by the native debugger.
3850 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3851 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3852 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3853 mNativeDebuggingApp = null;
3856 String invokeWith = null;
3857 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3858 // Debuggable apps may include a wrapper script with their library directory.
3859 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3860 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3862 if (new File(wrapperFileName).exists()) {
3863 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3866 StrictMode.setThreadPolicy(oldPolicy);
3870 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3871 if (requiredAbi == null) {
3872 requiredAbi = Build.SUPPORTED_ABIS[0];
3875 String instructionSet = null;
3876 if (app.info.primaryCpuAbi != null) {
3877 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3881 app.requiredAbi = requiredAbi;
3882 app.instructionSet = instructionSet;
3884 // the per-user SELinux context must be set
3885 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3886 Slog.wtf(TAG, "SELinux tag not defined",
3887 new IllegalStateException("SELinux tag not defined for "
3888 + app.info.packageName + " (uid " + app.uid + ")"));
3890 final String seInfo = app.info.seInfo
3891 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3892 // Start the process. It will either succeed and return a result containing
3893 // the PID of the new process, or else throw a RuntimeException.
3894 boolean isActivityProcess = (entryPoint == null);
3895 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3896 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3898 checkTime(startTime, "startProcess: asking zygote to start proc");
3899 ProcessStartResult startResult;
3900 if (hostingType.equals("webview_service")) {
3901 startResult = startWebView(entryPoint,
3902 app.processName, uid, uid, gids, debugFlags, mountExternal,
3903 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3904 app.info.dataDir, null, entryPointArgs);
3906 startResult = Process.start(entryPoint,
3907 app.processName, uid, uid, gids, debugFlags, mountExternal,
3908 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3909 app.info.dataDir, invokeWith, entryPointArgs);
3911 checkTime(startTime, "startProcess: returned from zygote!");
3912 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3914 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3915 checkTime(startTime, "startProcess: done updating battery stats");
3917 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3918 UserHandle.getUserId(uid), startResult.pid, uid,
3919 app.processName, hostingType,
3920 hostingNameStr != null ? hostingNameStr : "");
3923 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3924 seInfo, app.info.sourceDir, startResult.pid);
3925 } catch (RemoteException ex) {
3929 if (app.persistent) {
3930 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3933 checkTime(startTime, "startProcess: building log message");
3934 StringBuilder buf = mStringBuilder;
3936 buf.append("Start proc ");
3937 buf.append(startResult.pid);
3939 buf.append(app.processName);
3941 UserHandle.formatUid(buf, uid);
3942 if (!isActivityProcess) {
3944 buf.append(entryPoint);
3947 buf.append(" for ");
3948 buf.append(hostingType);
3949 if (hostingNameStr != null) {
3951 buf.append(hostingNameStr);
3953 Slog.i(TAG, buf.toString());
3954 app.setPid(startResult.pid);
3955 app.usingWrapper = startResult.usingWrapper;
3956 app.removed = false;
3958 app.killedByAm = false;
3959 checkTime(startTime, "startProcess: starting to update pids map");
3960 ProcessRecord oldApp;
3961 synchronized (mPidsSelfLocked) {
3962 oldApp = mPidsSelfLocked.get(startResult.pid);
3964 // If there is already an app occupying that pid that hasn't been cleaned up
3965 if (oldApp != null && !app.isolated) {
3966 // Clean up anything relating to this pid first
3967 Slog.w(TAG, "Reusing pid " + startResult.pid
3968 + " while app is still mapped to it");
3969 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3970 true /*replacingPid*/);
3972 synchronized (mPidsSelfLocked) {
3973 this.mPidsSelfLocked.put(startResult.pid, app);
3974 if (isActivityProcess) {
3975 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3977 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3978 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3981 checkTime(startTime, "startProcess: done updating pids map");
3982 } catch (RuntimeException e) {
3983 Slog.e(TAG, "Failure starting process " + app.processName, e);
3985 // Something went very wrong while trying to start this process; one
3986 // common case is when the package is frozen due to an active
3987 // upgrade. To recover, clean up any active bookkeeping related to
3988 // starting this process. (We already invoked this method once when
3989 // the package was initially frozen through KILL_APPLICATION_MSG, so
3990 // it doesn't hurt to use it again.)
3991 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3992 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3996 void updateUsageStats(ActivityRecord component, boolean resumed) {
3997 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3998 "updateUsageStats: comp=" + component + "res=" + resumed);
3999 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4001 if (mUsageStatsService != null) {
4002 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4003 UsageEvents.Event.MOVE_TO_FOREGROUND);
4005 synchronized (stats) {
4006 stats.noteActivityResumedLocked(component.app.uid);
4009 if (mUsageStatsService != null) {
4010 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4011 UsageEvents.Event.MOVE_TO_BACKGROUND);
4013 synchronized (stats) {
4014 stats.noteActivityPausedLocked(component.app.uid);
4019 Intent getHomeIntent() {
4020 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4021 intent.setComponent(mTopComponent);
4022 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4023 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4024 intent.addCategory(Intent.CATEGORY_HOME);
4029 boolean startHomeActivityLocked(int userId, String reason) {
4030 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4031 && mTopAction == null) {
4032 // We are running in factory test mode, but unable to find
4033 // the factory test app, so just sit around displaying the
4034 // error message and don't try to start anything.
4037 Intent intent = getHomeIntent();
4038 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4039 if (aInfo != null) {
4040 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4041 // Don't do this if the home app is currently being
4043 aInfo = new ActivityInfo(aInfo);
4044 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4045 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4046 aInfo.applicationInfo.uid, true);
4047 if (app == null || app.instr == null) {
4048 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4049 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
4052 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4058 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4059 ActivityInfo ai = null;
4060 ComponentName comp = intent.getComponent();
4064 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4066 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4068 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4072 ai = info.activityInfo;
4075 } catch (RemoteException e) {
4083 * Starts the "new version setup screen" if appropriate.
4085 void startSetupActivityLocked() {
4086 // Only do this once per boot.
4087 if (mCheckedForSetup) {
4091 // We will show this screen if the current one is a different
4092 // version than the last one shown, and we are not running in
4093 // low-level factory test mode.
4094 final ContentResolver resolver = mContext.getContentResolver();
4095 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4096 Settings.Global.getInt(resolver,
4097 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4098 mCheckedForSetup = true;
4100 // See if we should be showing the platform update setup UI.
4101 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4102 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4103 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4104 if (!ris.isEmpty()) {
4105 final ResolveInfo ri = ris.get(0);
4106 String vers = ri.activityInfo.metaData != null
4107 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4109 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4110 vers = ri.activityInfo.applicationInfo.metaData.getString(
4111 Intent.METADATA_SETUP_VERSION);
4113 String lastVers = Settings.Secure.getString(
4114 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4115 if (vers != null && !vers.equals(lastVers)) {
4116 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4117 intent.setComponent(new ComponentName(
4118 ri.activityInfo.packageName, ri.activityInfo.name));
4119 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4120 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4121 null, 0, 0, 0, null, false, false, null, null, null,
4122 "startSetupActivity");
4128 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4129 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4132 void enforceNotIsolatedCaller(String caller) {
4133 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4134 throw new SecurityException("Isolated process not allowed to call " + caller);
4138 void enforceShellRestriction(String restriction, int userHandle) {
4139 if (Binder.getCallingUid() == SHELL_UID) {
4140 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4141 throw new SecurityException("Shell does not have permission to access user "
4148 public int getFrontActivityScreenCompatMode() {
4149 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4150 synchronized (this) {
4151 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4156 public void setFrontActivityScreenCompatMode(int mode) {
4157 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4158 "setFrontActivityScreenCompatMode");
4159 synchronized (this) {
4160 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4165 public int getPackageScreenCompatMode(String packageName) {
4166 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4167 synchronized (this) {
4168 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4173 public void setPackageScreenCompatMode(String packageName, int mode) {
4174 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4175 "setPackageScreenCompatMode");
4176 synchronized (this) {
4177 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4182 public boolean getPackageAskScreenCompat(String packageName) {
4183 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4184 synchronized (this) {
4185 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4190 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4191 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4192 "setPackageAskScreenCompat");
4193 synchronized (this) {
4194 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4198 private boolean hasUsageStatsPermission(String callingPackage) {
4199 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4200 Binder.getCallingUid(), callingPackage);
4201 if (mode == AppOpsManager.MODE_DEFAULT) {
4202 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4203 == PackageManager.PERMISSION_GRANTED;
4205 return mode == AppOpsManager.MODE_ALLOWED;
4209 public int getPackageProcessState(String packageName, String callingPackage) {
4210 if (!hasUsageStatsPermission(callingPackage)) {
4211 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4212 "getPackageProcessState");
4215 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4216 synchronized (this) {
4217 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4218 final ProcessRecord proc = mLruProcesses.get(i);
4219 if (procState > proc.setProcState) {
4220 if (proc.pkgList.containsKey(packageName) ||
4221 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4222 procState = proc.setProcState;
4231 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4232 throws RemoteException {
4233 synchronized (this) {
4234 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4236 throw new IllegalArgumentException("Unknown process: " + process);
4238 if (app.thread == null) {
4239 throw new IllegalArgumentException("Process has no app thread");
4241 if (app.trimMemoryLevel >= level) {
4242 throw new IllegalArgumentException(
4243 "Unable to set a higher trim level than current level");
4245 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4246 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4247 throw new IllegalArgumentException("Unable to set a background trim level "
4248 + "on a foreground process");
4250 app.thread.scheduleTrimMemory(level);
4251 app.trimMemoryLevel = level;
4256 private void dispatchProcessesChanged() {
4258 synchronized (this) {
4259 N = mPendingProcessChanges.size();
4260 if (mActiveProcessChanges.length < N) {
4261 mActiveProcessChanges = new ProcessChangeItem[N];
4263 mPendingProcessChanges.toArray(mActiveProcessChanges);
4264 mPendingProcessChanges.clear();
4265 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4266 "*** Delivering " + N + " process changes");
4269 int i = mProcessObservers.beginBroadcast();
4272 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4273 if (observer != null) {
4275 for (int j=0; j<N; j++) {
4276 ProcessChangeItem item = mActiveProcessChanges[j];
4277 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4278 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4279 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4280 + item.uid + ": " + item.foregroundActivities);
4281 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4282 item.foregroundActivities);
4285 } catch (RemoteException e) {
4289 mProcessObservers.finishBroadcast();
4291 synchronized (this) {
4292 for (int j=0; j<N; j++) {
4293 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4298 private void dispatchProcessDied(int pid, int uid) {
4299 int i = mProcessObservers.beginBroadcast();
4302 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4303 if (observer != null) {
4305 observer.onProcessDied(pid, uid);
4306 } catch (RemoteException e) {
4310 mProcessObservers.finishBroadcast();
4314 void dispatchUidsChanged() {
4316 synchronized (this) {
4317 N = mPendingUidChanges.size();
4318 if (mActiveUidChanges.length < N) {
4319 mActiveUidChanges = new UidRecord.ChangeItem[N];
4321 for (int i=0; i<N; i++) {
4322 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4323 mActiveUidChanges[i] = change;
4324 if (change.uidRecord != null) {
4325 change.uidRecord.pendingChange = null;
4326 change.uidRecord = null;
4329 mPendingUidChanges.clear();
4330 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4331 "*** Delivering " + N + " uid changes");
4334 int i = mUidObservers.beginBroadcast();
4337 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4338 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4340 mUidObservers.finishBroadcast();
4342 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4343 for (int j = 0; j < N; ++j) {
4344 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4345 if (item.change == UidRecord.CHANGE_GONE
4346 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4347 mValidateUids.remove(item.uid);
4349 UidRecord validateUid = mValidateUids.get(item.uid);
4350 if (validateUid == null) {
4351 validateUid = new UidRecord(item.uid);
4352 mValidateUids.put(item.uid, validateUid);
4354 if (item.change == UidRecord.CHANGE_IDLE) {
4355 validateUid.idle = true;
4356 } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4357 validateUid.idle = false;
4359 validateUid.curProcState = validateUid.setProcState = item.processState;
4360 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4365 synchronized (this) {
4366 for (int j = 0; j < N; j++) {
4367 mAvailUidChanges.add(mActiveUidChanges[j]);
4372 private void dispatchUidsChangedForObserver(IUidObserver observer,
4373 UidObserverRegistration reg, int changesSize) {
4374 if (observer == null) {
4378 for (int j = 0; j < changesSize; j++) {
4379 UidRecord.ChangeItem item = mActiveUidChanges[j];
4380 final int change = item.change;
4381 if (change == UidRecord.CHANGE_IDLE
4382 || change == UidRecord.CHANGE_GONE_IDLE) {
4383 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4384 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4385 "UID idle uid=" + item.uid);
4386 observer.onUidIdle(item.uid, item.ephemeral);
4388 } else if (change == UidRecord.CHANGE_ACTIVE) {
4389 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4390 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4391 "UID active uid=" + item.uid);
4392 observer.onUidActive(item.uid);
4395 if (change == UidRecord.CHANGE_GONE
4396 || change == UidRecord.CHANGE_GONE_IDLE) {
4397 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4398 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4399 "UID gone uid=" + item.uid);
4400 observer.onUidGone(item.uid, item.ephemeral);
4402 if (reg.lastProcStates != null) {
4403 reg.lastProcStates.delete(item.uid);
4406 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4407 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4408 "UID CHANGED uid=" + item.uid
4409 + ": " + item.processState);
4410 boolean doReport = true;
4411 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4412 final int lastState = reg.lastProcStates.get(item.uid,
4413 ActivityManager.PROCESS_STATE_UNKNOWN);
4414 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4415 final boolean lastAboveCut = lastState <= reg.cutpoint;
4416 final boolean newAboveCut = item.processState <= reg.cutpoint;
4417 doReport = lastAboveCut != newAboveCut;
4419 doReport = item.processState
4420 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4424 if (reg.lastProcStates != null) {
4425 reg.lastProcStates.put(item.uid, item.processState);
4427 observer.onUidStateChanged(item.uid, item.processState,
4433 } catch (RemoteException e) {
4438 public final int startActivity(IApplicationThread caller, String callingPackage,
4439 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4440 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4441 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4442 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4443 UserHandle.getCallingUserId());
4446 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4447 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4448 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4449 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4450 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4452 // TODO: Switch to user app stacks here.
4453 String mimeType = intent.getType();
4454 final Uri data = intent.getData();
4455 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4456 mimeType = getProviderMimeType(data, userId);
4458 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4460 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4461 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
4462 null, null, 0, 0, null, null, null, null, false, userId, container, null,
4467 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4468 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4469 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4470 enforceNotIsolatedCaller("startActivity");
4471 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4472 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4473 // TODO: Switch to user app stacks here.
4474 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4475 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4476 profilerInfo, null, null, bOptions, false, userId, null, null,
4477 "startActivityAsUser");
4481 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4482 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4483 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4486 // This is very dangerous -- it allows you to perform a start activity (including
4487 // permission grants) as any app that may launch one of your own activities. So
4488 // we will only allow this to be done from activities that are part of the core framework,
4489 // and then only when they are running as the system.
4490 final ActivityRecord sourceRecord;
4491 final int targetUid;
4492 final String targetPackage;
4493 synchronized (this) {
4494 if (resultTo == null) {
4495 throw new SecurityException("Must be called from an activity");
4497 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4498 if (sourceRecord == null) {
4499 throw new SecurityException("Called with bad activity token: " + resultTo);
4501 if (!sourceRecord.info.packageName.equals("android")) {
4502 throw new SecurityException(
4503 "Must be called from an activity that is declared in the android package");
4505 if (sourceRecord.app == null) {
4506 throw new SecurityException("Called without a process attached to activity");
4508 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4509 // This is still okay, as long as this activity is running under the
4510 // uid of the original calling activity.
4511 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4512 throw new SecurityException(
4513 "Calling activity in uid " + sourceRecord.app.uid
4514 + " must be system uid or original calling uid "
4515 + sourceRecord.launchedFromUid);
4518 if (ignoreTargetSecurity) {
4519 if (intent.getComponent() == null) {
4520 throw new SecurityException(
4521 "Component must be specified with ignoreTargetSecurity");
4523 if (intent.getSelector() != null) {
4524 throw new SecurityException(
4525 "Selector not allowed with ignoreTargetSecurity");
4528 targetUid = sourceRecord.launchedFromUid;
4529 targetPackage = sourceRecord.launchedFromPackage;
4532 if (userId == UserHandle.USER_NULL) {
4533 userId = UserHandle.getUserId(sourceRecord.app.uid);
4536 // TODO: Switch to user app stacks here.
4538 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4539 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4540 null, null, bOptions, ignoreTargetSecurity, userId, null, null,
4541 "startActivityAsCaller");
4543 } catch (SecurityException e) {
4544 // XXX need to figure out how to propagate to original app.
4545 // A SecurityException here is generally actually a fault of the original
4546 // calling activity (such as a fairly granting permissions), so propagate it
4549 StringBuilder msg = new StringBuilder();
4550 msg.append("While launching");
4551 msg.append(intent.toString());
4553 msg.append(e.getMessage());
4560 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4561 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4562 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4563 enforceNotIsolatedCaller("startActivityAndWait");
4564 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4565 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4566 WaitResult res = new WaitResult();
4567 // TODO: Switch to user app stacks here.
4568 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4569 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4570 bOptions, false, userId, null, null, "startActivityAndWait");
4575 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4576 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4577 int startFlags, Configuration config, Bundle bOptions, int userId) {
4578 enforceNotIsolatedCaller("startActivityWithConfig");
4579 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4580 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4581 // TODO: Switch to user app stacks here.
4582 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4583 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4584 null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
4589 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4590 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4591 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4592 throws TransactionTooLargeException {
4593 enforceNotIsolatedCaller("startActivityIntentSender");
4594 // Refuse possible leaked file descriptors
4595 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4596 throw new IllegalArgumentException("File descriptors passed in Intent");
4599 if (!(target instanceof PendingIntentRecord)) {
4600 throw new IllegalArgumentException("Bad PendingIntent object");
4603 PendingIntentRecord pir = (PendingIntentRecord)target;
4605 synchronized (this) {
4606 // If this is coming from the currently resumed activity, it is
4607 // effectively saying that app switches are allowed at this point.
4608 final ActivityStack stack = getFocusedStack();
4609 if (stack.mResumedActivity != null &&
4610 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4611 mAppSwitchesAllowedTime = 0;
4614 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4615 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4620 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4621 Intent intent, String resolvedType, IVoiceInteractionSession session,
4622 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4623 Bundle bOptions, int userId) {
4624 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4625 != PackageManager.PERMISSION_GRANTED) {
4626 String msg = "Permission Denial: startVoiceActivity() from pid="
4627 + Binder.getCallingPid()
4628 + ", uid=" + Binder.getCallingUid()
4629 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4631 throw new SecurityException(msg);
4633 if (session == null || interactor == null) {
4634 throw new NullPointerException("null session or interactor");
4636 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4637 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4638 // TODO: Switch to user app stacks here.
4639 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4640 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4641 null, bOptions, false, userId, null, null, "startVoiceActivity");
4645 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4646 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4647 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4648 != PackageManager.PERMISSION_GRANTED) {
4649 final String msg = "Permission Denial: startAssistantActivity() from pid="
4650 + Binder.getCallingPid()
4651 + ", uid=" + Binder.getCallingUid()
4652 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4654 throw new SecurityException(msg);
4656 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4657 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4658 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4659 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4660 userId, null, null, "startAssistantActivity");
4664 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4665 throws RemoteException {
4666 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4667 synchronized (this) {
4668 ActivityRecord activity = getFocusedStack().topActivity();
4669 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4670 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4672 if (mRunningVoice != null || activity.getTask().voiceSession != null
4673 || activity.voiceSession != null) {
4674 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4677 if (activity.pendingVoiceInteractionStart) {
4678 Slog.w(TAG, "Pending start of voice interaction already.");
4681 activity.pendingVoiceInteractionStart = true;
4683 LocalServices.getService(VoiceInteractionManagerInternal.class)
4684 .startLocalVoiceInteraction(callingActivity, options);
4688 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4689 LocalServices.getService(VoiceInteractionManagerInternal.class)
4690 .stopLocalVoiceInteraction(callingActivity);
4694 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4695 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4696 .supportsLocalVoiceInteraction();
4699 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4700 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4701 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4702 if (activityToCallback == null) return;
4703 activityToCallback.setVoiceSessionLocked(voiceSession);
4705 // Inform the activity
4707 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4709 long token = Binder.clearCallingIdentity();
4711 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4713 Binder.restoreCallingIdentity(token);
4715 // TODO: VI Should we cache the activity so that it's easier to find later
4716 // rather than scan through all the stacks and activities?
4717 } catch (RemoteException re) {
4718 activityToCallback.clearVoiceSessionLocked();
4719 // TODO: VI Should this terminate the voice session?
4724 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4725 synchronized (this) {
4726 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4728 mVoiceWakeLock.acquire();
4730 mVoiceWakeLock.release();
4737 public boolean startNextMatchingActivity(IBinder callingActivity,
4738 Intent intent, Bundle bOptions) {
4739 // Refuse possible leaked file descriptors
4740 if (intent != null && intent.hasFileDescriptors() == true) {
4741 throw new IllegalArgumentException("File descriptors passed in Intent");
4743 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4745 synchronized (this) {
4746 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4748 ActivityOptions.abort(options);
4751 if (r.app == null || r.app.thread == null) {
4752 // The caller is not running... d'oh!
4753 ActivityOptions.abort(options);
4756 intent = new Intent(intent);
4757 // The caller is not allowed to change the data.
4758 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4759 // And we are resetting to find the next component...
4760 intent.setComponent(null);
4762 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4764 ActivityInfo aInfo = null;
4766 List<ResolveInfo> resolves =
4767 AppGlobals.getPackageManager().queryIntentActivities(
4768 intent, r.resolvedType,
4769 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4770 UserHandle.getCallingUserId()).getList();
4772 // Look for the original activity in the list...
4773 final int N = resolves != null ? resolves.size() : 0;
4774 for (int i=0; i<N; i++) {
4775 ResolveInfo rInfo = resolves.get(i);
4776 if (rInfo.activityInfo.packageName.equals(r.packageName)
4777 && rInfo.activityInfo.name.equals(r.info.name)) {
4778 // We found the current one... the next matching is
4782 aInfo = resolves.get(i).activityInfo;
4785 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4786 + "/" + r.info.name);
4787 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4788 ? "null" : aInfo.packageName + "/" + aInfo.name));
4793 } catch (RemoteException e) {
4796 if (aInfo == null) {
4797 // Nobody who is next!
4798 ActivityOptions.abort(options);
4799 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4803 intent.setComponent(new ComponentName(
4804 aInfo.applicationInfo.packageName, aInfo.name));
4805 intent.setFlags(intent.getFlags()&~(
4806 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4807 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4808 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4809 Intent.FLAG_ACTIVITY_NEW_TASK));
4811 // Okay now we need to start the new activity, replacing the
4812 // currently running activity. This is a little tricky because
4813 // we want to start the new one as if the current one is finished,
4814 // but not finish the current one first so that there is no flicker.
4816 final boolean wasFinishing = r.finishing;
4819 // Propagate reply information over to the new activity.
4820 final ActivityRecord resultTo = r.resultTo;
4821 final String resultWho = r.resultWho;
4822 final int requestCode = r.requestCode;
4824 if (resultTo != null) {
4825 resultTo.removeResultsLocked(r, resultWho, requestCode);
4828 final long origId = Binder.clearCallingIdentity();
4829 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4830 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4831 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4832 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4833 false, false, null, null, null, "startNextMatchingActivity");
4834 Binder.restoreCallingIdentity(origId);
4836 r.finishing = wasFinishing;
4837 if (res != ActivityManager.START_SUCCESS) {
4845 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4846 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4847 String msg = "Permission Denial: startActivityFromRecents called without " +
4848 START_TASKS_FROM_RECENTS;
4850 throw new SecurityException(msg);
4852 final long origId = Binder.clearCallingIdentity();
4854 synchronized (this) {
4855 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4858 Binder.restoreCallingIdentity(origId);
4862 final int startActivityInPackage(int uid, String callingPackage,
4863 Intent intent, String resolvedType, IBinder resultTo,
4864 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4865 IActivityContainer container, TaskRecord inTask, String reason) {
4867 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4868 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4870 // TODO: Switch to user app stacks here.
4871 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4872 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4873 null, null, null, bOptions, false, userId, container, inTask, reason);
4878 public final int startActivities(IApplicationThread caller, String callingPackage,
4879 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4881 final String reason = "startActivities";
4882 enforceNotIsolatedCaller(reason);
4883 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4884 userId, false, ALLOW_FULL_ONLY, reason, null);
4885 // TODO: Switch to user app stacks here.
4886 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4887 resolvedTypes, resultTo, bOptions, userId, reason);
4891 final int startActivitiesInPackage(int uid, String callingPackage,
4892 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4893 Bundle bOptions, int userId) {
4895 final String reason = "startActivityInPackage";
4896 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4897 userId, false, ALLOW_FULL_ONLY, reason, null);
4898 // TODO: Switch to user app stacks here.
4899 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4900 resultTo, bOptions, userId, reason);
4905 public void reportActivityFullyDrawn(IBinder token) {
4906 synchronized (this) {
4907 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4911 r.reportFullyDrawnLocked();
4916 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4917 synchronized (this) {
4918 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4922 final long origId = Binder.clearCallingIdentity();
4924 r.setRequestedOrientation(requestedOrientation);
4926 Binder.restoreCallingIdentity(origId);
4932 public int getRequestedOrientation(IBinder token) {
4933 synchronized (this) {
4934 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4936 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4938 return r.getRequestedOrientation();
4943 public final void requestActivityRelaunch(IBinder token) {
4944 synchronized(this) {
4945 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4949 final long origId = Binder.clearCallingIdentity();
4951 r.forceNewConfig = true;
4952 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4953 true /* preserveWindow */);
4955 Binder.restoreCallingIdentity(origId);
4961 * This is the internal entry point for handling Activity.finish().
4963 * @param token The Binder token referencing the Activity we want to finish.
4964 * @param resultCode Result code, if any, from this Activity.
4965 * @param resultData Result data (Intent), if any, from this Activity.
4966 * @param finishTask Whether to finish the task associated with this Activity.
4968 * @return Returns true if the activity successfully finished, or false if it is still running.
4971 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4973 // Refuse possible leaked file descriptors
4974 if (resultData != null && resultData.hasFileDescriptors() == true) {
4975 throw new IllegalArgumentException("File descriptors passed in Intent");
4978 synchronized(this) {
4979 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4983 // Keep track of the root activity of the task before we finish it
4984 TaskRecord tr = r.getTask();
4985 ActivityRecord rootR = tr.getRootActivity();
4986 if (rootR == null) {
4987 Slog.w(TAG, "Finishing task with all activities already finished");
4989 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4991 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4992 mStackSupervisor.isLastLockedTask(tr)) {
4993 Slog.i(TAG, "Not finishing task in lock task mode");
4994 mStackSupervisor.showLockTaskToast();
4997 if (mController != null) {
4998 // Find the first activity that is not finishing.
4999 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5001 // ask watcher if this is allowed
5002 boolean resumeOK = true;
5004 resumeOK = mController.activityResuming(next.packageName);
5005 } catch (RemoteException e) {
5007 Watchdog.getInstance().setActivityController(null);
5011 Slog.i(TAG, "Not finishing activity because controller resumed");
5016 final long origId = Binder.clearCallingIdentity();
5019 final boolean finishWithRootActivity =
5020 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5021 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5022 || (finishWithRootActivity && r == rootR)) {
5023 // If requested, remove the task that is associated to this activity only if it
5024 // was the root activity in the task. The result code and data is ignored
5025 // because we don't support returning them across task boundaries. Also, to
5026 // keep backwards compatibility we remove the task from recents when finishing
5027 // task with root activity.
5028 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5030 Slog.i(TAG, "Removing task failed to finish activity");
5033 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5034 resultData, "app-request", true);
5036 Slog.i(TAG, "Failed to finish by app-request");
5041 Binder.restoreCallingIdentity(origId);
5047 public final void finishHeavyWeightApp() {
5048 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5049 != PackageManager.PERMISSION_GRANTED) {
5050 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5051 + Binder.getCallingPid()
5052 + ", uid=" + Binder.getCallingUid()
5053 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5055 throw new SecurityException(msg);
5058 synchronized(this) {
5059 if (mHeavyWeightProcess == null) {
5063 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5064 for (int i = 0; i < activities.size(); i++) {
5065 ActivityRecord r = activities.get(i);
5066 if (!r.finishing && r.isInStackLocked()) {
5067 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5068 null, "finish-heavy", true);
5072 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5073 mHeavyWeightProcess.userId, 0));
5074 mHeavyWeightProcess = null;
5079 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5081 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5082 != PackageManager.PERMISSION_GRANTED) {
5083 String msg = "Permission Denial: crashApplication() from pid="
5084 + Binder.getCallingPid()
5085 + ", uid=" + Binder.getCallingUid()
5086 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5088 throw new SecurityException(msg);
5091 synchronized(this) {
5092 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5097 public final void finishSubActivity(IBinder token, String resultWho,
5099 synchronized(this) {
5100 final long origId = Binder.clearCallingIdentity();
5101 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5103 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5105 Binder.restoreCallingIdentity(origId);
5110 public boolean finishActivityAffinity(IBinder token) {
5111 synchronized(this) {
5112 final long origId = Binder.clearCallingIdentity();
5114 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5119 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5121 final TaskRecord task = r.getTask();
5122 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5123 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5124 mStackSupervisor.showLockTaskToast();
5127 return task.getStack().finishActivityAffinityLocked(r);
5129 Binder.restoreCallingIdentity(origId);
5135 public void finishVoiceTask(IVoiceInteractionSession session) {
5136 synchronized (this) {
5137 final long origId = Binder.clearCallingIdentity();
5139 // TODO: VI Consider treating local voice interactions and voice tasks
5141 mStackSupervisor.finishVoiceTask(session);
5143 Binder.restoreCallingIdentity(origId);
5150 public boolean releaseActivityInstance(IBinder token) {
5151 synchronized(this) {
5152 final long origId = Binder.clearCallingIdentity();
5154 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5158 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5160 Binder.restoreCallingIdentity(origId);
5166 public void releaseSomeActivities(IApplicationThread appInt) {
5167 synchronized(this) {
5168 final long origId = Binder.clearCallingIdentity();
5170 ProcessRecord app = getRecordForAppLocked(appInt);
5171 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5173 Binder.restoreCallingIdentity(origId);
5179 public boolean willActivityBeVisible(IBinder token) {
5180 synchronized(this) {
5181 ActivityStack stack = ActivityRecord.getStackLocked(token);
5182 if (stack != null) {
5183 return stack.willActivityBeVisibleLocked(token);
5190 public void overridePendingTransition(IBinder token, String packageName,
5191 int enterAnim, int exitAnim) {
5192 synchronized(this) {
5193 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5198 final long origId = Binder.clearCallingIdentity();
5200 if (self.state == ActivityState.RESUMED
5201 || self.state == ActivityState.PAUSING) {
5202 mWindowManager.overridePendingAppTransition(packageName,
5203 enterAnim, exitAnim, null);
5206 Binder.restoreCallingIdentity(origId);
5211 * Main function for removing an existing process from the activity manager
5212 * as a result of that process going away. Clears out all connections
5215 private final void handleAppDiedLocked(ProcessRecord app,
5216 boolean restarting, boolean allowRestart) {
5218 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5219 false /*replacingPid*/);
5220 if (!kept && !restarting) {
5221 removeLruProcessLocked(app);
5223 ProcessList.remove(pid);
5227 if (mProfileProc == app) {
5228 clearProfilerLocked();
5231 // Remove this application's activities from active lists.
5232 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5234 app.activities.clear();
5236 if (app.instr != null) {
5237 Slog.w(TAG, "Crash of app " + app.processName
5238 + " running instrumentation " + app.instr.mClass);
5239 Bundle info = new Bundle();
5240 info.putString("shortMsg", "Process crashed.");
5241 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5244 mWindowManager.deferSurfaceLayout();
5246 if (!restarting && hasVisibleActivities
5247 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5248 // If there was nothing to resume, and we are not already restarting this process, but
5249 // there is a visible activity that is hosted by the process... then make sure all
5250 // visible activities are running, taking care of restarting this process.
5251 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5254 mWindowManager.continueSurfaceLayout();
5258 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5259 final IBinder threadBinder = thread.asBinder();
5260 // Find the application record.
5261 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5262 final ProcessRecord rec = mLruProcesses.get(i);
5263 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5270 final ProcessRecord getRecordForAppLocked(
5271 IApplicationThread thread) {
5272 if (thread == null) {
5276 int appIndex = getLRURecordIndexForAppLocked(thread);
5277 if (appIndex >= 0) {
5278 return mLruProcesses.get(appIndex);
5281 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5282 // double-check that.
5283 final IBinder threadBinder = thread.asBinder();
5284 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5285 for (int i = pmap.size()-1; i >= 0; i--) {
5286 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5287 for (int j = procs.size()-1; j >= 0; j--) {
5288 final ProcessRecord proc = procs.valueAt(j);
5289 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5290 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5300 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5301 // If there are no longer any background processes running,
5302 // and the app that died was not running instrumentation,
5303 // then tell everyone we are now low on memory.
5304 boolean haveBg = false;
5305 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5306 ProcessRecord rec = mLruProcesses.get(i);
5307 if (rec.thread != null
5308 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5315 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5317 long now = SystemClock.uptimeMillis();
5318 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5321 mLastMemUsageReportTime = now;
5324 final ArrayList<ProcessMemInfo> memInfos
5325 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5326 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5327 long now = SystemClock.uptimeMillis();
5328 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5329 ProcessRecord rec = mLruProcesses.get(i);
5330 if (rec == dyingProc || rec.thread == null) {
5334 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5335 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5337 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5338 // The low memory report is overriding any current
5339 // state for a GC request. Make sure to do
5340 // heavy/important/visible/foreground processes first.
5341 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5342 rec.lastRequestedGc = 0;
5344 rec.lastRequestedGc = rec.lastLowMemory;
5346 rec.reportLowMemory = true;
5347 rec.lastLowMemory = now;
5348 mProcessesToGc.remove(rec);
5349 addProcessToGcListLocked(rec);
5353 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5354 mHandler.sendMessage(msg);
5356 scheduleAppGcsLocked();
5360 final void appDiedLocked(ProcessRecord app) {
5361 appDiedLocked(app, app.pid, app.thread, false);
5364 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5365 boolean fromBinderDied) {
5366 // First check if this ProcessRecord is actually active for the pid.
5367 synchronized (mPidsSelfLocked) {
5368 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5369 if (curProc != app) {
5370 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5375 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5376 synchronized (stats) {
5377 stats.noteProcessDiedLocked(app.info.uid, pid);
5381 if (!fromBinderDied) {
5382 killProcessQuiet(pid);
5384 killProcessGroup(app.uid, pid);
5388 // Clean up already done if the process has been re-started.
5389 if (app.pid == pid && app.thread != null &&
5390 app.thread.asBinder() == thread.asBinder()) {
5391 boolean doLowMem = app.instr == null;
5392 boolean doOomAdj = doLowMem;
5393 if (!app.killedByAm) {
5394 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5395 + ProcessList.makeOomAdjString(app.setAdj)
5396 + ProcessList.makeProcStateString(app.setProcState));
5397 mAllowLowerMemLevel = true;
5399 // Note that we always want to do oom adj to update our state with the
5400 // new number of procs.
5401 mAllowLowerMemLevel = false;
5404 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5405 app.setAdj, app.setProcState);
5406 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5407 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5408 handleAppDiedLocked(app, false, true);
5411 updateOomAdjLocked();
5414 doLowMemReportIfNeededLocked(app);
5416 } else if (app.pid != pid) {
5417 // A new process has already been started.
5418 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5419 + ") has died and restarted (pid " + app.pid + ").");
5420 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5421 } else if (DEBUG_PROCESSES) {
5422 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5423 + thread.asBinder());
5428 * If a stack trace dump file is configured, dump process stack traces.
5429 * @param clearTraces causes the dump file to be erased prior to the new
5430 * traces being written, if true; when false, the new traces will be
5431 * appended to any existing file content.
5432 * @param firstPids of dalvik VM processes to dump stack traces for first
5433 * @param lastPids of dalvik VM processes to dump stack traces for last
5434 * @param nativePids optional list of native pids to dump stack crawls
5436 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5437 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5438 ArrayList<Integer> nativePids) {
5439 ArrayList<Integer> extraPids = null;
5441 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5442 // of the top users at the time of the request.
5443 if (processCpuTracker != null) {
5444 processCpuTracker.init();
5447 } catch (InterruptedException ignored) {
5450 processCpuTracker.update();
5452 // We'll take the stack crawls of just the top apps using CPU.
5453 final int N = processCpuTracker.countWorkingStats();
5454 extraPids = new ArrayList<>();
5455 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5456 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5457 if (lastPids.indexOfKey(stats.pid) >= 0) {
5458 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5460 extraPids.add(stats.pid);
5461 } else if (DEBUG_ANR) {
5462 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5468 boolean useTombstonedForJavaTraces = false;
5471 final String tracesDir = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5472 if (tracesDir.isEmpty()) {
5473 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5474 // dumping scheme. All traces are written to a global trace file (usually
5475 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5476 // the file if requested.
5478 // This mode of operation will be removed in the near future.
5481 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5482 if (globalTracesPath.isEmpty()) {
5483 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5487 tracesFile = new File(globalTracesPath);
5489 if (clearTraces && tracesFile.exists()) {
5490 tracesFile.delete();
5493 tracesFile.createNewFile();
5494 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5495 } catch (IOException e) {
5496 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5500 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5501 // Each set of ANR traces is written to a separate file and dumpstate will process
5502 // all such files and add them to a captured bug report if they're recent enough.
5504 // NOTE: We should consider creating the file in native code atomically once we've
5505 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5508 tracesFile = File.createTempFile("anr_", "", new File(tracesDir));
5509 FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5510 } catch (IOException ioe) {
5511 Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
5515 useTombstonedForJavaTraces = true;
5518 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5519 useTombstonedForJavaTraces);
5524 * Legacy code, do not use. Existing users will be deleted.
5529 public static class DumpStackFileObserver extends FileObserver {
5530 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5531 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5533 private final String mTracesPath;
5534 private boolean mClosed;
5536 public DumpStackFileObserver(String tracesPath) {
5537 super(tracesPath, FileObserver.CLOSE_WRITE);
5538 mTracesPath = tracesPath;
5542 public synchronized void onEvent(int event, String path) {
5547 public long dumpWithTimeout(int pid, long timeout) {
5548 sendSignal(pid, SIGNAL_QUIT);
5549 final long start = SystemClock.elapsedRealtime();
5551 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5552 synchronized (this) {
5554 wait(waitTime); // Wait for traces file to be closed.
5555 } catch (InterruptedException e) {
5560 // This avoids a corner case of passing a negative time to the native
5561 // trace in case we've already hit the overall timeout.
5562 final long timeWaited = SystemClock.elapsedRealtime() - start;
5563 if (timeWaited >= timeout) {
5568 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5569 ". Attempting native stack collection.");
5571 final long nativeDumpTimeoutMs = Math.min(
5572 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5574 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5575 (int) (nativeDumpTimeoutMs / 1000));
5578 final long end = SystemClock.elapsedRealtime();
5581 return (end - start);
5586 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5587 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5588 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5589 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5592 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5593 final long timeStart = SystemClock.elapsedRealtime();
5594 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5595 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5596 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5599 return SystemClock.elapsedRealtime() - timeStart;
5602 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5603 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5604 boolean useTombstonedForJavaTraces) {
5606 // We don't need any sort of inotify based monitoring when we're dumping traces via
5607 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5608 // control of all writes to the file in question.
5609 final DumpStackFileObserver observer;
5610 if (useTombstonedForJavaTraces) {
5613 // Use a FileObserver to detect when traces finish writing.
5614 // The order of traces is considered important to maintain for legibility.
5615 observer = new DumpStackFileObserver(tracesFile);
5618 // We must complete all stack dumps within 20 seconds.
5619 long remainingTime = 20 * 1000;
5621 if (observer != null) {
5622 observer.startWatching();
5625 // First collect all of the stacks of the most important pids.
5626 if (firstPids != null) {
5627 int num = firstPids.size();
5628 for (int i = 0; i < num; i++) {
5629 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5630 + firstPids.get(i));
5631 final long timeTaken;
5632 if (useTombstonedForJavaTraces) {
5633 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5635 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5638 remainingTime -= timeTaken;
5639 if (remainingTime <= 0) {
5640 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5641 "); deadline exceeded.");
5646 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5651 // Next collect the stacks of the native pids
5652 if (nativePids != null) {
5653 for (int pid : nativePids) {
5654 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5655 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5657 final long start = SystemClock.elapsedRealtime();
5658 Debug.dumpNativeBacktraceToFileTimeout(
5659 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5660 final long timeTaken = SystemClock.elapsedRealtime() - start;
5662 remainingTime -= timeTaken;
5663 if (remainingTime <= 0) {
5664 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5665 "); deadline exceeded.");
5670 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5675 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5676 if (extraPids != null) {
5677 for (int pid : extraPids) {
5678 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5680 final long timeTaken;
5681 if (useTombstonedForJavaTraces) {
5682 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5684 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5687 remainingTime -= timeTaken;
5688 if (remainingTime <= 0) {
5689 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5690 "); deadline exceeded.");
5695 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5700 if (observer != null) {
5701 observer.stopWatching();
5706 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5707 if (true || IS_USER_BUILD) {
5710 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5711 if (tracesPath == null || tracesPath.length() == 0) {
5715 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5716 StrictMode.allowThreadDiskWrites();
5718 final File tracesFile = new File(tracesPath);
5719 final File tracesDir = tracesFile.getParentFile();
5720 final File tracesTmp = new File(tracesDir, "__tmp__");
5722 if (tracesFile.exists()) {
5724 tracesFile.renameTo(tracesTmp);
5726 StringBuilder sb = new StringBuilder();
5727 Time tobj = new Time();
5728 tobj.set(System.currentTimeMillis());
5729 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5731 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5732 sb.append(" since ");
5734 FileOutputStream fos = new FileOutputStream(tracesFile);
5735 fos.write(sb.toString().getBytes());
5737 fos.write("\n*** No application process!".getBytes());
5740 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5741 } catch (IOException e) {
5742 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5747 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5748 firstPids.add(app.pid);
5749 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5752 File lastTracesFile = null;
5753 File curTracesFile = null;
5754 for (int i=9; i>=0; i--) {
5755 String name = String.format(Locale.US, "slow%02d.txt", i);
5756 curTracesFile = new File(tracesDir, name);
5757 if (curTracesFile.exists()) {
5758 if (lastTracesFile != null) {
5759 curTracesFile.renameTo(lastTracesFile);
5761 curTracesFile.delete();
5764 lastTracesFile = curTracesFile;
5766 tracesFile.renameTo(curTracesFile);
5767 if (tracesTmp.exists()) {
5768 tracesTmp.renameTo(tracesFile);
5771 StrictMode.setThreadPolicy(oldPolicy);
5775 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5776 if (!mLaunchWarningShown) {
5777 mLaunchWarningShown = true;
5778 mUiHandler.post(new Runnable() {
5781 synchronized (ActivityManagerService.this) {
5782 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5784 mUiHandler.postDelayed(new Runnable() {
5787 synchronized (ActivityManagerService.this) {
5789 mLaunchWarningShown = false;
5800 public boolean clearApplicationUserData(final String packageName,
5801 final IPackageDataObserver observer, int userId) {
5802 enforceNotIsolatedCaller("clearApplicationUserData");
5803 int uid = Binder.getCallingUid();
5804 int pid = Binder.getCallingPid();
5805 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5806 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5809 long callingId = Binder.clearCallingIdentity();
5811 IPackageManager pm = AppGlobals.getPackageManager();
5813 synchronized(this) {
5814 if (getPackageManagerInternalLocked().isPackageDataProtected(
5815 userId, packageName)) {
5816 throw new SecurityException(
5817 "Cannot clear data for a protected package: " + packageName);
5821 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5822 } catch (RemoteException e) {
5825 Slog.w(TAG, "Invalid packageName: " + packageName);
5826 if (observer != null) {
5828 observer.onRemoveCompleted(packageName, false);
5829 } catch (RemoteException e) {
5830 Slog.i(TAG, "Observer no longer exists.");
5835 if (uid == pkgUid || checkComponentPermission(
5836 android.Manifest.permission.CLEAR_APP_USER_DATA,
5838 == PackageManager.PERMISSION_GRANTED) {
5839 forceStopPackageLocked(packageName, pkgUid, "clear data");
5841 throw new SecurityException("PID " + pid + " does not have permission "
5842 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5843 + " of package " + packageName);
5846 // Remove all tasks match the cleared application package and user
5847 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5848 final TaskRecord tr = mRecentTasks.get(i);
5849 final String taskPackageName =
5850 tr.getBaseIntent().getComponent().getPackageName();
5851 if (tr.userId != userId) continue;
5852 if (!taskPackageName.equals(packageName)) continue;
5853 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5857 final int pkgUidF = pkgUid;
5858 final int userIdF = userId;
5859 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5861 public void onRemoveCompleted(String packageName, boolean succeeded)
5862 throws RemoteException {
5863 synchronized (ActivityManagerService.this) {
5864 finishForceStopPackageLocked(packageName, pkgUidF);
5867 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5868 Uri.fromParts("package", packageName, null));
5869 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5870 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5871 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5872 broadcastIntentInPackage("android", SYSTEM_UID, intent,
5873 null, null, 0, null, null, null, null, false, false, userIdF);
5875 if (observer != null) {
5876 observer.onRemoveCompleted(packageName, succeeded);
5882 // Clear application user data
5883 pm.clearApplicationUserData(packageName, localObserver, userId);
5885 synchronized(this) {
5886 // Remove all permissions granted from/to this package
5887 removeUriPermissionsForPackageLocked(packageName, userId, true);
5890 // Reset notification settings.
5891 INotificationManager inm = NotificationManager.getService();
5892 inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5893 } catch (RemoteException e) {
5896 Binder.restoreCallingIdentity(callingId);
5902 public void killBackgroundProcesses(final String packageName, int userId) {
5903 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5904 != PackageManager.PERMISSION_GRANTED &&
5905 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5906 != PackageManager.PERMISSION_GRANTED) {
5907 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5908 + Binder.getCallingPid()
5909 + ", uid=" + Binder.getCallingUid()
5910 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5912 throw new SecurityException(msg);
5915 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5916 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5917 long callingId = Binder.clearCallingIdentity();
5919 IPackageManager pm = AppGlobals.getPackageManager();
5920 synchronized(this) {
5923 appId = UserHandle.getAppId(
5924 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5925 } catch (RemoteException e) {
5928 Slog.w(TAG, "Invalid packageName: " + packageName);
5931 killPackageProcessesLocked(packageName, appId, userId,
5932 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5935 Binder.restoreCallingIdentity(callingId);
5940 public void killAllBackgroundProcesses() {
5941 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5942 != PackageManager.PERMISSION_GRANTED) {
5943 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5944 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5945 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5947 throw new SecurityException(msg);
5950 final long callingId = Binder.clearCallingIdentity();
5952 synchronized (this) {
5953 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5954 final int NP = mProcessNames.getMap().size();
5955 for (int ip = 0; ip < NP; ip++) {
5956 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5957 final int NA = apps.size();
5958 for (int ia = 0; ia < NA; ia++) {
5959 final ProcessRecord app = apps.valueAt(ia);
5960 if (app.persistent) {
5961 // We don't kill persistent processes.
5966 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5973 final int N = procs.size();
5974 for (int i = 0; i < N; i++) {
5975 removeProcessLocked(procs.get(i), false, true, "kill all background");
5978 mAllowLowerMemLevel = true;
5980 updateOomAdjLocked();
5981 doLowMemReportIfNeededLocked(null);
5984 Binder.restoreCallingIdentity(callingId);
5989 * Kills all background processes, except those matching any of the
5990 * specified properties.
5992 * @param minTargetSdk the target SDK version at or above which to preserve
5993 * processes, or {@code -1} to ignore the target SDK
5994 * @param maxProcState the process state at or below which to preserve
5995 * processes, or {@code -1} to ignore the process state
5997 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5998 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5999 != PackageManager.PERMISSION_GRANTED) {
6000 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6001 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6002 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6004 throw new SecurityException(msg);
6007 final long callingId = Binder.clearCallingIdentity();
6009 synchronized (this) {
6010 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6011 final int NP = mProcessNames.getMap().size();
6012 for (int ip = 0; ip < NP; ip++) {
6013 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6014 final int NA = apps.size();
6015 for (int ia = 0; ia < NA; ia++) {
6016 final ProcessRecord app = apps.valueAt(ia);
6019 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6020 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6027 final int N = procs.size();
6028 for (int i = 0; i < N; i++) {
6029 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6033 Binder.restoreCallingIdentity(callingId);
6038 public void forceStopPackage(final String packageName, int userId) {
6039 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6040 != PackageManager.PERMISSION_GRANTED) {
6041 String msg = "Permission Denial: forceStopPackage() from pid="
6042 + Binder.getCallingPid()
6043 + ", uid=" + Binder.getCallingUid()
6044 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6046 throw new SecurityException(msg);
6048 final int callingPid = Binder.getCallingPid();
6049 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6050 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6051 long callingId = Binder.clearCallingIdentity();
6053 IPackageManager pm = AppGlobals.getPackageManager();
6054 synchronized(this) {
6055 int[] users = userId == UserHandle.USER_ALL
6056 ? mUserController.getUsers() : new int[] { userId };
6057 for (int user : users) {
6060 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6062 } catch (RemoteException e) {
6065 Slog.w(TAG, "Invalid packageName: " + packageName);
6069 pm.setPackageStoppedState(packageName, true, user);
6070 } catch (RemoteException e) {
6071 } catch (IllegalArgumentException e) {
6072 Slog.w(TAG, "Failed trying to unstop package "
6073 + packageName + ": " + e);
6075 if (mUserController.isUserRunningLocked(user, 0)) {
6076 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6077 finishForceStopPackageLocked(packageName, pkgUid);
6082 Binder.restoreCallingIdentity(callingId);
6087 public void addPackageDependency(String packageName) {
6088 synchronized (this) {
6089 int callingPid = Binder.getCallingPid();
6090 if (callingPid == myPid()) {
6095 synchronized (mPidsSelfLocked) {
6096 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6099 if (proc.pkgDeps == null) {
6100 proc.pkgDeps = new ArraySet<String>(1);
6102 proc.pkgDeps.add(packageName);
6108 * The pkg name and app id have to be specified.
6111 public void killApplication(String pkg, int appId, int userId, String reason) {
6115 // Make sure the uid is valid.
6117 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6120 int callerUid = Binder.getCallingUid();
6121 // Only the system server can kill an application
6122 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6123 // Post an aysnc message to kill the application
6124 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6127 Bundle bundle = new Bundle();
6128 bundle.putString("pkg", pkg);
6129 bundle.putString("reason", reason);
6131 mHandler.sendMessage(msg);
6133 throw new SecurityException(callerUid + " cannot kill pkg: " +
6139 public void closeSystemDialogs(String reason) {
6140 enforceNotIsolatedCaller("closeSystemDialogs");
6142 final int pid = Binder.getCallingPid();
6143 final int uid = Binder.getCallingUid();
6144 final long origId = Binder.clearCallingIdentity();
6146 synchronized (this) {
6147 // Only allow this from foreground processes, so that background
6148 // applications can't abuse it to prevent system UI from being shown.
6149 if (uid >= FIRST_APPLICATION_UID) {
6151 synchronized (mPidsSelfLocked) {
6152 proc = mPidsSelfLocked.get(pid);
6154 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6155 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6156 + " from background process " + proc);
6160 closeSystemDialogsLocked(reason);
6163 Binder.restoreCallingIdentity(origId);
6167 void closeSystemDialogsLocked(String reason) {
6168 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6169 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6170 | Intent.FLAG_RECEIVER_FOREGROUND);
6171 if (reason != null) {
6172 intent.putExtra("reason", reason);
6174 mWindowManager.closeSystemDialogs(reason);
6176 mStackSupervisor.closeSystemDialogsLocked();
6178 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6179 AppOpsManager.OP_NONE, null, false, false,
6180 -1, SYSTEM_UID, UserHandle.USER_ALL);
6184 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6185 enforceNotIsolatedCaller("getProcessMemoryInfo");
6186 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6187 for (int i=pids.length-1; i>=0; i--) {
6190 synchronized (this) {
6191 synchronized (mPidsSelfLocked) {
6192 proc = mPidsSelfLocked.get(pids[i]);
6193 oomAdj = proc != null ? proc.setAdj : 0;
6196 infos[i] = new Debug.MemoryInfo();
6197 Debug.getMemoryInfo(pids[i], infos[i]);
6199 synchronized (this) {
6200 if (proc.thread != null && proc.setAdj == oomAdj) {
6201 // Record this for posterity if the process has been stable.
6202 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6203 infos[i].getTotalUss(), false, proc.pkgList);
6212 public long[] getProcessPss(int[] pids) {
6213 enforceNotIsolatedCaller("getProcessPss");
6214 long[] pss = new long[pids.length];
6215 for (int i=pids.length-1; i>=0; i--) {
6218 synchronized (this) {
6219 synchronized (mPidsSelfLocked) {
6220 proc = mPidsSelfLocked.get(pids[i]);
6221 oomAdj = proc != null ? proc.setAdj : 0;
6224 long[] tmpUss = new long[1];
6225 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6227 synchronized (this) {
6228 if (proc.thread != null && proc.setAdj == oomAdj) {
6229 // Record this for posterity if the process has been stable.
6230 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6239 public void killApplicationProcess(String processName, int uid) {
6240 if (processName == null) {
6244 int callerUid = Binder.getCallingUid();
6245 // Only the system server can kill an application
6246 if (callerUid == SYSTEM_UID) {
6247 synchronized (this) {
6248 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6249 if (app != null && app.thread != null) {
6251 app.thread.scheduleSuicide();
6252 } catch (RemoteException e) {
6253 // If the other end already died, then our work here is done.
6256 Slog.w(TAG, "Process/uid not found attempting kill of "
6257 + processName + " / " + uid);
6261 throw new SecurityException(callerUid + " cannot kill app process: " +
6266 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6267 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6268 false, true, false, false, UserHandle.getUserId(uid), reason);
6271 private void finishForceStopPackageLocked(final String packageName, int uid) {
6272 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6273 Uri.fromParts("package", packageName, null));
6274 if (!mProcessesReady) {
6275 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6276 | Intent.FLAG_RECEIVER_FOREGROUND);
6278 intent.putExtra(Intent.EXTRA_UID, uid);
6279 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6280 broadcastIntentLocked(null, null, intent,
6281 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6282 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6286 private final boolean killPackageProcessesLocked(String packageName, int appId,
6287 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6288 boolean doit, boolean evenPersistent, String reason) {
6289 ArrayList<ProcessRecord> procs = new ArrayList<>();
6291 // Remove all processes this package may have touched: all with the
6292 // same UID (except for the system or root user), and all whose name
6293 // matches the package name.
6294 final int NP = mProcessNames.getMap().size();
6295 for (int ip=0; ip<NP; ip++) {
6296 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6297 final int NA = apps.size();
6298 for (int ia=0; ia<NA; ia++) {
6299 ProcessRecord app = apps.valueAt(ia);
6300 if (app.persistent && !evenPersistent) {
6301 // we don't kill persistent processes
6311 // Skip process if it doesn't meet our oom adj requirement.
6312 if (app.setAdj < minOomAdj) {
6316 // If no package is specified, we call all processes under the
6318 if (packageName == null) {
6319 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6322 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6325 // Package has been specified, we want to hit all processes
6326 // that match it. We need to qualify this by the processes
6327 // that are running under the specified app and user ID.
6329 final boolean isDep = app.pkgDeps != null
6330 && app.pkgDeps.contains(packageName);
6331 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6334 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6337 if (!app.pkgList.containsKey(packageName) && !isDep) {
6342 // Process has passed all conditions, kill it!
6351 int N = procs.size();
6352 for (int i=0; i<N; i++) {
6353 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6355 updateOomAdjLocked();
6359 private void cleanupDisabledPackageComponentsLocked(
6360 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6362 Set<String> disabledClasses = null;
6363 boolean packageDisabled = false;
6364 IPackageManager pm = AppGlobals.getPackageManager();
6366 if (changedClasses == null) {
6367 // Nothing changed...
6371 // Determine enable/disable state of the package and its components.
6372 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6373 for (int i = changedClasses.length - 1; i >= 0; i--) {
6374 final String changedClass = changedClasses[i];
6376 if (changedClass.equals(packageName)) {
6378 // Entire package setting changed
6379 enabled = pm.getApplicationEnabledSetting(packageName,
6380 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6381 } catch (Exception e) {
6382 // No such package/component; probably racing with uninstall. In any
6383 // event it means we have nothing further to do here.
6386 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6387 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6388 if (packageDisabled) {
6389 // Entire package is disabled.
6390 // No need to continue to check component states.
6391 disabledClasses = null;
6396 enabled = pm.getComponentEnabledSetting(
6397 new ComponentName(packageName, changedClass),
6398 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6399 } catch (Exception e) {
6400 // As above, probably racing with uninstall.
6403 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6404 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6405 if (disabledClasses == null) {
6406 disabledClasses = new ArraySet<>(changedClasses.length);
6408 disabledClasses.add(changedClass);
6413 if (!packageDisabled && disabledClasses == null) {
6414 // Nothing to do here...
6418 // Clean-up disabled activities.
6419 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6420 packageName, disabledClasses, true, false, userId) && mBooted) {
6421 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6422 mStackSupervisor.scheduleIdleLocked();
6425 // Clean-up disabled tasks
6426 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6428 // Clean-up disabled services.
6429 mServices.bringDownDisabledPackageServicesLocked(
6430 packageName, disabledClasses, userId, false, killProcess, true);
6432 // Clean-up disabled providers.
6433 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6434 mProviderMap.collectPackageProvidersLocked(
6435 packageName, disabledClasses, true, false, userId, providers);
6436 for (int i = providers.size() - 1; i >= 0; i--) {
6437 removeDyingProviderLocked(null, providers.get(i), true);
6440 // Clean-up disabled broadcast receivers.
6441 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6442 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6443 packageName, disabledClasses, userId, true);
6448 final boolean clearBroadcastQueueForUserLocked(int userId) {
6449 boolean didSomething = false;
6450 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6451 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6452 null, null, userId, true);
6454 return didSomething;
6457 final boolean forceStopPackageLocked(String packageName, int appId,
6458 boolean callerWillRestart, boolean purgeCache, boolean doit,
6459 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6462 if (userId == UserHandle.USER_ALL && packageName == null) {
6463 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6466 if (appId < 0 && packageName != null) {
6468 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6469 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6470 } catch (RemoteException e) {
6475 if (packageName != null) {
6476 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6477 + " user=" + userId + ": " + reason);
6479 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6482 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6485 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6486 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6487 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6489 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6491 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6492 packageName, null, doit, evenPersistent, userId)) {
6496 didSomething = true;
6499 if (mServices.bringDownDisabledPackageServicesLocked(
6500 packageName, null, userId, evenPersistent, true, doit)) {
6504 didSomething = true;
6507 if (packageName == null) {
6508 // Remove all sticky broadcasts from this user.
6509 mStickyBroadcasts.remove(userId);
6512 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6513 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6514 userId, providers)) {
6518 didSomething = true;
6520 for (i = providers.size() - 1; i >= 0; i--) {
6521 removeDyingProviderLocked(null, providers.get(i), true);
6524 // Remove transient permissions granted from/to this package/user
6525 removeUriPermissionsForPackageLocked(packageName, userId, false);
6528 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6529 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6530 packageName, null, userId, doit);
6534 if (packageName == null || uninstalling) {
6535 // Remove pending intents. For now we only do this when force
6536 // stopping users, because we have some problems when doing this
6537 // for packages -- app widgets are not currently cleaned up for
6538 // such packages, so they can be left with bad pending intents.
6539 if (mIntentSenderRecords.size() > 0) {
6540 Iterator<WeakReference<PendingIntentRecord>> it
6541 = mIntentSenderRecords.values().iterator();
6542 while (it.hasNext()) {
6543 WeakReference<PendingIntentRecord> wpir = it.next();
6548 PendingIntentRecord pir = wpir.get();
6553 if (packageName == null) {
6554 // Stopping user, remove all objects for the user.
6555 if (pir.key.userId != userId) {
6556 // Not the same user, skip it.
6560 if (UserHandle.getAppId(pir.uid) != appId) {
6561 // Different app id, skip it.
6564 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6565 // Different user, skip it.
6568 if (!pir.key.packageName.equals(packageName)) {
6569 // Different package, skip it.
6576 didSomething = true;
6578 makeIntentSenderCanceledLocked(pir);
6579 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6580 pir.key.activity.pendingResults.remove(pir.ref);
6587 if (purgeCache && packageName != null) {
6588 AttributeCache ac = AttributeCache.instance();
6590 ac.removePackage(packageName);
6594 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6595 mStackSupervisor.scheduleIdleLocked();
6599 return didSomething;
6602 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6603 return removeProcessNameLocked(name, uid, null);
6606 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6607 final ProcessRecord expecting) {
6608 ProcessRecord old = mProcessNames.get(name, uid);
6609 // Only actually remove when the currently recorded value matches the
6610 // record that we expected; if it doesn't match then we raced with a
6611 // newly created process and we don't want to destroy the new one.
6612 if ((expecting == null) || (old == expecting)) {
6613 mProcessNames.remove(name, uid);
6615 if (old != null && old.uidRecord != null) {
6616 old.uidRecord.numProcs--;
6617 if (old.uidRecord.numProcs == 0) {
6618 // No more processes using this uid, tell clients it is gone.
6619 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6620 "No more processes in " + old.uidRecord);
6621 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6622 EventLogTags.writeAmUidStopped(uid);
6623 mActiveUids.remove(uid);
6624 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6626 old.uidRecord = null;
6628 mIsolatedProcesses.remove(uid);
6632 private final void addProcessNameLocked(ProcessRecord proc) {
6633 // We shouldn't already have a process under this name, but just in case we
6634 // need to clean up whatever may be there now.
6635 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6636 if (old == proc && proc.persistent) {
6637 // We are re-adding a persistent process. Whatevs! Just leave it there.
6638 Slog.w(TAG, "Re-adding persistent process " + proc);
6639 } else if (old != null) {
6640 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6642 UidRecord uidRec = mActiveUids.get(proc.uid);
6643 if (uidRec == null) {
6644 uidRec = new UidRecord(proc.uid);
6645 // This is the first appearance of the uid, report it now!
6646 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6647 "Creating new process uid: " + uidRec);
6648 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6649 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6650 uidRec.setWhitelist = uidRec.curWhitelist = true;
6652 uidRec.updateHasInternetPermission();
6653 mActiveUids.put(proc.uid, uidRec);
6654 EventLogTags.writeAmUidRunning(uidRec.uid);
6655 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6656 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6658 proc.uidRecord = uidRec;
6660 // Reset render thread tid if it was already set, so new process can set it again.
6661 proc.renderThreadTid = 0;
6663 mProcessNames.put(proc.processName, proc.uid, proc);
6664 if (proc.isolated) {
6665 mIsolatedProcesses.put(proc.uid, proc);
6669 boolean removeProcessLocked(ProcessRecord app,
6670 boolean callerWillRestart, boolean allowRestart, String reason) {
6671 final String name = app.processName;
6672 final int uid = app.uid;
6673 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6674 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6676 ProcessRecord old = mProcessNames.get(name, uid);
6678 // This process is no longer active, so nothing to do.
6679 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6682 removeProcessNameLocked(name, uid);
6683 if (mHeavyWeightProcess == app) {
6684 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6685 mHeavyWeightProcess.userId, 0));
6686 mHeavyWeightProcess = null;
6688 boolean needRestart = false;
6689 if (app.pid > 0 && app.pid != MY_PID) {
6691 synchronized (mPidsSelfLocked) {
6692 mPidsSelfLocked.remove(pid);
6693 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6695 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6697 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6698 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6700 boolean willRestart = false;
6701 if (app.persistent && !app.isolated) {
6702 if (!callerWillRestart) {
6708 app.kill(reason, true);
6709 handleAppDiedLocked(app, willRestart, allowRestart);
6711 removeLruProcessLocked(app);
6712 addAppLocked(app.info, null, false, null /* ABI override */);
6715 mRemovedProcesses.add(app);
6721 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6722 cleanupAppInLaunchingProvidersLocked(app, true);
6723 removeProcessLocked(app, false, true, "timeout publishing content providers");
6726 private final void processStartTimedOutLocked(ProcessRecord app) {
6727 final int pid = app.pid;
6728 boolean gone = false;
6729 synchronized (mPidsSelfLocked) {
6730 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6731 if (knownApp != null && knownApp.thread == null) {
6732 mPidsSelfLocked.remove(pid);
6738 Slog.w(TAG, "Process " + app + " failed to attach");
6739 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6740 pid, app.uid, app.processName);
6741 removeProcessNameLocked(app.processName, app.uid);
6742 if (mHeavyWeightProcess == app) {
6743 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6744 mHeavyWeightProcess.userId, 0));
6745 mHeavyWeightProcess = null;
6747 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6749 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6751 // Take care of any launching providers waiting for this process.
6752 cleanupAppInLaunchingProvidersLocked(app, true);
6753 // Take care of any services that are waiting for the process.
6754 mServices.processStartTimedOutLocked(app);
6755 app.kill("start timeout", true);
6756 removeLruProcessLocked(app);
6757 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6758 Slog.w(TAG, "Unattached app died before backup, skipping");
6759 mHandler.post(new Runnable() {
6763 IBackupManager bm = IBackupManager.Stub.asInterface(
6764 ServiceManager.getService(Context.BACKUP_SERVICE));
6765 bm.agentDisconnected(app.info.packageName);
6766 } catch (RemoteException e) {
6767 // Can't happen; the backup manager is local
6772 if (isPendingBroadcastProcessLocked(pid)) {
6773 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6774 skipPendingBroadcastLocked(pid);
6777 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6781 private final boolean attachApplicationLocked(IApplicationThread thread,
6784 // Find the application record that is being attached... either via
6785 // the pid if we are running in multiple processes, or just pull the
6786 // next app record if we are emulating process with anonymous threads.
6788 long startTime = SystemClock.uptimeMillis();
6789 if (pid != MY_PID && pid >= 0) {
6790 synchronized (mPidsSelfLocked) {
6791 app = mPidsSelfLocked.get(pid);
6798 Slog.w(TAG, "No pending application record for pid " + pid
6799 + " (IApplicationThread " + thread + "); dropping process");
6800 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6801 if (pid > 0 && pid != MY_PID) {
6802 killProcessQuiet(pid);
6803 //TODO: killProcessGroup(app.info.uid, pid);
6806 thread.scheduleExit();
6807 } catch (Exception e) {
6808 // Ignore exceptions.
6814 // If this application record is still attached to a previous
6815 // process, clean it up now.
6816 if (app.thread != null) {
6817 handleAppDiedLocked(app, true, true);
6820 // Tell the process all about itself.
6822 if (DEBUG_ALL) Slog.v(
6823 TAG, "Binding process pid " + pid + " to record " + app);
6825 final String processName = app.processName;
6827 AppDeathRecipient adr = new AppDeathRecipient(
6829 thread.asBinder().linkToDeath(adr, 0);
6830 app.deathRecipient = adr;
6831 } catch (RemoteException e) {
6832 app.resetPackageList(mProcessStats);
6833 startProcessLocked(app, "link fail", processName);
6837 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6839 app.makeActive(thread, mProcessStats);
6840 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6841 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6842 app.forcingToImportant = null;
6843 updateProcessForegroundLocked(app, false, false);
6844 app.hasShownUi = false;
6845 app.debugging = false;
6847 app.killedByAm = false;
6851 // We carefully use the same state that PackageManager uses for
6852 // filtering, since we use this flag to decide if we need to install
6853 // providers when user is unlocked later
6854 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6856 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6858 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6859 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6861 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6862 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6864 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6867 checkTime(startTime, "attachApplicationLocked: before bindApplication");
6870 Slog.i(TAG, "Launching preboot mode app: " + app);
6873 if (DEBUG_ALL) Slog.v(
6874 TAG, "New app record " + app
6875 + " thread=" + thread.asBinder() + " pid=" + pid);
6877 int testMode = ApplicationThreadConstants.DEBUG_OFF;
6878 if (mDebugApp != null && mDebugApp.equals(processName)) {
6879 testMode = mWaitForDebugger
6880 ? ApplicationThreadConstants.DEBUG_WAIT
6881 : ApplicationThreadConstants.DEBUG_ON;
6882 app.debugging = true;
6883 if (mDebugTransient) {
6884 mDebugApp = mOrigDebugApp;
6885 mWaitForDebugger = mOrigWaitForDebugger;
6888 String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6889 ParcelFileDescriptor profileFd = null;
6890 int samplingInterval = 0;
6891 boolean profileAutoStop = false;
6892 boolean profileStreamingOutput = false;
6893 if (mProfileApp != null && mProfileApp.equals(processName)) {
6895 profileFile = mProfileFile;
6896 profileFd = mProfileFd;
6897 samplingInterval = mSamplingInterval;
6898 profileAutoStop = mAutoStopProfiler;
6899 profileStreamingOutput = mStreamingOutput;
6901 boolean enableTrackAllocation = false;
6902 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6903 enableTrackAllocation = true;
6904 mTrackAllocationApp = null;
6907 // If the app is being launched for restore or full backup, set it up specially
6908 boolean isRestrictedBackupMode = false;
6909 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6910 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6911 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6912 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6913 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6916 if (app.instr != null) {
6917 notifyPackageUse(app.instr.mClass.getPackageName(),
6918 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6920 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6921 + processName + " with config " + getGlobalConfiguration());
6922 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6923 app.compat = compatibilityInfoForPackageLocked(appInfo);
6924 if (profileFd != null) {
6925 profileFd = profileFd.dup();
6927 ProfilerInfo profilerInfo = profileFile == null ? null
6928 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6929 profileStreamingOutput);
6931 // We deprecated Build.SERIAL and it is not accessible to
6932 // apps that target the v2 security sandbox. Since access to
6933 // the serial is now behind a permission we push down the value.
6934 String buildSerial = Build.UNKNOWN;
6935 if (appInfo.targetSandboxVersion != 2) {
6936 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6937 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6941 // Check if this is a secondary process that should be incorporated into some
6942 // currently active instrumentation. (Note we do this AFTER all of the profiling
6943 // stuff above because profiling can currently happen only in the primary
6944 // instrumentation process.)
6945 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6946 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6947 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6948 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6949 if (aInstr.mTargetProcesses.length == 0) {
6950 // This is the wildcard mode, where every process brought up for
6951 // the target instrumentation should be included.
6952 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6954 aInstr.mRunningProcesses.add(app);
6957 for (String proc : aInstr.mTargetProcesses) {
6958 if (proc.equals(app.processName)) {
6960 aInstr.mRunningProcesses.add(app);
6969 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6970 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6971 if (app.instr != null) {
6972 thread.bindApplication(processName, appInfo, providers,
6974 profilerInfo, app.instr.mArguments,
6976 app.instr.mUiAutomationConnection, testMode,
6977 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6978 isRestrictedBackupMode || !normalMode, app.persistent,
6979 new Configuration(getGlobalConfiguration()), app.compat,
6980 getCommonServicesLocked(app.isolated),
6981 mCoreSettingsObserver.getCoreSettingsLocked(),
6984 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6985 null, null, null, testMode,
6986 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6987 isRestrictedBackupMode || !normalMode, app.persistent,
6988 new Configuration(getGlobalConfiguration()), app.compat,
6989 getCommonServicesLocked(app.isolated),
6990 mCoreSettingsObserver.getCoreSettingsLocked(),
6994 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6995 updateLruProcessLocked(app, false, null);
6996 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6997 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6998 } catch (Exception e) {
6999 // todo: Yikes! What should we do? For now we will try to
7000 // start another process, but that could easily get us in
7001 // an infinite loop of restarting processes...
7002 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7004 app.resetPackageList(mProcessStats);
7005 app.unlinkDeathRecipient();
7006 startProcessLocked(app, "bind fail", processName);
7010 // Remove this record from the list of starting applications.
7011 mPersistentStartingProcesses.remove(app);
7012 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7013 "Attach application locked removing on hold: " + app);
7014 mProcessesOnHold.remove(app);
7016 boolean badApp = false;
7017 boolean didSomething = false;
7019 // See if the top visible activity is waiting to run in this process...
7022 if (mStackSupervisor.attachApplicationLocked(app)) {
7023 didSomething = true;
7025 } catch (Exception e) {
7026 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7031 // Find any services that should be running in this process...
7034 didSomething |= mServices.attachApplicationLocked(app, processName);
7035 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7036 } catch (Exception e) {
7037 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7042 // Check if a next-broadcast receiver is in this process...
7043 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7045 didSomething |= sendPendingBroadcastsLocked(app);
7046 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7047 } catch (Exception e) {
7048 // If the app died trying to launch the receiver we declare it 'bad'
7049 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7054 // Check whether the next backup agent is in this process...
7055 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7056 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7057 "New app is backup target, launching agent for " + app);
7058 notifyPackageUse(mBackupTarget.appInfo.packageName,
7059 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7061 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7062 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7063 mBackupTarget.backupMode);
7064 } catch (Exception e) {
7065 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7071 app.kill("error during init", true);
7072 handleAppDiedLocked(app, false, true);
7076 if (!didSomething) {
7077 updateOomAdjLocked();
7078 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7085 public final void attachApplication(IApplicationThread thread) {
7086 synchronized (this) {
7087 int callingPid = Binder.getCallingPid();
7088 final long origId = Binder.clearCallingIdentity();
7089 attachApplicationLocked(thread, callingPid);
7090 Binder.restoreCallingIdentity(origId);
7095 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7096 final long origId = Binder.clearCallingIdentity();
7097 synchronized (this) {
7098 ActivityStack stack = ActivityRecord.getStackLocked(token);
7099 if (stack != null) {
7101 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7102 false /* processPausingActivities */, config);
7103 if (stopProfiling) {
7104 if ((mProfileProc == r.app) && (mProfileFd != null)) {
7107 } catch (IOException e) {
7109 clearProfilerLocked();
7114 Binder.restoreCallingIdentity(origId);
7117 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7118 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7119 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7122 void enableScreenAfterBoot() {
7123 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7124 SystemClock.uptimeMillis());
7125 mWindowManager.enableScreenAfterBoot();
7127 synchronized (this) {
7128 updateEventDispatchingLocked();
7133 public void showBootMessage(final CharSequence msg, final boolean always) {
7134 if (Binder.getCallingUid() != myUid()) {
7135 throw new SecurityException();
7137 mWindowManager.showBootMessage(msg, always);
7141 public void keyguardGoingAway(int flags) {
7142 enforceNotIsolatedCaller("keyguardGoingAway");
7143 final long token = Binder.clearCallingIdentity();
7145 synchronized (this) {
7146 mKeyguardController.keyguardGoingAway(flags);
7149 Binder.restoreCallingIdentity(token);
7154 * @return whther the keyguard is currently locked.
7156 boolean isKeyguardLocked() {
7157 return mKeyguardController.isKeyguardLocked();
7160 final void finishBooting() {
7161 synchronized (this) {
7162 if (!mBootAnimationComplete) {
7163 mCallFinishBooting = true;
7166 mCallFinishBooting = false;
7169 ArraySet<String> completedIsas = new ArraySet<String>();
7170 for (String abi : Build.SUPPORTED_ABIS) {
7171 zygoteProcess.establishZygoteConnectionForAbi(abi);
7172 final String instructionSet = VMRuntime.getInstructionSet(abi);
7173 if (!completedIsas.contains(instructionSet)) {
7175 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7176 } catch (InstallerException e) {
7177 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7178 e.getMessage() +")");
7180 completedIsas.add(instructionSet);
7184 IntentFilter pkgFilter = new IntentFilter();
7185 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7186 pkgFilter.addDataScheme("package");
7187 mContext.registerReceiver(new BroadcastReceiver() {
7189 public void onReceive(Context context, Intent intent) {
7190 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7192 for (String pkg : pkgs) {
7193 synchronized (ActivityManagerService.this) {
7194 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7195 0, "query restart")) {
7196 setResultCode(Activity.RESULT_OK);
7205 IntentFilter dumpheapFilter = new IntentFilter();
7206 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7207 mContext.registerReceiver(new BroadcastReceiver() {
7209 public void onReceive(Context context, Intent intent) {
7210 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7211 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7213 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7218 // Let system services know.
7219 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7221 synchronized (this) {
7222 // Ensure that any processes we had put on hold are now started
7224 final int NP = mProcessesOnHold.size();
7226 ArrayList<ProcessRecord> procs =
7227 new ArrayList<ProcessRecord>(mProcessesOnHold);
7228 for (int ip=0; ip<NP; ip++) {
7229 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7231 startProcessLocked(procs.get(ip), "on-hold", null);
7235 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7236 // Start looking for apps that are abusing wake locks.
7237 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7238 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7239 // Tell anyone interested that we are done booting!
7240 SystemProperties.set("sys.boot_completed", "1");
7242 // And trigger dev.bootcomplete if we are not showing encryption progress
7243 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7244 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7245 SystemProperties.set("dev.bootcomplete", "1");
7247 mUserController.sendBootCompletedLocked(
7248 new IIntentReceiver.Stub() {
7250 public void performReceive(Intent intent, int resultCode,
7251 String data, Bundle extras, boolean ordered,
7252 boolean sticky, int sendingUser) {
7253 synchronized (ActivityManagerService.this) {
7254 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7259 scheduleStartProfilesLocked();
7265 public void bootAnimationComplete() {
7266 final boolean callFinishBooting;
7267 synchronized (this) {
7268 callFinishBooting = mCallFinishBooting;
7269 mBootAnimationComplete = true;
7271 if (callFinishBooting) {
7272 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7274 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7278 final void ensureBootCompleted() {
7280 boolean enableScreen;
7281 synchronized (this) {
7284 enableScreen = !mBooted;
7289 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7291 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7295 enableScreenAfterBoot();
7300 public final void activityResumed(IBinder token) {
7301 final long origId = Binder.clearCallingIdentity();
7302 synchronized(this) {
7303 ActivityRecord.activityResumedLocked(token);
7304 mWindowManager.notifyAppResumedFinished(token);
7306 Binder.restoreCallingIdentity(origId);
7310 public final void activityPaused(IBinder token) {
7311 final long origId = Binder.clearCallingIdentity();
7312 synchronized(this) {
7313 ActivityStack stack = ActivityRecord.getStackLocked(token);
7314 if (stack != null) {
7315 stack.activityPausedLocked(token, false);
7318 Binder.restoreCallingIdentity(origId);
7322 public final void activityStopped(IBinder token, Bundle icicle,
7323 PersistableBundle persistentState, CharSequence description) {
7324 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7326 // Refuse possible leaked file descriptors
7327 if (icicle != null && icicle.hasFileDescriptors()) {
7328 throw new IllegalArgumentException("File descriptors passed in Bundle");
7331 final long origId = Binder.clearCallingIdentity();
7333 synchronized (this) {
7334 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7336 r.activityStoppedLocked(icicle, persistentState, description);
7342 Binder.restoreCallingIdentity(origId);
7346 public final void activityDestroyed(IBinder token) {
7347 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7348 synchronized (this) {
7349 ActivityStack stack = ActivityRecord.getStackLocked(token);
7350 if (stack != null) {
7351 stack.activityDestroyedLocked(token, "activityDestroyed");
7357 public final void activityRelaunched(IBinder token) {
7358 final long origId = Binder.clearCallingIdentity();
7359 synchronized (this) {
7360 mStackSupervisor.activityRelaunchedLocked(token);
7362 Binder.restoreCallingIdentity(origId);
7366 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7367 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7368 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7369 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7370 synchronized (this) {
7371 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7372 if (record == null) {
7373 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7374 + "found for: " + token);
7376 record.setSizeConfigurations(horizontalSizeConfiguration,
7377 verticalSizeConfigurations, smallestSizeConfigurations);
7382 public final void backgroundResourcesReleased(IBinder token) {
7383 final long origId = Binder.clearCallingIdentity();
7385 synchronized (this) {
7386 ActivityStack stack = ActivityRecord.getStackLocked(token);
7387 if (stack != null) {
7388 stack.backgroundResourcesReleased();
7392 Binder.restoreCallingIdentity(origId);
7397 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7398 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7402 public final void notifyEnterAnimationComplete(IBinder token) {
7403 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7407 public String getCallingPackage(IBinder token) {
7408 synchronized (this) {
7409 ActivityRecord r = getCallingRecordLocked(token);
7410 return r != null ? r.info.packageName : null;
7415 public ComponentName getCallingActivity(IBinder token) {
7416 synchronized (this) {
7417 ActivityRecord r = getCallingRecordLocked(token);
7418 return r != null ? r.intent.getComponent() : null;
7422 private ActivityRecord getCallingRecordLocked(IBinder token) {
7423 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7431 public ComponentName getActivityClassForToken(IBinder token) {
7432 synchronized(this) {
7433 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7437 return r.intent.getComponent();
7442 public String getPackageForToken(IBinder token) {
7443 synchronized(this) {
7444 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7448 return r.packageName;
7453 public boolean isRootVoiceInteraction(IBinder token) {
7454 synchronized(this) {
7455 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7459 return r.rootVoiceInteraction;
7464 public IIntentSender getIntentSender(int type,
7465 String packageName, IBinder token, String resultWho,
7466 int requestCode, Intent[] intents, String[] resolvedTypes,
7467 int flags, Bundle bOptions, int userId) {
7468 enforceNotIsolatedCaller("getIntentSender");
7469 // Refuse possible leaked file descriptors
7470 if (intents != null) {
7471 if (intents.length < 1) {
7472 throw new IllegalArgumentException("Intents array length must be >= 1");
7474 for (int i=0; i<intents.length; i++) {
7475 Intent intent = intents[i];
7476 if (intent != null) {
7477 if (intent.hasFileDescriptors()) {
7478 throw new IllegalArgumentException("File descriptors passed in Intent");
7480 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7481 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7482 throw new IllegalArgumentException(
7483 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7485 intents[i] = new Intent(intent);
7488 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7489 throw new IllegalArgumentException(
7490 "Intent array length does not match resolvedTypes length");
7493 if (bOptions != null) {
7494 if (bOptions.hasFileDescriptors()) {
7495 throw new IllegalArgumentException("File descriptors passed in options");
7499 synchronized(this) {
7500 int callingUid = Binder.getCallingUid();
7501 int origUserId = userId;
7502 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7503 type == ActivityManager.INTENT_SENDER_BROADCAST,
7504 ALLOW_NON_FULL, "getIntentSender", null);
7505 if (origUserId == UserHandle.USER_CURRENT) {
7506 // We don't want to evaluate this until the pending intent is
7507 // actually executed. However, we do want to always do the
7508 // security checking for it above.
7509 userId = UserHandle.USER_CURRENT;
7512 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7513 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7514 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7515 if (!UserHandle.isSameApp(callingUid, uid)) {
7516 String msg = "Permission Denial: getIntentSender() from pid="
7517 + Binder.getCallingPid()
7518 + ", uid=" + Binder.getCallingUid()
7519 + ", (need uid=" + uid + ")"
7520 + " is not allowed to send as package " + packageName;
7522 throw new SecurityException(msg);
7526 return getIntentSenderLocked(type, packageName, callingUid, userId,
7527 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7529 } catch (RemoteException e) {
7530 throw new SecurityException(e);
7535 IIntentSender getIntentSenderLocked(int type, String packageName,
7536 int callingUid, int userId, IBinder token, String resultWho,
7537 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7539 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7540 ActivityRecord activity = null;
7541 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7542 activity = ActivityRecord.isInStackLocked(token);
7543 if (activity == null) {
7544 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7547 if (activity.finishing) {
7548 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7553 // We're going to be splicing together extras before sending, so we're
7554 // okay poking into any contained extras.
7555 if (intents != null) {
7556 for (int i = 0; i < intents.length; i++) {
7557 intents[i].setDefusable(true);
7560 Bundle.setDefusable(bOptions, true);
7562 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7563 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7564 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7565 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7566 |PendingIntent.FLAG_UPDATE_CURRENT);
7568 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7569 type, packageName, activity, resultWho,
7570 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7571 WeakReference<PendingIntentRecord> ref;
7572 ref = mIntentSenderRecords.get(key);
7573 PendingIntentRecord rec = ref != null ? ref.get() : null;
7575 if (!cancelCurrent) {
7576 if (updateCurrent) {
7577 if (rec.key.requestIntent != null) {
7578 rec.key.requestIntent.replaceExtras(intents != null ?
7579 intents[intents.length - 1] : null);
7581 if (intents != null) {
7582 intents[intents.length-1] = rec.key.requestIntent;
7583 rec.key.allIntents = intents;
7584 rec.key.allResolvedTypes = resolvedTypes;
7586 rec.key.allIntents = null;
7587 rec.key.allResolvedTypes = null;
7592 makeIntentSenderCanceledLocked(rec);
7593 mIntentSenderRecords.remove(key);
7598 rec = new PendingIntentRecord(this, key, callingUid);
7599 mIntentSenderRecords.put(key, rec.ref);
7600 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7601 if (activity.pendingResults == null) {
7602 activity.pendingResults
7603 = new HashSet<WeakReference<PendingIntentRecord>>();
7605 activity.pendingResults.add(rec.ref);
7611 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7612 Intent intent, String resolvedType,
7613 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7614 if (target instanceof PendingIntentRecord) {
7615 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7616 whitelistToken, finishedReceiver, requiredPermission, options);
7618 if (intent == null) {
7619 // Weird case: someone has given us their own custom IIntentSender, and now
7620 // they have someone else trying to send to it but of course this isn't
7621 // really a PendingIntent, so there is no base Intent, and the caller isn't
7622 // supplying an Intent... but we never want to dispatch a null Intent to
7623 // a receiver, so um... let's make something up.
7624 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7625 intent = new Intent(Intent.ACTION_MAIN);
7628 target.send(code, intent, resolvedType, whitelistToken, null,
7629 requiredPermission, options);
7630 } catch (RemoteException e) {
7632 // Platform code can rely on getting a result back when the send is done, but if
7633 // this intent sender is from outside of the system we can't rely on it doing that.
7634 // So instead we don't give it the result receiver, and instead just directly
7635 // report the finish immediately.
7636 if (finishedReceiver != null) {
7638 finishedReceiver.performReceive(intent, 0,
7639 null, null, false, false, UserHandle.getCallingUserId());
7640 } catch (RemoteException e) {
7648 public void cancelIntentSender(IIntentSender sender) {
7649 if (!(sender instanceof PendingIntentRecord)) {
7652 synchronized(this) {
7653 PendingIntentRecord rec = (PendingIntentRecord)sender;
7655 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7656 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7657 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7658 String msg = "Permission Denial: cancelIntentSender() from pid="
7659 + Binder.getCallingPid()
7660 + ", uid=" + Binder.getCallingUid()
7661 + " is not allowed to cancel package "
7662 + rec.key.packageName;
7664 throw new SecurityException(msg);
7666 } catch (RemoteException e) {
7667 throw new SecurityException(e);
7669 cancelIntentSenderLocked(rec, true);
7673 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7674 makeIntentSenderCanceledLocked(rec);
7675 mIntentSenderRecords.remove(rec.key);
7676 if (cleanActivity && rec.key.activity != null) {
7677 rec.key.activity.pendingResults.remove(rec.ref);
7681 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7682 rec.canceled = true;
7683 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7684 if (callbacks != null) {
7685 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7690 public String getPackageForIntentSender(IIntentSender pendingResult) {
7691 if (!(pendingResult instanceof PendingIntentRecord)) {
7695 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7696 return res.key.packageName;
7697 } catch (ClassCastException e) {
7703 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7704 if (!(sender instanceof PendingIntentRecord)) {
7707 synchronized(this) {
7708 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7713 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7714 IResultReceiver receiver) {
7715 if (!(sender instanceof PendingIntentRecord)) {
7718 synchronized(this) {
7719 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7724 public int getUidForIntentSender(IIntentSender sender) {
7725 if (sender instanceof PendingIntentRecord) {
7727 PendingIntentRecord res = (PendingIntentRecord)sender;
7729 } catch (ClassCastException e) {
7736 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7737 if (!(pendingResult instanceof PendingIntentRecord)) {
7741 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7742 if (res.key.allIntents == null) {
7745 for (int i=0; i<res.key.allIntents.length; i++) {
7746 Intent intent = res.key.allIntents[i];
7747 if (intent.getPackage() != null && intent.getComponent() != null) {
7752 } catch (ClassCastException e) {
7758 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7759 if (!(pendingResult instanceof PendingIntentRecord)) {
7763 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7764 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7768 } catch (ClassCastException e) {
7774 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7775 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7776 "getIntentForIntentSender()");
7777 if (!(pendingResult instanceof PendingIntentRecord)) {
7781 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7782 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7783 } catch (ClassCastException e) {
7789 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7790 if (!(pendingResult instanceof PendingIntentRecord)) {
7794 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7795 synchronized (this) {
7796 return getTagForIntentSenderLocked(res, prefix);
7798 } catch (ClassCastException e) {
7803 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7804 final Intent intent = res.key.requestIntent;
7805 if (intent != null) {
7806 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7807 || res.lastTagPrefix.equals(prefix))) {
7810 res.lastTagPrefix = prefix;
7811 final StringBuilder sb = new StringBuilder(128);
7812 if (prefix != null) {
7815 if (intent.getAction() != null) {
7816 sb.append(intent.getAction());
7817 } else if (intent.getComponent() != null) {
7818 intent.getComponent().appendShortString(sb);
7822 return res.lastTag = sb.toString();
7828 public void setProcessLimit(int max) {
7829 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7830 "setProcessLimit()");
7831 synchronized (this) {
7832 mConstants.setOverrideMaxCachedProcesses(max);
7838 public int getProcessLimit() {
7839 synchronized (this) {
7840 return mConstants.getOverrideMaxCachedProcesses();
7844 void importanceTokenDied(ImportanceToken token) {
7845 synchronized (ActivityManagerService.this) {
7846 synchronized (mPidsSelfLocked) {
7848 = mImportantProcesses.get(token.pid);
7852 mImportantProcesses.remove(token.pid);
7853 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7857 pr.forcingToImportant = null;
7858 updateProcessForegroundLocked(pr, false, false);
7860 updateOomAdjLocked();
7865 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7866 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7867 "setProcessImportant()");
7868 synchronized(this) {
7869 boolean changed = false;
7871 synchronized (mPidsSelfLocked) {
7872 ProcessRecord pr = mPidsSelfLocked.get(pid);
7873 if (pr == null && isForeground) {
7874 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7877 ImportanceToken oldToken = mImportantProcesses.get(pid);
7878 if (oldToken != null) {
7879 oldToken.token.unlinkToDeath(oldToken, 0);
7880 mImportantProcesses.remove(pid);
7882 pr.forcingToImportant = null;
7886 if (isForeground && token != null) {
7887 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7889 public void binderDied() {
7890 importanceTokenDied(this);
7894 token.linkToDeath(newToken, 0);
7895 mImportantProcesses.put(pid, newToken);
7896 pr.forcingToImportant = newToken;
7898 } catch (RemoteException e) {
7899 // If the process died while doing this, we will later
7900 // do the cleanup with the process death link.
7906 updateOomAdjLocked();
7912 public boolean isAppForeground(int uid) throws RemoteException {
7913 synchronized (this) {
7914 UidRecord uidRec = mActiveUids.get(uid);
7915 if (uidRec == null || uidRec.idle) {
7918 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7922 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7923 // be guarded by permission checking.
7924 int getUidState(int uid) {
7925 synchronized (this) {
7926 return getUidStateLocked(uid);
7930 int getUidStateLocked(int uid) {
7931 UidRecord uidRec = mActiveUids.get(uid);
7932 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7936 public boolean isInMultiWindowMode(IBinder token) {
7937 final long origId = Binder.clearCallingIdentity();
7939 synchronized(this) {
7940 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7944 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7945 return !r.getTask().mFullscreen;
7948 Binder.restoreCallingIdentity(origId);
7953 public boolean isInPictureInPictureMode(IBinder token) {
7954 final long origId = Binder.clearCallingIdentity();
7956 synchronized(this) {
7957 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7960 Binder.restoreCallingIdentity(origId);
7964 private boolean isInPictureInPictureMode(ActivityRecord r) {
7965 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7966 r.getStack().isInStackLocked(r) == null) {
7970 // If we are animating to fullscreen then we have already dispatched the PIP mode
7971 // changed, so we should reflect that check here as well.
7972 final PinnedActivityStack stack = r.getStack();
7973 final PinnedStackWindowController windowController = stack.getWindowContainerController();
7974 return !windowController.isAnimatingBoundsToFullscreen();
7978 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7979 final long origId = Binder.clearCallingIdentity();
7981 synchronized(this) {
7982 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7983 "enterPictureInPictureMode", token, params);
7985 // If the activity is already in picture in picture mode, then just return early
7986 if (isInPictureInPictureMode(r)) {
7990 // Activity supports picture-in-picture, now check that we can enter PiP at this
7992 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7993 false /* noThrow */, false /* beforeStopping */)) {
7997 final Runnable enterPipRunnable = () -> {
7998 // Only update the saved args from the args that are set
7999 r.pictureInPictureArgs.copyOnlySet(params);
8000 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8001 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8002 // Adjust the source bounds by the insets for the transition down
8003 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8004 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8005 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8006 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8007 stack.setPictureInPictureAspectRatio(aspectRatio);
8008 stack.setPictureInPictureActions(actions);
8010 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8011 r.supportsPictureInPictureWhilePausing);
8012 logPictureInPictureArgs(params);
8015 if (isKeyguardLocked()) {
8016 // If the keyguard is showing or occluded, then try and dismiss it before
8017 // entering picture-in-picture (this will prompt the user to authenticate if the
8018 // device is currently locked).
8020 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8022 public void onDismissError() throws RemoteException {
8027 public void onDismissSucceeded() throws RemoteException {
8028 mHandler.post(enterPipRunnable);
8032 public void onDismissCancelled() throws RemoteException {
8036 } catch (RemoteException e) {
8040 // Enter picture in picture immediately otherwise
8041 enterPipRunnable.run();
8046 Binder.restoreCallingIdentity(origId);
8051 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8052 final long origId = Binder.clearCallingIdentity();
8054 synchronized(this) {
8055 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8056 "setPictureInPictureParams", token, params);
8058 // Only update the saved args from the args that are set
8059 r.pictureInPictureArgs.copyOnlySet(params);
8060 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8061 // If the activity is already in picture-in-picture, update the pinned stack now
8062 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8063 // be used the next time the activity enters PiP
8064 final PinnedActivityStack stack = r.getStack();
8065 if (!stack.isAnimatingBoundsToFullscreen()) {
8066 stack.setPictureInPictureAspectRatio(
8067 r.pictureInPictureArgs.getAspectRatio());
8068 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8071 logPictureInPictureArgs(params);
8074 Binder.restoreCallingIdentity(origId);
8079 public int getMaxNumPictureInPictureActions(IBinder token) {
8080 // Currently, this is a static constant, but later, we may change this to be dependent on
8081 // the context of the activity
8085 private void logPictureInPictureArgs(PictureInPictureParams params) {
8086 if (params.hasSetActions()) {
8087 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8088 params.getActions().size());
8090 if (params.hasSetAspectRatio()) {
8091 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8092 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8093 MetricsLogger.action(lm);
8098 * Checks the state of the system and the activity associated with the given {@param token} to
8099 * verify that picture-in-picture is supported for that activity.
8101 * @return the activity record for the given {@param token} if all the checks pass.
8103 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8104 IBinder token, PictureInPictureParams params) {
8105 if (!mSupportsPictureInPicture) {
8106 throw new IllegalStateException(caller
8107 + ": Device doesn't support picture-in-picture mode.");
8110 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8112 throw new IllegalStateException(caller
8113 + ": Can't find activity for token=" + token);
8116 if (!r.supportsPictureInPicture()) {
8117 throw new IllegalStateException(caller
8118 + ": Current activity does not support picture-in-picture.");
8121 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8122 throw new IllegalStateException(caller
8123 + ": Activities on the home, assistant, or recents stack not supported");
8126 if (params.hasSetAspectRatio()
8127 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8128 params.getAspectRatio())) {
8129 final float minAspectRatio = mContext.getResources().getFloat(
8130 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8131 final float maxAspectRatio = mContext.getResources().getFloat(
8132 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8133 throw new IllegalArgumentException(String.format(caller
8134 + ": Aspect ratio is too extreme (must be between %f and %f).",
8135 minAspectRatio, maxAspectRatio));
8138 // Truncate the number of actions if necessary
8139 params.truncateActions(getMaxNumPictureInPictureActions(token));
8144 // =========================================================
8146 // =========================================================
8148 static class ProcessInfoService extends IProcessInfoService.Stub {
8149 final ActivityManagerService mActivityManagerService;
8150 ProcessInfoService(ActivityManagerService activityManagerService) {
8151 mActivityManagerService = activityManagerService;
8155 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8156 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8157 /*in*/ pids, /*out*/ states, null);
8161 public void getProcessStatesAndOomScoresFromPids(
8162 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8163 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8164 /*in*/ pids, /*out*/ states, /*out*/ scores);
8169 * For each PID in the given input array, write the current process state
8170 * for that process into the states array, or -1 to indicate that no
8171 * process with the given PID exists. If scores array is provided, write
8172 * the oom score for the process into the scores array, with INVALID_ADJ
8173 * indicating the PID doesn't exist.
8175 public void getProcessStatesAndOomScoresForPIDs(
8176 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8177 if (scores != null) {
8178 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8179 "getProcessStatesAndOomScoresForPIDs()");
8183 throw new NullPointerException("pids");
8184 } else if (states == null) {
8185 throw new NullPointerException("states");
8186 } else if (pids.length != states.length) {
8187 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8188 } else if (scores != null && pids.length != scores.length) {
8189 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8192 synchronized (mPidsSelfLocked) {
8193 for (int i = 0; i < pids.length; i++) {
8194 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8195 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8197 if (scores != null) {
8198 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8204 // =========================================================
8206 // =========================================================
8208 static class PermissionController extends IPermissionController.Stub {
8209 ActivityManagerService mActivityManagerService;
8210 PermissionController(ActivityManagerService activityManagerService) {
8211 mActivityManagerService = activityManagerService;
8215 public boolean checkPermission(String permission, int pid, int uid) {
8216 return mActivityManagerService.checkPermission(permission, pid,
8217 uid) == PackageManager.PERMISSION_GRANTED;
8221 public String[] getPackagesForUid(int uid) {
8222 return mActivityManagerService.mContext.getPackageManager()
8223 .getPackagesForUid(uid);
8227 public boolean isRuntimePermission(String permission) {
8229 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8230 .getPermissionInfo(permission, 0);
8231 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8232 == PermissionInfo.PROTECTION_DANGEROUS;
8233 } catch (NameNotFoundException nnfe) {
8234 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8240 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8242 public int checkComponentPermission(String permission, int pid, int uid,
8243 int owningUid, boolean exported) {
8244 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8245 owningUid, exported);
8249 public Object getAMSLock() {
8250 return ActivityManagerService.this;
8255 * This can be called with or without the global lock held.
8257 int checkComponentPermission(String permission, int pid, int uid,
8258 int owningUid, boolean exported) {
8259 if (pid == MY_PID) {
8260 return PackageManager.PERMISSION_GRANTED;
8262 return ActivityManager.checkComponentPermission(permission, uid,
8263 owningUid, exported);
8267 * As the only public entry point for permissions checking, this method
8268 * can enforce the semantic that requesting a check on a null global
8269 * permission is automatically denied. (Internally a null permission
8270 * string is used when calling {@link #checkComponentPermission} in cases
8271 * when only uid-based security is needed.)
8273 * This can be called with or without the global lock held.
8276 public int checkPermission(String permission, int pid, int uid) {
8277 if (permission == null) {
8278 return PackageManager.PERMISSION_DENIED;
8280 return checkComponentPermission(permission, pid, uid, -1, true);
8284 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8285 if (permission == null) {
8286 return PackageManager.PERMISSION_DENIED;
8289 // We might be performing an operation on behalf of an indirect binder
8290 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8291 // client identity accordingly before proceeding.
8292 Identity tlsIdentity = sCallerIdentity.get();
8293 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8294 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8295 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8296 uid = tlsIdentity.uid;
8297 pid = tlsIdentity.pid;
8300 return checkComponentPermission(permission, pid, uid, -1, true);
8304 * Binder IPC calls go through the public entry point.
8305 * This can be called with or without the global lock held.
8307 int checkCallingPermission(String permission) {
8308 return checkPermission(permission,
8309 Binder.getCallingPid(),
8310 UserHandle.getAppId(Binder.getCallingUid()));
8314 * This can be called with or without the global lock held.
8316 void enforceCallingPermission(String permission, String func) {
8317 if (checkCallingPermission(permission)
8318 == PackageManager.PERMISSION_GRANTED) {
8322 String msg = "Permission Denial: " + func + " from pid="
8323 + Binder.getCallingPid()
8324 + ", uid=" + Binder.getCallingUid()
8325 + " requires " + permission;
8327 throw new SecurityException(msg);
8331 * Determine if UID is holding permissions required to access {@link Uri} in
8332 * the given {@link ProviderInfo}. Final permission checking is always done
8333 * in {@link ContentProvider}.
8335 private final boolean checkHoldingPermissionsLocked(
8336 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8337 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8338 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8339 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8340 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8341 != PERMISSION_GRANTED) {
8345 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8348 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8349 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8350 if (pi.applicationInfo.uid == uid) {
8352 } else if (!pi.exported) {
8356 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8357 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8359 // check if target holds top-level <provider> permissions
8360 if (!readMet && pi.readPermission != null && considerUidPermissions
8361 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8364 if (!writeMet && pi.writePermission != null && considerUidPermissions
8365 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8369 // track if unprotected read/write is allowed; any denied
8370 // <path-permission> below removes this ability
8371 boolean allowDefaultRead = pi.readPermission == null;
8372 boolean allowDefaultWrite = pi.writePermission == null;
8374 // check if target holds any <path-permission> that match uri
8375 final PathPermission[] pps = pi.pathPermissions;
8377 final String path = grantUri.uri.getPath();
8379 while (i > 0 && (!readMet || !writeMet)) {
8381 PathPermission pp = pps[i];
8382 if (pp.match(path)) {
8384 final String pprperm = pp.getReadPermission();
8385 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8386 "Checking read perm for " + pprperm + " for " + pp.getPath()
8387 + ": match=" + pp.match(path)
8388 + " check=" + pm.checkUidPermission(pprperm, uid));
8389 if (pprperm != null) {
8390 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8391 == PERMISSION_GRANTED) {
8394 allowDefaultRead = false;
8399 final String ppwperm = pp.getWritePermission();
8400 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8401 "Checking write perm " + ppwperm + " for " + pp.getPath()
8402 + ": match=" + pp.match(path)
8403 + " check=" + pm.checkUidPermission(ppwperm, uid));
8404 if (ppwperm != null) {
8405 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8406 == PERMISSION_GRANTED) {
8409 allowDefaultWrite = false;
8417 // grant unprotected <provider> read/write, if not blocked by
8418 // <path-permission> above
8419 if (allowDefaultRead) readMet = true;
8420 if (allowDefaultWrite) writeMet = true;
8422 } catch (RemoteException e) {
8426 return readMet && writeMet;
8429 public boolean isAppStartModeDisabled(int uid, String packageName) {
8430 synchronized (this) {
8431 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8432 == ActivityManager.APP_START_MODE_DISABLED;
8436 // Unified app-op and target sdk check
8437 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8438 // Apps that target O+ are always subject to background check
8439 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8440 if (DEBUG_BACKGROUND_CHECK) {
8441 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8443 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8445 // ...and legacy apps get an AppOp check
8446 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8448 if (DEBUG_BACKGROUND_CHECK) {
8449 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8452 case AppOpsManager.MODE_ALLOWED:
8453 return ActivityManager.APP_START_MODE_NORMAL;
8454 case AppOpsManager.MODE_IGNORED:
8455 return ActivityManager.APP_START_MODE_DELAYED;
8457 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8461 // Service launch is available to apps with run-in-background exemptions but
8462 // some other background operations are not. If we're doing a check
8463 // of service-launch policy, allow those callers to proceed unrestricted.
8464 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8466 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8467 if (DEBUG_BACKGROUND_CHECK) {
8468 Slog.i(TAG, "App " + uid + "/" + packageName
8469 + " is persistent; not restricted in background");
8471 return ActivityManager.APP_START_MODE_NORMAL;
8474 // Non-persistent but background whitelisted?
8475 if (uidOnBackgroundWhitelist(uid)) {
8476 if (DEBUG_BACKGROUND_CHECK) {
8477 Slog.i(TAG, "App " + uid + "/" + packageName
8478 + " on background whitelist; not restricted in background");
8480 return ActivityManager.APP_START_MODE_NORMAL;
8483 // Is this app on the battery whitelist?
8484 if (isOnDeviceIdleWhitelistLocked(uid)) {
8485 if (DEBUG_BACKGROUND_CHECK) {
8486 Slog.i(TAG, "App " + uid + "/" + packageName
8487 + " on idle whitelist; not restricted in background");
8489 return ActivityManager.APP_START_MODE_NORMAL;
8492 // None of the service-policy criteria apply, so we apply the common criteria
8493 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8496 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8497 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8498 UidRecord uidRec = mActiveUids.get(uid);
8499 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8500 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8501 + (uidRec != null ? uidRec.idle : false));
8502 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8504 if (uidRec == null) {
8505 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8506 UserHandle.getUserId(uid), packageName);
8508 ephemeral = uidRec.ephemeral;
8512 // We are hard-core about ephemeral apps not running in the background.
8513 return ActivityManager.APP_START_MODE_DISABLED;
8516 // The caller is only interested in whether app starts are completely
8517 // disabled for the given package (that is, it is an instant app). So
8518 // we don't need to go further, which is all just seeing if we should
8519 // apply a "delayed" mode for a regular app.
8520 return ActivityManager.APP_START_MODE_NORMAL;
8522 final int startMode = (alwaysRestrict)
8523 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8524 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8526 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8527 + " pkg=" + packageName + " startMode=" + startMode
8528 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8529 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8530 // This is an old app that has been forced into a "compatible as possible"
8531 // mode of background check. To increase compatibility, we will allow other
8532 // foreground apps to cause its services to start.
8533 if (callingPid >= 0) {
8535 synchronized (mPidsSelfLocked) {
8536 proc = mPidsSelfLocked.get(callingPid);
8539 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8540 // Whoever is instigating this is in the foreground, so we will allow it
8542 return ActivityManager.APP_START_MODE_NORMAL;
8549 return ActivityManager.APP_START_MODE_NORMAL;
8552 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8553 final int appId = UserHandle.getAppId(uid);
8554 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8555 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8556 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8559 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8560 ProviderInfo pi = null;
8561 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8566 pi = AppGlobals.getPackageManager().resolveContentProvider(
8567 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8569 } catch (RemoteException ex) {
8575 void grantEphemeralAccessLocked(int userId, Intent intent,
8576 int targetAppId, int ephemeralAppId) {
8577 getPackageManagerInternalLocked().
8578 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8581 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8582 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8583 if (targetUris != null) {
8584 return targetUris.get(grantUri);
8589 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8590 String targetPkg, int targetUid, GrantUri grantUri) {
8591 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8592 if (targetUris == null) {
8593 targetUris = Maps.newArrayMap();
8594 mGrantedUriPermissions.put(targetUid, targetUris);
8597 UriPermission perm = targetUris.get(grantUri);
8599 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8600 targetUris.put(grantUri, perm);
8606 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8607 final int modeFlags) {
8608 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8609 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8610 : UriPermission.STRENGTH_OWNED;
8612 // Root gets to do everything.
8617 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8618 if (perms == null) return false;
8620 // First look for exact match
8621 final UriPermission exactPerm = perms.get(grantUri);
8622 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8626 // No exact match, look for prefixes
8627 final int N = perms.size();
8628 for (int i = 0; i < N; i++) {
8629 final UriPermission perm = perms.valueAt(i);
8630 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8631 && perm.getStrength(modeFlags) >= minStrength) {
8640 * @param uri This uri must NOT contain an embedded userId.
8641 * @param userId The userId in which the uri is to be resolved.
8644 public int checkUriPermission(Uri uri, int pid, int uid,
8645 final int modeFlags, int userId, IBinder callerToken) {
8646 enforceNotIsolatedCaller("checkUriPermission");
8648 // Another redirected-binder-call permissions check as in
8649 // {@link checkPermissionWithToken}.
8650 Identity tlsIdentity = sCallerIdentity.get();
8651 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8652 uid = tlsIdentity.uid;
8653 pid = tlsIdentity.pid;
8656 // Our own process gets to do everything.
8657 if (pid == MY_PID) {
8658 return PackageManager.PERMISSION_GRANTED;
8660 synchronized (this) {
8661 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8662 ? PackageManager.PERMISSION_GRANTED
8663 : PackageManager.PERMISSION_DENIED;
8668 * Check if the targetPkg can be granted permission to access uri by
8669 * the callingUid using the given modeFlags. Throws a security exception
8670 * if callingUid is not allowed to do this. Returns the uid of the target
8671 * if the URI permission grant should be performed; returns -1 if it is not
8672 * needed (for example targetPkg already has permission to access the URI).
8673 * If you already know the uid of the target, you can supply it in
8674 * lastTargetUid else set that to -1.
8676 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8677 final int modeFlags, int lastTargetUid) {
8678 if (!Intent.isAccessUriMode(modeFlags)) {
8682 if (targetPkg != null) {
8683 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8684 "Checking grant " + targetPkg + " permission to " + grantUri);
8687 final IPackageManager pm = AppGlobals.getPackageManager();
8689 // If this is not a content: uri, we can't do anything with it.
8690 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8691 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8692 "Can't grant URI permission for non-content URI: " + grantUri);
8696 final String authority = grantUri.uri.getAuthority();
8697 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8698 MATCH_DEBUG_TRIAGED_MISSING);
8700 Slog.w(TAG, "No content provider found for permission check: " +
8701 grantUri.uri.toSafeString());
8705 int targetUid = lastTargetUid;
8706 if (targetUid < 0 && targetPkg != null) {
8708 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8709 UserHandle.getUserId(callingUid));
8710 if (targetUid < 0) {
8711 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8712 "Can't grant URI permission no uid for: " + targetPkg);
8715 } catch (RemoteException ex) {
8720 // If we're extending a persistable grant, then we always need to create
8721 // the grant data structure so that take/release APIs work
8722 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8726 if (targetUid >= 0) {
8727 // First... does the target actually need this permission?
8728 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8729 // No need to grant the target this permission.
8730 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8731 "Target " + targetPkg + " already has full permission to " + grantUri);
8735 // First... there is no target package, so can anyone access it?
8736 boolean allowed = pi.exported;
8737 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8738 if (pi.readPermission != null) {
8742 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8743 if (pi.writePermission != null) {
8752 /* There is a special cross user grant if:
8753 * - The target is on another user.
8754 * - Apps on the current user can access the uri without any uid permissions.
8755 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8756 * grant uri permissions.
8758 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8759 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8760 modeFlags, false /*without considering the uid permissions*/);
8762 // Second... is the provider allowing granting of URI permissions?
8763 if (!specialCrossUserGrant) {
8764 if (!pi.grantUriPermissions) {
8765 throw new SecurityException("Provider " + pi.packageName
8767 + " does not allow granting of Uri permissions (uri "
8770 if (pi.uriPermissionPatterns != null) {
8771 final int N = pi.uriPermissionPatterns.length;
8772 boolean allowed = false;
8773 for (int i=0; i<N; i++) {
8774 if (pi.uriPermissionPatterns[i] != null
8775 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8781 throw new SecurityException("Provider " + pi.packageName
8783 + " does not allow granting of permission to path of Uri "
8789 // Third... does the caller itself have permission to access
8791 final int callingAppId = UserHandle.getAppId(callingUid);
8792 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8793 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8794 // Exempted authority for cropping user photos in Settings app
8796 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8797 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8801 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8802 // Require they hold a strong enough Uri permission
8803 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8804 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8805 throw new SecurityException(
8806 "UID " + callingUid + " does not have permission to " + grantUri
8807 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8808 + "or related APIs");
8810 throw new SecurityException(
8811 "UID " + callingUid + " does not have permission to " + grantUri);
8819 * @param uri This uri must NOT contain an embedded userId.
8820 * @param userId The userId in which the uri is to be resolved.
8823 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8824 final int modeFlags, int userId) {
8825 enforceNotIsolatedCaller("checkGrantUriPermission");
8826 synchronized(this) {
8827 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8828 new GrantUri(userId, uri, false), modeFlags, -1);
8832 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8833 final int modeFlags, UriPermissionOwner owner) {
8834 if (!Intent.isAccessUriMode(modeFlags)) {
8838 // So here we are: the caller has the assumed permission
8839 // to the uri, and the target doesn't. Let's now give this to
8842 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8843 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8845 final String authority = grantUri.uri.getAuthority();
8846 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8847 MATCH_DEBUG_TRIAGED_MISSING);
8849 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8853 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8854 grantUri.prefix = true;
8856 final UriPermission perm = findOrCreateUriPermissionLocked(
8857 pi.packageName, targetPkg, targetUid, grantUri);
8858 perm.grantModes(modeFlags, owner);
8861 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8862 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8863 if (targetPkg == null) {
8864 throw new NullPointerException("targetPkg");
8867 final IPackageManager pm = AppGlobals.getPackageManager();
8869 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8870 } catch (RemoteException ex) {
8874 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8876 if (targetUid < 0) {
8880 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8884 static class NeededUriGrants extends ArrayList<GrantUri> {
8885 final String targetPkg;
8886 final int targetUid;
8889 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8890 this.targetPkg = targetPkg;
8891 this.targetUid = targetUid;
8897 * Like checkGrantUriPermissionLocked, but takes an Intent.
8899 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8900 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8901 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8902 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8903 + " clip=" + (intent != null ? intent.getClipData() : null)
8904 + " from " + intent + "; flags=0x"
8905 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8907 if (targetPkg == null) {
8908 throw new NullPointerException("targetPkg");
8911 if (intent == null) {
8914 Uri data = intent.getData();
8915 ClipData clip = intent.getClipData();
8916 if (data == null && clip == null) {
8919 // Default userId for uris in the intent (if they don't specify it themselves)
8920 int contentUserHint = intent.getContentUserHint();
8921 if (contentUserHint == UserHandle.USER_CURRENT) {
8922 contentUserHint = UserHandle.getUserId(callingUid);
8924 final IPackageManager pm = AppGlobals.getPackageManager();
8926 if (needed != null) {
8927 targetUid = needed.targetUid;
8930 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8932 } catch (RemoteException ex) {
8935 if (targetUid < 0) {
8936 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8937 "Can't grant URI permission no uid for: " + targetPkg
8938 + " on user " + targetUserId);
8943 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8944 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8946 if (targetUid > 0) {
8947 if (needed == null) {
8948 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8950 needed.add(grantUri);
8954 for (int i=0; i<clip.getItemCount(); i++) {
8955 Uri uri = clip.getItemAt(i).getUri();
8957 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8958 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8960 if (targetUid > 0) {
8961 if (needed == null) {
8962 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8964 needed.add(grantUri);
8967 Intent clipIntent = clip.getItemAt(i).getIntent();
8968 if (clipIntent != null) {
8969 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8970 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8971 if (newNeeded != null) {
8983 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8985 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8986 UriPermissionOwner owner) {
8987 if (needed != null) {
8988 for (int i=0; i<needed.size(); i++) {
8989 GrantUri grantUri = needed.get(i);
8990 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8991 grantUri, needed.flags, owner);
8996 void grantUriPermissionFromIntentLocked(int callingUid,
8997 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8998 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8999 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9000 if (needed == null) {
9004 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9008 * @param uri This uri must NOT contain an embedded userId.
9009 * @param userId The userId in which the uri is to be resolved.
9012 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9013 final int modeFlags, int userId) {
9014 enforceNotIsolatedCaller("grantUriPermission");
9015 GrantUri grantUri = new GrantUri(userId, uri, false);
9016 synchronized(this) {
9017 final ProcessRecord r = getRecordForAppLocked(caller);
9019 throw new SecurityException("Unable to find app for caller "
9021 + " when granting permission to uri " + grantUri);
9023 if (targetPkg == null) {
9024 throw new IllegalArgumentException("null target");
9026 if (grantUri == null) {
9027 throw new IllegalArgumentException("null uri");
9030 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9031 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9032 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9033 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9035 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9036 UserHandle.getUserId(r.uid));
9040 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9041 if (perm.modeFlags == 0) {
9042 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9044 if (perms != null) {
9045 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9046 "Removing " + perm.targetUid + " permission to " + perm.uri);
9048 perms.remove(perm.uri);
9049 if (perms.isEmpty()) {
9050 mGrantedUriPermissions.remove(perm.targetUid);
9056 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9057 final int modeFlags) {
9058 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9059 "Revoking all granted permissions to " + grantUri);
9061 final IPackageManager pm = AppGlobals.getPackageManager();
9062 final String authority = grantUri.uri.getAuthority();
9063 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9064 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9066 Slog.w(TAG, "No content provider found for permission revoke: "
9067 + grantUri.toSafeString());
9071 // Does the caller have this permission on the URI?
9072 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9073 // If they don't have direct access to the URI, then revoke any
9074 // ownerless URI permissions that have been granted to them.
9075 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9076 if (perms != null) {
9077 boolean persistChanged = false;
9078 for (int i = perms.size()-1; i >= 0; i--) {
9079 final UriPermission perm = perms.valueAt(i);
9080 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9083 if (perm.uri.sourceUserId == grantUri.sourceUserId
9084 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9085 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9086 "Revoking non-owned " + perm.targetUid
9087 + " permission to " + perm.uri);
9088 persistChanged |= perm.revokeModes(
9089 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9090 if (perm.modeFlags == 0) {
9095 if (perms.isEmpty()) {
9096 mGrantedUriPermissions.remove(callingUid);
9098 if (persistChanged) {
9099 schedulePersistUriGrants();
9105 boolean persistChanged = false;
9107 // Go through all of the permissions and remove any that match.
9108 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9109 final int targetUid = mGrantedUriPermissions.keyAt(i);
9110 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9112 for (int j = perms.size()-1; j >= 0; j--) {
9113 final UriPermission perm = perms.valueAt(j);
9114 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9117 if (perm.uri.sourceUserId == grantUri.sourceUserId
9118 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9119 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9120 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9121 persistChanged |= perm.revokeModes(
9122 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9123 targetPackage == null);
9124 if (perm.modeFlags == 0) {
9130 if (perms.isEmpty()) {
9131 mGrantedUriPermissions.removeAt(i);
9135 if (persistChanged) {
9136 schedulePersistUriGrants();
9141 * @param uri This uri must NOT contain an embedded userId.
9142 * @param userId The userId in which the uri is to be resolved.
9145 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9146 final int modeFlags, int userId) {
9147 enforceNotIsolatedCaller("revokeUriPermission");
9148 synchronized(this) {
9149 final ProcessRecord r = getRecordForAppLocked(caller);
9151 throw new SecurityException("Unable to find app for caller "
9153 + " when revoking permission to uri " + uri);
9156 Slog.w(TAG, "revokeUriPermission: null uri");
9160 if (!Intent.isAccessUriMode(modeFlags)) {
9164 final String authority = uri.getAuthority();
9165 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9166 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9168 Slog.w(TAG, "No content provider found for permission revoke: "
9169 + uri.toSafeString());
9173 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9179 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9182 * @param packageName Package name to match, or {@code null} to apply to all
9184 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9186 * @param persistable If persistable grants should be removed.
9188 private void removeUriPermissionsForPackageLocked(
9189 String packageName, int userHandle, boolean persistable) {
9190 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9191 throw new IllegalArgumentException("Must narrow by either package or user");
9194 boolean persistChanged = false;
9196 int N = mGrantedUriPermissions.size();
9197 for (int i = 0; i < N; i++) {
9198 final int targetUid = mGrantedUriPermissions.keyAt(i);
9199 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9201 // Only inspect grants matching user
9202 if (userHandle == UserHandle.USER_ALL
9203 || userHandle == UserHandle.getUserId(targetUid)) {
9204 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9205 final UriPermission perm = it.next();
9207 // Only inspect grants matching package
9208 if (packageName == null || perm.sourcePkg.equals(packageName)
9209 || perm.targetPkg.equals(packageName)) {
9210 // Hacky solution as part of fixing a security bug; ignore
9211 // grants associated with DownloadManager so we don't have
9212 // to immediately launch it to regrant the permissions
9213 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9214 && !persistable) continue;
9216 persistChanged |= perm.revokeModes(persistable
9217 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9219 // Only remove when no modes remain; any persisted grants
9220 // will keep this alive.
9221 if (perm.modeFlags == 0) {
9227 if (perms.isEmpty()) {
9228 mGrantedUriPermissions.remove(targetUid);
9235 if (persistChanged) {
9236 schedulePersistUriGrants();
9241 public IBinder newUriPermissionOwner(String name) {
9242 enforceNotIsolatedCaller("newUriPermissionOwner");
9243 synchronized(this) {
9244 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9245 return owner.getExternalTokenLocked();
9250 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9251 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9252 synchronized(this) {
9253 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9255 throw new IllegalArgumentException("Activity does not exist; token="
9258 return r.getUriPermissionsLocked().getExternalTokenLocked();
9262 * @param uri This uri must NOT contain an embedded userId.
9263 * @param sourceUserId The userId in which the uri is to be resolved.
9264 * @param targetUserId The userId of the app that receives the grant.
9267 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9268 final int modeFlags, int sourceUserId, int targetUserId) {
9269 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9270 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9271 "grantUriPermissionFromOwner", null);
9272 synchronized(this) {
9273 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9274 if (owner == null) {
9275 throw new IllegalArgumentException("Unknown owner: " + token);
9277 if (fromUid != Binder.getCallingUid()) {
9278 if (Binder.getCallingUid() != myUid()) {
9279 // Only system code can grant URI permissions on behalf
9281 throw new SecurityException("nice try");
9284 if (targetPkg == null) {
9285 throw new IllegalArgumentException("null target");
9288 throw new IllegalArgumentException("null uri");
9291 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9292 modeFlags, owner, targetUserId);
9297 * @param uri This uri must NOT contain an embedded userId.
9298 * @param userId The userId in which the uri is to be resolved.
9301 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9302 synchronized(this) {
9303 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9304 if (owner == null) {
9305 throw new IllegalArgumentException("Unknown owner: " + token);
9309 owner.removeUriPermissionsLocked(mode);
9311 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9312 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9317 private void schedulePersistUriGrants() {
9318 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9319 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9320 10 * DateUtils.SECOND_IN_MILLIS);
9324 private void writeGrantedUriPermissions() {
9325 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9327 // Snapshot permissions so we can persist without lock
9328 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9329 synchronized (this) {
9330 final int size = mGrantedUriPermissions.size();
9331 for (int i = 0; i < size; i++) {
9332 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9333 for (UriPermission perm : perms.values()) {
9334 if (perm.persistedModeFlags != 0) {
9335 persist.add(perm.snapshot());
9341 FileOutputStream fos = null;
9343 fos = mGrantFile.startWrite();
9345 XmlSerializer out = new FastXmlSerializer();
9346 out.setOutput(fos, StandardCharsets.UTF_8.name());
9347 out.startDocument(null, true);
9348 out.startTag(null, TAG_URI_GRANTS);
9349 for (UriPermission.Snapshot perm : persist) {
9350 out.startTag(null, TAG_URI_GRANT);
9351 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9352 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9353 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9354 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9355 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9356 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9357 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9358 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9359 out.endTag(null, TAG_URI_GRANT);
9361 out.endTag(null, TAG_URI_GRANTS);
9364 mGrantFile.finishWrite(fos);
9365 } catch (IOException e) {
9367 mGrantFile.failWrite(fos);
9372 private void readGrantedUriPermissionsLocked() {
9373 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9375 final long now = System.currentTimeMillis();
9377 FileInputStream fis = null;
9379 fis = mGrantFile.openRead();
9380 final XmlPullParser in = Xml.newPullParser();
9381 in.setInput(fis, StandardCharsets.UTF_8.name());
9384 while ((type = in.next()) != END_DOCUMENT) {
9385 final String tag = in.getName();
9386 if (type == START_TAG) {
9387 if (TAG_URI_GRANT.equals(tag)) {
9388 final int sourceUserId;
9389 final int targetUserId;
9390 final int userHandle = readIntAttribute(in,
9391 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9392 if (userHandle != UserHandle.USER_NULL) {
9393 // For backwards compatibility.
9394 sourceUserId = userHandle;
9395 targetUserId = userHandle;
9397 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9398 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9400 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9401 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9402 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9403 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9404 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9405 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9407 // Sanity check that provider still belongs to source package
9408 // Both direct boot aware and unaware packages are fine as we
9409 // will do filtering at query time to avoid multiple parsing.
9410 final ProviderInfo pi = getProviderInfoLocked(
9411 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9412 | MATCH_DIRECT_BOOT_UNAWARE);
9413 if (pi != null && sourcePkg.equals(pi.packageName)) {
9416 targetUid = AppGlobals.getPackageManager().getPackageUid(
9417 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9418 } catch (RemoteException e) {
9420 if (targetUid != -1) {
9421 final UriPermission perm = findOrCreateUriPermissionLocked(
9422 sourcePkg, targetPkg, targetUid,
9423 new GrantUri(sourceUserId, uri, prefix));
9424 perm.initPersistedModes(modeFlags, createdTime);
9427 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9428 + " but instead found " + pi);
9433 } catch (FileNotFoundException e) {
9434 // Missing grants is okay
9435 } catch (IOException e) {
9436 Slog.wtf(TAG, "Failed reading Uri grants", e);
9437 } catch (XmlPullParserException e) {
9438 Slog.wtf(TAG, "Failed reading Uri grants", e);
9440 IoUtils.closeQuietly(fis);
9445 * @param uri This uri must NOT contain an embedded userId.
9446 * @param userId The userId in which the uri is to be resolved.
9449 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9450 enforceNotIsolatedCaller("takePersistableUriPermission");
9452 Preconditions.checkFlagsArgument(modeFlags,
9453 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9455 synchronized (this) {
9456 final int callingUid = Binder.getCallingUid();
9457 boolean persistChanged = false;
9458 GrantUri grantUri = new GrantUri(userId, uri, false);
9460 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9461 new GrantUri(userId, uri, false));
9462 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9463 new GrantUri(userId, uri, true));
9465 final boolean exactValid = (exactPerm != null)
9466 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9467 final boolean prefixValid = (prefixPerm != null)
9468 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9470 if (!(exactValid || prefixValid)) {
9471 throw new SecurityException("No persistable permission grants found for UID "
9472 + callingUid + " and Uri " + grantUri.toSafeString());
9476 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9479 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9482 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9484 if (persistChanged) {
9485 schedulePersistUriGrants();
9491 * @param uri This uri must NOT contain an embedded userId.
9492 * @param userId The userId in which the uri is to be resolved.
9495 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9496 enforceNotIsolatedCaller("releasePersistableUriPermission");
9498 Preconditions.checkFlagsArgument(modeFlags,
9499 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9501 synchronized (this) {
9502 final int callingUid = Binder.getCallingUid();
9503 boolean persistChanged = false;
9505 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9506 new GrantUri(userId, uri, false));
9507 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9508 new GrantUri(userId, uri, true));
9509 if (exactPerm == null && prefixPerm == null) {
9510 throw new SecurityException("No permission grants found for UID " + callingUid
9511 + " and Uri " + uri.toSafeString());
9514 if (exactPerm != null) {
9515 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9516 removeUriPermissionIfNeededLocked(exactPerm);
9518 if (prefixPerm != null) {
9519 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9520 removeUriPermissionIfNeededLocked(prefixPerm);
9523 if (persistChanged) {
9524 schedulePersistUriGrants();
9530 * Prune any older {@link UriPermission} for the given UID until outstanding
9531 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9533 * @return if any mutations occured that require persisting.
9535 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9536 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9537 if (perms == null) return false;
9538 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9540 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9541 for (UriPermission perm : perms.values()) {
9542 if (perm.persistedModeFlags != 0) {
9543 persisted.add(perm);
9547 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9548 if (trimCount <= 0) return false;
9550 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9551 for (int i = 0; i < trimCount; i++) {
9552 final UriPermission perm = persisted.get(i);
9554 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9555 "Trimming grant created at " + perm.persistedCreateTime);
9557 perm.releasePersistableModes(~0);
9558 removeUriPermissionIfNeededLocked(perm);
9565 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9566 String packageName, boolean incoming) {
9567 enforceNotIsolatedCaller("getPersistedUriPermissions");
9568 Preconditions.checkNotNull(packageName, "packageName");
9570 final int callingUid = Binder.getCallingUid();
9571 final int callingUserId = UserHandle.getUserId(callingUid);
9572 final IPackageManager pm = AppGlobals.getPackageManager();
9574 final int packageUid = pm.getPackageUid(packageName,
9575 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9576 if (packageUid != callingUid) {
9577 throw new SecurityException(
9578 "Package " + packageName + " does not belong to calling UID " + callingUid);
9580 } catch (RemoteException e) {
9581 throw new SecurityException("Failed to verify package name ownership");
9584 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9585 synchronized (this) {
9587 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9589 if (perms == null) {
9590 Slog.w(TAG, "No permission grants found for " + packageName);
9592 for (UriPermission perm : perms.values()) {
9593 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9594 result.add(perm.buildPersistedPublicApiObject());
9599 final int size = mGrantedUriPermissions.size();
9600 for (int i = 0; i < size; i++) {
9601 final ArrayMap<GrantUri, UriPermission> perms =
9602 mGrantedUriPermissions.valueAt(i);
9603 for (UriPermission perm : perms.values()) {
9604 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9605 result.add(perm.buildPersistedPublicApiObject());
9611 return new ParceledListSlice<android.content.UriPermission>(result);
9615 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9616 String packageName, int userId) {
9617 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9618 "getGrantedUriPermissions");
9620 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9621 synchronized (this) {
9622 final int size = mGrantedUriPermissions.size();
9623 for (int i = 0; i < size; i++) {
9624 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9625 for (UriPermission perm : perms.values()) {
9626 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9627 && perm.persistedModeFlags != 0) {
9628 result.add(perm.buildPersistedPublicApiObject());
9633 return new ParceledListSlice<android.content.UriPermission>(result);
9637 public void clearGrantedUriPermissions(String packageName, int userId) {
9638 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9639 "clearGrantedUriPermissions");
9640 removeUriPermissionsForPackageLocked(packageName, userId, true);
9644 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9645 synchronized (this) {
9647 who != null ? getRecordForAppLocked(who) : null;
9648 if (app == null) return;
9650 Message msg = Message.obtain();
9651 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9653 msg.arg1 = waiting ? 1 : 0;
9654 mUiHandler.sendMessage(msg);
9659 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9660 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9661 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9662 outInfo.availMem = getFreeMemory();
9663 outInfo.totalMem = getTotalMemory();
9664 outInfo.threshold = homeAppMem;
9665 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9666 outInfo.hiddenAppThreshold = cachedAppMem;
9667 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9668 ProcessList.SERVICE_ADJ);
9669 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9670 ProcessList.VISIBLE_APP_ADJ);
9671 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9672 ProcessList.FOREGROUND_APP_ADJ);
9675 // =========================================================
9677 // =========================================================
9680 public List<IBinder> getAppTasks(String callingPackage) {
9681 int callingUid = Binder.getCallingUid();
9682 long ident = Binder.clearCallingIdentity();
9684 synchronized(this) {
9685 ArrayList<IBinder> list = new ArrayList<IBinder>();
9687 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9689 final int N = mRecentTasks.size();
9690 for (int i = 0; i < N; i++) {
9691 TaskRecord tr = mRecentTasks.get(i);
9692 // Skip tasks that do not match the caller. We don't need to verify
9693 // callingPackage, because we are also limiting to callingUid and know
9694 // that will limit to the correct security sandbox.
9695 if (tr.effectiveUid != callingUid) {
9698 Intent intent = tr.getBaseIntent();
9699 if (intent == null ||
9700 !callingPackage.equals(intent.getComponent().getPackageName())) {
9703 ActivityManager.RecentTaskInfo taskInfo =
9704 createRecentTaskInfoFromTaskRecord(tr);
9705 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9706 list.add(taskImpl.asBinder());
9709 Binder.restoreCallingIdentity(ident);
9716 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9717 final int callingUid = Binder.getCallingUid();
9718 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9720 synchronized(this) {
9721 if (DEBUG_ALL) Slog.v(
9722 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9724 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9727 // TODO: Improve with MRU list from all ActivityStacks.
9728 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9735 * Creates a new RecentTaskInfo from a TaskRecord.
9737 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9738 // Update the task description to reflect any changes in the task stack
9739 tr.updateTaskDescription();
9741 // Compose the recent task info
9742 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9743 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9744 rti.persistentId = tr.taskId;
9745 rti.baseIntent = new Intent(tr.getBaseIntent());
9746 rti.origActivity = tr.origActivity;
9747 rti.realActivity = tr.realActivity;
9748 rti.description = tr.lastDescription;
9749 rti.stackId = tr.getStackId();
9750 rti.userId = tr.userId;
9751 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9752 rti.firstActiveTime = tr.firstActiveTime;
9753 rti.lastActiveTime = tr.lastActiveTime;
9754 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9755 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9756 rti.numActivities = 0;
9757 if (tr.mBounds != null) {
9758 rti.bounds = new Rect(tr.mBounds);
9760 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9761 rti.resizeMode = tr.mResizeMode;
9763 ActivityRecord base = null;
9764 ActivityRecord top = null;
9767 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9768 tmp = tr.mActivities.get(i);
9769 if (tmp.finishing) {
9773 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9776 rti.numActivities++;
9779 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9780 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9785 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9786 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9787 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9789 if (checkPermission(android.Manifest.permission.GET_TASKS,
9790 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9791 // Temporary compatibility: some existing apps on the system image may
9792 // still be requesting the old permission and not switched to the new
9793 // one; if so, we'll still allow them full access. This means we need
9794 // to see if they are holding the old permission and are a system app.
9796 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9798 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9799 + " is using old GET_TASKS but privileged; allowing");
9801 } catch (RemoteException e) {
9806 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9807 + " does not hold REAL_GET_TASKS; limiting output");
9813 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9815 final int callingUid = Binder.getCallingUid();
9816 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9817 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9819 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9820 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9821 synchronized (this) {
9822 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9824 final boolean detailed = checkCallingPermission(
9825 android.Manifest.permission.GET_DETAILED_TASKS)
9826 == PackageManager.PERMISSION_GRANTED;
9828 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9829 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9830 return ParceledListSlice.emptyList();
9832 mRecentTasks.loadUserRecentsLocked(userId);
9834 final int recentsCount = mRecentTasks.size();
9835 ArrayList<ActivityManager.RecentTaskInfo> res =
9836 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9838 final Set<Integer> includedUsers;
9839 if (includeProfiles) {
9840 includedUsers = mUserController.getProfileIds(userId);
9842 includedUsers = new HashSet<>();
9844 includedUsers.add(Integer.valueOf(userId));
9846 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9847 TaskRecord tr = mRecentTasks.get(i);
9848 // Only add calling user or related users recent tasks
9849 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9850 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9854 if (tr.realActivitySuspended) {
9855 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9859 // Return the entry if desired by the caller. We always return
9860 // the first entry, because callers always expect this to be the
9861 // foreground app. We may filter others if the caller has
9862 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9863 // we should exclude the entry.
9867 || (tr.intent == null)
9868 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9871 // If the caller doesn't have the GET_TASKS permission, then only
9872 // allow them to see a small subset of tasks -- their own and home.
9873 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9874 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9878 final ActivityStack stack = tr.getStack();
9879 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9880 if (stack != null && stack.isHomeOrRecentsStack()) {
9881 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9882 "Skipping, home or recents stack task: " + tr);
9886 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9887 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9888 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9889 "Skipping, top task in docked stack: " + tr);
9893 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9894 if (stack != null && stack.isPinnedStack()) {
9895 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9896 "Skipping, pinned stack task: " + tr);
9900 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9901 // Don't include auto remove tasks that are finished or finishing.
9902 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9903 "Skipping, auto-remove without activity: " + tr);
9906 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9907 && !tr.isAvailable) {
9908 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9909 "Skipping, unavail real act: " + tr);
9913 if (!tr.mUserSetupComplete) {
9914 // Don't include task launched while user is not done setting-up.
9915 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9916 "Skipping, user setup not complete: " + tr);
9920 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9922 rti.baseIntent.replaceExtras((Bundle)null);
9929 return new ParceledListSlice<>(res);
9934 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9935 synchronized (this) {
9936 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9937 "getTaskThumbnail()");
9938 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9939 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9941 return tr.getTaskThumbnailLocked();
9948 public ActivityManager.TaskDescription getTaskDescription(int id) {
9949 synchronized (this) {
9950 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9951 "getTaskDescription()");
9952 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9953 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9955 return tr.lastTaskDescription;
9962 public int addAppTask(IBinder activityToken, Intent intent,
9963 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9964 final int callingUid = Binder.getCallingUid();
9965 final long callingIdent = Binder.clearCallingIdentity();
9968 synchronized (this) {
9969 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9971 throw new IllegalArgumentException("Activity does not exist; token="
9974 ComponentName comp = intent.getComponent();
9976 throw new IllegalArgumentException("Intent " + intent
9977 + " must specify explicit component");
9979 if (thumbnail.getWidth() != mThumbnailWidth
9980 || thumbnail.getHeight() != mThumbnailHeight) {
9981 throw new IllegalArgumentException("Bad thumbnail size: got "
9982 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9983 + mThumbnailWidth + "x" + mThumbnailHeight);
9985 if (intent.getSelector() != null) {
9986 intent.setSelector(null);
9988 if (intent.getSourceBounds() != null) {
9989 intent.setSourceBounds(null);
9991 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9992 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9993 // The caller has added this as an auto-remove task... that makes no
9994 // sense, so turn off auto-remove.
9995 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9998 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9999 mLastAddedTaskActivity = null;
10001 ActivityInfo ainfo = mLastAddedTaskActivity;
10002 if (ainfo == null) {
10003 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10004 comp, 0, UserHandle.getUserId(callingUid));
10005 if (ainfo.applicationInfo.uid != callingUid) {
10006 throw new SecurityException(
10007 "Can't add task for another application: target uid="
10008 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10012 TaskRecord task = new TaskRecord(this,
10013 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10014 ainfo, intent, description, new TaskThumbnailInfo());
10016 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10017 if (trimIdx >= 0) {
10018 // If this would have caused a trim, then we'll abort because that
10019 // means it would be added at the end of the list but then just removed.
10020 return INVALID_TASK_ID;
10023 final int N = mRecentTasks.size();
10024 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10025 final TaskRecord tr = mRecentTasks.remove(N - 1);
10026 tr.removedFromRecents();
10029 task.inRecents = true;
10030 mRecentTasks.add(task);
10031 r.getStack().addTask(task, false, "addAppTask");
10033 task.setLastThumbnailLocked(thumbnail);
10034 task.freeLastThumbnail();
10035 return task.taskId;
10038 Binder.restoreCallingIdentity(callingIdent);
10043 public Point getAppTaskThumbnailSize() {
10044 synchronized (this) {
10045 return new Point(mThumbnailWidth, mThumbnailHeight);
10050 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10051 synchronized (this) {
10052 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10054 r.setTaskDescription(td);
10055 final TaskRecord task = r.getTask();
10056 task.updateTaskDescription();
10057 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10063 public void setTaskResizeable(int taskId, int resizeableMode) {
10064 synchronized (this) {
10065 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10066 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10067 if (task == null) {
10068 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10071 task.setResizeMode(resizeableMode);
10076 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10077 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10078 long ident = Binder.clearCallingIdentity();
10080 synchronized (this) {
10081 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10082 if (task == null) {
10083 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10086 // Place the task in the right stack if it isn't there already based on
10087 // the requested bounds.
10088 // The stack transition logic is:
10089 // - a null bounds on a freeform task moves that task to fullscreen
10090 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10091 // that task to freeform
10092 // - otherwise the task is not moved
10093 int stackId = task.getStackId();
10094 if (!StackId.isTaskResizeAllowed(stackId)) {
10095 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10097 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10098 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10099 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10100 stackId = FREEFORM_WORKSPACE_STACK_ID;
10103 // Reparent the task to the right stack if necessary
10104 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10105 if (stackId != task.getStackId()) {
10106 // Defer resume until the task is resized below
10107 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10108 DEFER_RESUME, "resizeTask");
10109 preserveWindow = false;
10112 // After reparenting (which only resizes the task to the stack bounds), resize the
10113 // task to the actual bounds provided
10114 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10117 Binder.restoreCallingIdentity(ident);
10122 public Rect getTaskBounds(int taskId) {
10123 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10124 long ident = Binder.clearCallingIdentity();
10125 Rect rect = new Rect();
10127 synchronized (this) {
10128 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10129 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10130 if (task == null) {
10131 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10134 if (task.getStack() != null) {
10135 // Return the bounds from window manager since it will be adjusted for various
10136 // things like the presense of a docked stack for tasks that aren't resizeable.
10137 task.getWindowContainerBounds(rect);
10139 // Task isn't in window manager yet since it isn't associated with a stack.
10140 // Return the persist value from activity manager
10141 if (task.mBounds != null) {
10142 rect.set(task.mBounds);
10143 } else if (task.mLastNonFullscreenBounds != null) {
10144 rect.set(task.mLastNonFullscreenBounds);
10149 Binder.restoreCallingIdentity(ident);
10155 public void cancelTaskWindowTransition(int taskId) {
10156 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10157 final long ident = Binder.clearCallingIdentity();
10159 synchronized (this) {
10160 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10161 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10162 if (task == null) {
10163 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10166 task.cancelWindowTransition();
10169 Binder.restoreCallingIdentity(ident);
10174 public void cancelTaskThumbnailTransition(int taskId) {
10175 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10176 final long ident = Binder.clearCallingIdentity();
10178 synchronized (this) {
10179 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10180 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10181 if (task == null) {
10182 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10185 task.cancelThumbnailTransition();
10188 Binder.restoreCallingIdentity(ident);
10193 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10194 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10195 final long ident = Binder.clearCallingIdentity();
10197 final TaskRecord task;
10198 synchronized (this) {
10199 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10200 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10201 if (task == null) {
10202 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10206 // Don't call this while holding the lock as this operation might hit the disk.
10207 return task.getSnapshot(reducedResolution);
10209 Binder.restoreCallingIdentity(ident);
10214 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10215 if (userId != UserHandle.getCallingUserId()) {
10216 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10217 "getTaskDescriptionIcon");
10219 final File passedIconFile = new File(filePath);
10220 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10221 passedIconFile.getName());
10222 if (!legitIconFile.getPath().equals(filePath)
10223 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10224 throw new IllegalArgumentException("Bad file path: " + filePath
10225 + " passed for userId " + userId);
10227 return mRecentTasks.getTaskDescriptionIcon(filePath);
10231 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10232 throws RemoteException {
10233 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10234 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10235 activityOptions.getCustomInPlaceResId() == 0) {
10236 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10237 "with valid animation");
10239 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10240 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10241 activityOptions.getCustomInPlaceResId());
10242 mWindowManager.executeAppTransition();
10245 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10246 // Remove all tasks with activities in the specified package from the list of recent tasks
10247 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10248 TaskRecord tr = mRecentTasks.get(i);
10249 if (tr.userId != userId) continue;
10251 ComponentName cn = tr.intent.getComponent();
10252 if (cn != null && cn.getPackageName().equals(packageName)) {
10253 // If the package name matches, remove the task.
10254 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10259 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10262 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10263 TaskRecord tr = mRecentTasks.get(i);
10264 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10268 ComponentName cn = tr.intent.getComponent();
10269 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10270 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10271 if (sameComponent) {
10272 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10278 public void removeStack(int stackId) {
10279 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10280 if (StackId.isHomeOrRecentsStack(stackId)) {
10281 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10284 synchronized (this) {
10285 final long ident = Binder.clearCallingIdentity();
10287 mStackSupervisor.removeStackLocked(stackId);
10289 Binder.restoreCallingIdentity(ident);
10295 public void moveStackToDisplay(int stackId, int displayId) {
10296 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10298 synchronized (this) {
10299 final long ident = Binder.clearCallingIdentity();
10301 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10302 + " to displayId=" + displayId);
10303 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10305 Binder.restoreCallingIdentity(ident);
10311 public boolean removeTask(int taskId) {
10312 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10313 synchronized (this) {
10314 final long ident = Binder.clearCallingIdentity();
10316 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10318 Binder.restoreCallingIdentity(ident);
10324 * TODO: Add mController hook
10327 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10328 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10330 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10331 synchronized(this) {
10332 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10336 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10337 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10339 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10340 Binder.getCallingUid(), -1, -1, "Task to front")) {
10341 ActivityOptions.abort(options);
10344 final long origId = Binder.clearCallingIdentity();
10346 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10347 if (task == null) {
10348 Slog.d(TAG, "Could not find task for id: "+ taskId);
10351 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10352 mStackSupervisor.showLockTaskToast();
10353 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10356 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10357 if (prev != null) {
10358 task.setTaskToReturnTo(prev);
10360 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10361 false /* forceNonResizable */);
10363 final ActivityRecord topActivity = task.getTopActivity();
10364 if (topActivity != null) {
10366 // We are reshowing a task, use a starting window to hide the initial draw delay
10367 // so the transition can start earlier.
10368 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10369 true /* taskSwitch */, fromRecents);
10372 Binder.restoreCallingIdentity(origId);
10374 ActivityOptions.abort(options);
10378 * Attempts to move a task backwards in z-order (the order of activities within the task is
10381 * There are several possible results of this call:
10382 * - if the task is locked, then we will show the lock toast
10383 * - if there is a task behind the provided task, then that task is made visible and resumed as
10384 * this task is moved to the back
10385 * - otherwise, if there are no other tasks in the stack:
10386 * - if this task is in the pinned stack, then we remove the stack completely, which will
10387 * have the effect of moving the task to the top or bottom of the fullscreen stack
10388 * (depending on whether it is visible)
10389 * - otherwise, we simply return home and hide this task
10391 * @param token A reference to the activity we wish to move
10392 * @param nonRoot If false then this only works if the activity is the root
10393 * of a task; if true it will work for any activity in a task.
10394 * @return Returns true if the move completed, false if not.
10397 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10398 enforceNotIsolatedCaller("moveActivityTaskToBack");
10399 synchronized(this) {
10400 final long origId = Binder.clearCallingIdentity();
10402 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10403 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10404 if (task != null) {
10405 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10408 Binder.restoreCallingIdentity(origId);
10415 public void moveTaskBackwards(int task) {
10416 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10417 "moveTaskBackwards()");
10419 synchronized(this) {
10420 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10421 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10424 final long origId = Binder.clearCallingIdentity();
10425 moveTaskBackwardsLocked(task);
10426 Binder.restoreCallingIdentity(origId);
10430 private final void moveTaskBackwardsLocked(int task) {
10431 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10435 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10436 IActivityContainerCallback callback) throws RemoteException {
10437 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10438 synchronized (this) {
10439 if (parentActivityToken == null) {
10440 throw new IllegalArgumentException("parent token must not be null");
10442 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10446 if (callback == null) {
10447 throw new IllegalArgumentException("callback must not be null");
10449 return mStackSupervisor.createVirtualActivityContainer(r, callback);
10454 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10455 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10456 synchronized (this) {
10457 final int stackId = mStackSupervisor.getNextStackId();
10458 final ActivityStack stack =
10459 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10460 if (stack == null) {
10463 return stack.mActivityContainer;
10468 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10469 synchronized (this) {
10470 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10471 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10472 return stack.mActivityContainer.getDisplayId();
10474 return DEFAULT_DISPLAY;
10479 public int getActivityStackId(IBinder token) throws RemoteException {
10480 synchronized (this) {
10481 ActivityStack stack = ActivityRecord.getStackLocked(token);
10482 if (stack == null) {
10483 return INVALID_STACK_ID;
10485 return stack.mStackId;
10490 public void exitFreeformMode(IBinder token) throws RemoteException {
10491 synchronized (this) {
10492 long ident = Binder.clearCallingIdentity();
10494 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10496 throw new IllegalArgumentException(
10497 "exitFreeformMode: No activity record matching token=" + token);
10500 final ActivityStack stack = r.getStack();
10501 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10502 throw new IllegalStateException(
10503 "exitFreeformMode: You can only go fullscreen from freeform.");
10506 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10507 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10508 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10510 Binder.restoreCallingIdentity(ident);
10516 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10517 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10518 if (StackId.isHomeOrRecentsStack(stackId)) {
10519 throw new IllegalArgumentException(
10520 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10522 synchronized (this) {
10523 long ident = Binder.clearCallingIdentity();
10525 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10526 if (task == null) {
10527 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10531 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10532 + " to stackId=" + stackId + " toTop=" + toTop);
10533 if (stackId == DOCKED_STACK_ID) {
10534 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10535 null /* initialBounds */);
10537 task.reparent(stackId, toTop,
10538 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10540 Binder.restoreCallingIdentity(ident);
10546 public void swapDockedAndFullscreenStack() throws RemoteException {
10547 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10548 synchronized (this) {
10549 long ident = Binder.clearCallingIdentity();
10551 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10552 FULLSCREEN_WORKSPACE_STACK_ID);
10553 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10555 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10556 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10558 if (topTask == null || tasks == null || tasks.size() == 0) {
10560 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10564 // TODO: App transition
10565 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10567 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10568 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10569 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10570 final int size = tasks.size();
10571 for (int i = 0; i < size; i++) {
10572 final int id = tasks.get(i).taskId;
10573 if (id == topTask.taskId) {
10577 // Defer the resume until after all the tasks have been moved
10578 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10579 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10580 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10583 // Because we deferred the resume to avoid conflicts with stack switches while
10584 // resuming, we need to do it after all the tasks are moved.
10585 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10586 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10588 mWindowManager.executeAppTransition();
10590 Binder.restoreCallingIdentity(ident);
10596 * Moves the input task to the docked stack.
10598 * @param taskId Id of task to move.
10599 * @param createMode The mode the docked stack should be created in if it doesn't exist
10601 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10603 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10604 * @param toTop If the task and stack should be moved to the top.
10605 * @param animate Whether we should play an animation for the moving the task
10606 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10607 * docked stack. Pass {@code null} to use default bounds.
10610 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10611 Rect initialBounds) {
10612 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10613 synchronized (this) {
10614 long ident = Binder.clearCallingIdentity();
10616 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10617 if (task == null) {
10618 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10622 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10623 + " to createMode=" + createMode + " toTop=" + toTop);
10624 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10626 // Defer resuming until we move the home stack to the front below
10627 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10628 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10629 "moveTaskToDockedStack");
10631 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10635 Binder.restoreCallingIdentity(ident);
10641 * Moves the top activity in the input stackId to the pinned stack.
10643 * @param stackId Id of stack to move the top activity to pinned stack.
10644 * @param bounds Bounds to use for pinned stack.
10646 * @return True if the top activity of the input stack was successfully moved to the pinned
10650 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10651 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10652 synchronized (this) {
10653 if (!mSupportsPictureInPicture) {
10654 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10655 + "Device doesn't support picture-in-picture mode");
10658 long ident = Binder.clearCallingIdentity();
10660 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10662 Binder.restoreCallingIdentity(ident);
10668 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10669 boolean preserveWindows, boolean animate, int animationDuration) {
10670 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10671 long ident = Binder.clearCallingIdentity();
10673 synchronized (this) {
10675 if (stackId == PINNED_STACK_ID) {
10676 final PinnedActivityStack pinnedStack =
10677 mStackSupervisor.getStack(PINNED_STACK_ID);
10678 if (pinnedStack != null) {
10679 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10680 destBounds, animationDuration, false /* fromFullscreen */);
10683 throw new IllegalArgumentException("Stack: " + stackId
10684 + " doesn't support animated resize.");
10687 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10688 null /* tempTaskInsetBounds */, preserveWindows,
10689 allowResizeInDockedMode, !DEFER_RESUME);
10693 Binder.restoreCallingIdentity(ident);
10698 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10699 Rect tempDockedTaskInsetBounds,
10700 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10701 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10702 "resizeDockedStack()");
10703 long ident = Binder.clearCallingIdentity();
10705 synchronized (this) {
10706 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10707 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10711 Binder.restoreCallingIdentity(ident);
10716 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10717 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10718 "resizePinnedStack()");
10719 final long ident = Binder.clearCallingIdentity();
10721 synchronized (this) {
10722 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10725 Binder.restoreCallingIdentity(ident);
10730 * Try to place task to provided position. The final position might be different depending on
10731 * current user and stacks state. The task will be moved to target stack if it's currently in
10735 public void positionTaskInStack(int taskId, int stackId, int position) {
10736 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10737 if (StackId.isHomeOrRecentsStack(stackId)) {
10738 throw new IllegalArgumentException(
10739 "positionTaskInStack: Attempt to change the position of task "
10740 + taskId + " in/to home/recents stack");
10742 synchronized (this) {
10743 long ident = Binder.clearCallingIdentity();
10745 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10746 + taskId + " in stackId=" + stackId + " at position=" + position);
10747 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10748 if (task == null) {
10749 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10753 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10756 // TODO: Have the callers of this API call a separate reparent method if that is
10757 // what they intended to do vs. having this method also do reparenting.
10758 if (task.getStack() == stack) {
10759 // Change position in current stack.
10760 stack.positionChildAt(task, position);
10762 // Reparent to new stack.
10763 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10764 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10767 Binder.restoreCallingIdentity(ident);
10773 public List<StackInfo> getAllStackInfos() {
10774 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10775 long ident = Binder.clearCallingIdentity();
10777 synchronized (this) {
10778 return mStackSupervisor.getAllStackInfosLocked();
10781 Binder.restoreCallingIdentity(ident);
10786 public StackInfo getStackInfo(int stackId) {
10787 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10788 long ident = Binder.clearCallingIdentity();
10790 synchronized (this) {
10791 return mStackSupervisor.getStackInfoLocked(stackId);
10794 Binder.restoreCallingIdentity(ident);
10799 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10800 synchronized(this) {
10801 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10806 public void updateDeviceOwner(String packageName) {
10807 final int callingUid = Binder.getCallingUid();
10808 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10809 throw new SecurityException("updateDeviceOwner called from non-system process");
10811 synchronized (this) {
10812 mDeviceOwnerName = packageName;
10817 public void updateLockTaskPackages(int userId, String[] packages) {
10818 final int callingUid = Binder.getCallingUid();
10819 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10820 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10821 "updateLockTaskPackages()");
10823 synchronized (this) {
10824 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10825 Arrays.toString(packages));
10826 mLockTaskPackages.put(userId, packages);
10827 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10832 void startLockTaskModeLocked(TaskRecord task) {
10833 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10834 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10838 // When a task is locked, dismiss the pinned stack if it exists
10839 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10841 if (pinnedStack != null) {
10842 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10845 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10846 // is initiated by system after the pinning request was shown and locked mode is initiated
10847 // by an authorized app directly
10848 final int callingUid = Binder.getCallingUid();
10849 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10850 long ident = Binder.clearCallingIdentity();
10852 if (!isSystemInitiated) {
10853 task.mLockTaskUid = callingUid;
10854 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10855 // startLockTask() called by app and task mode is lockTaskModeDefault.
10856 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10857 StatusBarManagerInternal statusBarManager =
10858 LocalServices.getService(StatusBarManagerInternal.class);
10859 if (statusBarManager != null) {
10860 statusBarManager.showScreenPinningRequest(task.taskId);
10865 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10866 if (stack == null || task != stack.topTask()) {
10867 throw new IllegalArgumentException("Invalid task, not in foreground");
10870 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10872 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10873 ActivityManager.LOCK_TASK_MODE_PINNED :
10874 ActivityManager.LOCK_TASK_MODE_LOCKED,
10875 "startLockTask", true);
10877 Binder.restoreCallingIdentity(ident);
10882 public void startLockTaskModeById(int taskId) {
10883 synchronized (this) {
10884 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10885 if (task != null) {
10886 startLockTaskModeLocked(task);
10892 public void startLockTaskModeByToken(IBinder token) {
10893 synchronized (this) {
10894 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10898 final TaskRecord task = r.getTask();
10899 if (task != null) {
10900 startLockTaskModeLocked(task);
10906 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10907 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10908 // This makes inner call to look as if it was initiated by system.
10909 long ident = Binder.clearCallingIdentity();
10911 synchronized (this) {
10912 startLockTaskModeById(taskId);
10915 Binder.restoreCallingIdentity(ident);
10920 public void stopLockTaskMode() {
10921 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10922 if (lockTask == null) {
10923 // Our work here is done.
10927 final int callingUid = Binder.getCallingUid();
10928 final int lockTaskUid = lockTask.mLockTaskUid;
10929 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10930 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10934 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10935 // It is possible lockTaskMode was started by the system process because
10936 // android:lockTaskMode is set to a locking value in the application manifest
10937 // instead of the app calling startLockTaskMode. In this case
10938 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10939 // {@link TaskRecord.effectiveUid} instead. Also caller with
10940 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10941 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10942 && callingUid != lockTaskUid
10943 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10944 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10945 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10948 long ident = Binder.clearCallingIdentity();
10950 Log.d(TAG, "stopLockTaskMode");
10952 synchronized (this) {
10953 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10954 "stopLockTask", true);
10956 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10958 tm.showInCallScreen(false);
10961 Binder.restoreCallingIdentity(ident);
10966 * This API should be called by SystemUI only when user perform certain action to dismiss
10967 * lock task mode. We should only dismiss pinned lock task mode in this case.
10970 public void stopSystemLockTaskMode() throws RemoteException {
10971 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10972 stopLockTaskMode();
10974 mStackSupervisor.showLockTaskToast();
10979 public boolean isInLockTaskMode() {
10980 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10984 public int getLockTaskModeState() {
10985 synchronized (this) {
10986 return mStackSupervisor.getLockTaskModeState();
10991 public void showLockTaskEscapeMessage(IBinder token) {
10992 synchronized (this) {
10993 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10997 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11002 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11003 throws RemoteException {
11004 synchronized (this) {
11005 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11007 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11011 final long origId = Binder.clearCallingIdentity();
11013 r.setDisablePreviewScreenshots(disable);
11015 Binder.restoreCallingIdentity(origId);
11020 // =========================================================
11021 // CONTENT PROVIDERS
11022 // =========================================================
11024 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11025 List<ProviderInfo> providers = null;
11027 providers = AppGlobals.getPackageManager()
11028 .queryContentProviders(app.processName, app.uid,
11029 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11030 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11032 } catch (RemoteException ex) {
11034 if (DEBUG_MU) Slog.v(TAG_MU,
11035 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11036 int userId = app.userId;
11037 if (providers != null) {
11038 int N = providers.size();
11039 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11040 for (int i=0; i<N; i++) {
11041 // TODO: keep logic in sync with installEncryptionUnawareProviders
11043 (ProviderInfo)providers.get(i);
11044 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11045 cpi.name, cpi.flags);
11046 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11047 // This is a singleton provider, but a user besides the
11048 // default user is asking to initialize a process it runs
11049 // in... well, no, it doesn't actually run in this process,
11050 // it runs in the process of the default user. Get rid of it.
11051 providers.remove(i);
11057 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11058 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11060 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11061 mProviderMap.putProviderByClass(comp, cpr);
11063 if (DEBUG_MU) Slog.v(TAG_MU,
11064 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11065 app.pubProviders.put(cpi.name, cpr);
11066 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11067 // Don't add this if it is a platform component that is marked
11068 // to run in multiple processes, because this is actually
11069 // part of the framework so doesn't make sense to track as a
11070 // separate apk in the process.
11071 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11074 notifyPackageUse(cpi.applicationInfo.packageName,
11075 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11082 * Check if the calling UID has a possible chance at accessing the provider
11083 * at the given authority and user.
11085 public String checkContentProviderAccess(String authority, int userId) {
11086 if (userId == UserHandle.USER_ALL) {
11087 mContext.enforceCallingOrSelfPermission(
11088 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11089 userId = UserHandle.getCallingUserId();
11092 ProviderInfo cpi = null;
11094 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11095 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11096 | PackageManager.MATCH_DISABLED_COMPONENTS
11097 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11098 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11100 } catch (RemoteException ignored) {
11103 return "Failed to find provider " + authority + " for user " + userId
11104 + "; expected to find a valid ContentProvider for this authority";
11107 ProcessRecord r = null;
11108 synchronized (mPidsSelfLocked) {
11109 r = mPidsSelfLocked.get(Binder.getCallingPid());
11112 return "Failed to find PID " + Binder.getCallingPid();
11115 synchronized (this) {
11116 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11121 * Check if {@link ProcessRecord} has a possible chance at accessing the
11122 * given {@link ProviderInfo}. Final permission checking is always done
11123 * in {@link ContentProvider}.
11125 private final String checkContentProviderPermissionLocked(
11126 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11127 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11128 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11129 boolean checkedGrants = false;
11131 // Looking for cross-user grants before enforcing the typical cross-users permissions
11132 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11133 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11134 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11137 checkedGrants = true;
11139 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11140 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11141 if (userId != tmpTargetUserId) {
11142 // When we actually went to determine the final targer user ID, this ended
11143 // up different than our initial check for the authority. This is because
11144 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11145 // SELF. So we need to re-check the grants again.
11146 checkedGrants = false;
11149 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11150 cpi.applicationInfo.uid, cpi.exported)
11151 == PackageManager.PERMISSION_GRANTED) {
11154 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11155 cpi.applicationInfo.uid, cpi.exported)
11156 == PackageManager.PERMISSION_GRANTED) {
11160 PathPermission[] pps = cpi.pathPermissions;
11162 int i = pps.length;
11165 PathPermission pp = pps[i];
11166 String pprperm = pp.getReadPermission();
11167 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11168 cpi.applicationInfo.uid, cpi.exported)
11169 == PackageManager.PERMISSION_GRANTED) {
11172 String ppwperm = pp.getWritePermission();
11173 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11174 cpi.applicationInfo.uid, cpi.exported)
11175 == PackageManager.PERMISSION_GRANTED) {
11180 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11184 final String suffix;
11185 if (!cpi.exported) {
11186 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11187 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11188 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11190 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11192 final String msg = "Permission Denial: opening provider " + cpi.name
11193 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11194 + ", uid=" + callingUid + ")" + suffix;
11200 * Returns if the ContentProvider has granted a uri to callingUid
11202 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11203 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11204 if (perms != null) {
11205 for (int i=perms.size()-1; i>=0; i--) {
11206 GrantUri grantUri = perms.keyAt(i);
11207 if (grantUri.sourceUserId == userId || !checkUser) {
11208 if (matchesProvider(grantUri.uri, cpi)) {
11218 * Returns true if the uri authority is one of the authorities specified in the provider.
11220 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11221 String uriAuth = uri.getAuthority();
11222 String cpiAuth = cpi.authority;
11223 if (cpiAuth.indexOf(';') == -1) {
11224 return cpiAuth.equals(uriAuth);
11226 String[] cpiAuths = cpiAuth.split(";");
11227 int length = cpiAuths.length;
11228 for (int i = 0; i < length; i++) {
11229 if (cpiAuths[i].equals(uriAuth)) return true;
11234 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11235 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11237 for (int i=0; i<r.conProviders.size(); i++) {
11238 ContentProviderConnection conn = r.conProviders.get(i);
11239 if (conn.provider == cpr) {
11240 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11241 "Adding provider requested by "
11242 + r.processName + " from process "
11243 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11244 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11246 conn.stableCount++;
11247 conn.numStableIncs++;
11249 conn.unstableCount++;
11250 conn.numUnstableIncs++;
11255 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11257 conn.stableCount = 1;
11258 conn.numStableIncs = 1;
11260 conn.unstableCount = 1;
11261 conn.numUnstableIncs = 1;
11263 cpr.connections.add(conn);
11264 r.conProviders.add(conn);
11265 startAssociationLocked(r.uid, r.processName, r.curProcState,
11266 cpr.uid, cpr.name, cpr.info.processName);
11269 cpr.addExternalProcessHandleLocked(externalProcessToken);
11273 boolean decProviderCountLocked(ContentProviderConnection conn,
11274 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11275 if (conn != null) {
11276 cpr = conn.provider;
11277 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11278 "Removing provider requested by "
11279 + conn.client.processName + " from process "
11280 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11281 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11283 conn.stableCount--;
11285 conn.unstableCount--;
11287 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11288 cpr.connections.remove(conn);
11289 conn.client.conProviders.remove(conn);
11290 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11291 // The client is more important than last activity -- note the time this
11292 // is happening, so we keep the old provider process around a bit as last
11293 // activity to avoid thrashing it.
11294 if (cpr.proc != null) {
11295 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11298 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11303 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11307 private void checkTime(long startTime, String where) {
11308 long now = SystemClock.uptimeMillis();
11309 if ((now-startTime) > 50) {
11310 // If we are taking more than 50ms, log about it.
11311 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11315 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11317 PROC_SPACE_TERM|PROC_PARENS,
11318 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11321 private final long[] mProcessStateStatsLongs = new long[1];
11323 boolean isProcessAliveLocked(ProcessRecord proc) {
11324 if (proc.procStatFile == null) {
11325 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11327 mProcessStateStatsLongs[0] = 0;
11328 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11329 mProcessStateStatsLongs, null)) {
11330 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11333 final long state = mProcessStateStatsLongs[0];
11334 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11336 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11339 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11340 String name, IBinder token, boolean stable, int userId) {
11341 ContentProviderRecord cpr;
11342 ContentProviderConnection conn = null;
11343 ProviderInfo cpi = null;
11345 synchronized(this) {
11346 long startTime = SystemClock.uptimeMillis();
11348 ProcessRecord r = null;
11349 if (caller != null) {
11350 r = getRecordForAppLocked(caller);
11352 throw new SecurityException(
11353 "Unable to find app for caller " + caller
11354 + " (pid=" + Binder.getCallingPid()
11355 + ") when getting content provider " + name);
11359 boolean checkCrossUser = true;
11361 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11363 // First check if this content provider has been published...
11364 cpr = mProviderMap.getProviderByName(name, userId);
11365 // If that didn't work, check if it exists for user 0 and then
11366 // verify that it's a singleton provider before using it.
11367 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11368 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11371 if (isSingleton(cpi.processName, cpi.applicationInfo,
11372 cpi.name, cpi.flags)
11373 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11374 userId = UserHandle.USER_SYSTEM;
11375 checkCrossUser = false;
11383 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11384 if (providerRunning) {
11387 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11388 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11390 throw new SecurityException(msg);
11392 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11394 if (r != null && cpr.canRunHere(r)) {
11395 // This provider has been published or is in the process
11396 // of being published... but it is also allowed to run
11397 // in the caller's process, so don't make a connection
11398 // and just let the caller instantiate its own instance.
11399 ContentProviderHolder holder = cpr.newHolder(null);
11400 // don't give caller the provider object, it needs
11401 // to make its own.
11402 holder.provider = null;
11405 // Don't expose providers between normal apps and instant apps
11407 if (AppGlobals.getPackageManager()
11408 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11411 } catch (RemoteException e) {
11414 final long origId = Binder.clearCallingIdentity();
11416 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11418 // In this case the provider instance already exists, so we can
11419 // return it right away.
11420 conn = incProviderCountLocked(r, cpr, token, stable);
11421 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11422 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11423 // If this is a perceptible app accessing the provider,
11424 // make sure to count it as being accessed and thus
11425 // back up on the LRU list. This is good because
11426 // content providers are often expensive to start.
11427 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11428 updateLruProcessLocked(cpr.proc, false, null);
11429 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11433 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11434 final int verifiedAdj = cpr.proc.verifiedAdj;
11435 boolean success = updateOomAdjLocked(cpr.proc, true);
11436 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11437 // if the process has been successfully adjusted. So to reduce races with
11438 // it, we will check whether the process still exists. Note that this doesn't
11439 // completely get rid of races with LMK killing the process, but should make
11440 // them much smaller.
11441 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11444 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11445 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11446 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11447 // NOTE: there is still a race here where a signal could be
11448 // pending on the process even though we managed to update its
11449 // adj level. Not sure what to do about this, but at least
11450 // the race is now smaller.
11452 // Uh oh... it looks like the provider's process
11453 // has been killed on us. We need to wait for a new
11454 // process to be started, and make sure its death
11455 // doesn't kill our process.
11456 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11457 + " is crashing; detaching " + r);
11458 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11459 checkTime(startTime, "getContentProviderImpl: before appDied");
11460 appDiedLocked(cpr.proc);
11461 checkTime(startTime, "getContentProviderImpl: after appDied");
11463 // This wasn't the last ref our process had on
11464 // the provider... we have now been killed, bail.
11467 providerRunning = false;
11470 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11473 Binder.restoreCallingIdentity(origId);
11476 if (!providerRunning) {
11478 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11479 cpi = AppGlobals.getPackageManager().
11480 resolveContentProvider(name,
11481 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11482 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11483 } catch (RemoteException ex) {
11488 // If the provider is a singleton AND
11489 // (it's a call within the same user || the provider is a
11491 // Then allow connecting to the singleton provider
11492 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11493 cpi.name, cpi.flags)
11494 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11496 userId = UserHandle.USER_SYSTEM;
11498 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11499 checkTime(startTime, "getContentProviderImpl: got app info for user");
11502 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11503 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11505 throw new SecurityException(msg);
11507 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11509 if (!mProcessesReady
11510 && !cpi.processName.equals("system")) {
11511 // If this content provider does not run in the system
11512 // process, and the system is not yet ready to run other
11513 // processes, then fail fast instead of hanging.
11514 throw new IllegalArgumentException(
11515 "Attempt to launch content provider before system ready");
11518 // Make sure that the user who owns this provider is running. If not,
11519 // we don't want to allow it to run.
11520 if (!mUserController.isUserRunningLocked(userId, 0)) {
11521 Slog.w(TAG, "Unable to launch app "
11522 + cpi.applicationInfo.packageName + "/"
11523 + cpi.applicationInfo.uid + " for provider "
11524 + name + ": user " + userId + " is stopped");
11528 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11529 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11530 cpr = mProviderMap.getProviderByClass(comp, userId);
11531 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11532 final boolean firstClass = cpr == null;
11534 final long ident = Binder.clearCallingIdentity();
11536 // If permissions need a review before any of the app components can run,
11537 // we return no provider and launch a review activity if the calling app
11538 // is in the foreground.
11539 if (mPermissionReviewRequired) {
11540 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11546 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11547 ApplicationInfo ai =
11548 AppGlobals.getPackageManager().
11549 getApplicationInfo(
11550 cpi.applicationInfo.packageName,
11551 STOCK_PM_FLAGS, userId);
11552 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11554 Slog.w(TAG, "No package info for content provider "
11558 ai = getAppInfoForUser(ai, userId);
11559 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11560 } catch (RemoteException ex) {
11561 // pm is in same process, this will never happen.
11563 Binder.restoreCallingIdentity(ident);
11567 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11569 if (r != null && cpr.canRunHere(r)) {
11570 // If this is a multiprocess provider, then just return its
11571 // info and allow the caller to instantiate it. Only do
11572 // this if the provider is the same user as the caller's
11573 // process, or can run as root (so can be in any process).
11574 return cpr.newHolder(null);
11577 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11578 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11579 + cpr.info.name + " callers=" + Debug.getCallers(6));
11581 // This is single process, and our app is now connecting to it.
11582 // See if we are already in the process of launching this
11584 final int N = mLaunchingProviders.size();
11586 for (i = 0; i < N; i++) {
11587 if (mLaunchingProviders.get(i) == cpr) {
11592 // If the provider is not already being launched, then get it
11595 final long origId = Binder.clearCallingIdentity();
11598 // Content provider is now in use, its package can't be stopped.
11600 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11601 AppGlobals.getPackageManager().setPackageStoppedState(
11602 cpr.appInfo.packageName, false, userId);
11603 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11604 } catch (RemoteException e) {
11605 } catch (IllegalArgumentException e) {
11606 Slog.w(TAG, "Failed trying to unstop package "
11607 + cpr.appInfo.packageName + ": " + e);
11610 // Use existing process if already started
11611 checkTime(startTime, "getContentProviderImpl: looking for process record");
11612 ProcessRecord proc = getProcessRecordLocked(
11613 cpi.processName, cpr.appInfo.uid, false);
11614 if (proc != null && proc.thread != null && !proc.killed) {
11615 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11616 "Installing in existing process " + proc);
11617 if (!proc.pubProviders.containsKey(cpi.name)) {
11618 checkTime(startTime, "getContentProviderImpl: scheduling install");
11619 proc.pubProviders.put(cpi.name, cpr);
11621 proc.thread.scheduleInstallProvider(cpi);
11622 } catch (RemoteException e) {
11626 checkTime(startTime, "getContentProviderImpl: before start process");
11627 proc = startProcessLocked(cpi.processName,
11628 cpr.appInfo, false, 0, "content provider",
11629 new ComponentName(cpi.applicationInfo.packageName,
11630 cpi.name), false, false, false);
11631 checkTime(startTime, "getContentProviderImpl: after start process");
11632 if (proc == null) {
11633 Slog.w(TAG, "Unable to launch app "
11634 + cpi.applicationInfo.packageName + "/"
11635 + cpi.applicationInfo.uid + " for provider "
11636 + name + ": process is bad");
11640 cpr.launchingApp = proc;
11641 mLaunchingProviders.add(cpr);
11643 Binder.restoreCallingIdentity(origId);
11647 checkTime(startTime, "getContentProviderImpl: updating data structures");
11649 // Make sure the provider is published (the same provider class
11650 // may be published under multiple names).
11652 mProviderMap.putProviderByClass(comp, cpr);
11655 mProviderMap.putProviderByName(name, cpr);
11656 conn = incProviderCountLocked(r, cpr, token, stable);
11657 if (conn != null) {
11658 conn.waiting = true;
11661 checkTime(startTime, "getContentProviderImpl: done!");
11663 grantEphemeralAccessLocked(userId, null /*intent*/,
11664 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11667 // Wait for the provider to be published...
11668 synchronized (cpr) {
11669 while (cpr.provider == null) {
11670 if (cpr.launchingApp == null) {
11671 Slog.w(TAG, "Unable to launch app "
11672 + cpi.applicationInfo.packageName + "/"
11673 + cpi.applicationInfo.uid + " for provider "
11674 + name + ": launching app became null");
11675 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11676 UserHandle.getUserId(cpi.applicationInfo.uid),
11677 cpi.applicationInfo.packageName,
11678 cpi.applicationInfo.uid, name);
11682 if (DEBUG_MU) Slog.v(TAG_MU,
11683 "Waiting to start provider " + cpr
11684 + " launchingApp=" + cpr.launchingApp);
11685 if (conn != null) {
11686 conn.waiting = true;
11689 } catch (InterruptedException ex) {
11691 if (conn != null) {
11692 conn.waiting = false;
11697 return cpr != null ? cpr.newHolder(conn) : null;
11700 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11701 ProcessRecord r, final int userId) {
11702 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11703 cpi.packageName, userId)) {
11705 final boolean callerForeground = r == null || r.setSchedGroup
11706 != ProcessList.SCHED_GROUP_BACKGROUND;
11708 // Show a permission review UI only for starting from a foreground app
11709 if (!callerForeground) {
11710 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11711 + cpi.packageName + " requires a permissions review");
11715 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11716 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11717 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11718 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11720 if (DEBUG_PERMISSIONS_REVIEW) {
11721 Slog.i(TAG, "u" + userId + " Launching permission review "
11722 + "for package " + cpi.packageName);
11725 final UserHandle userHandle = new UserHandle(userId);
11726 mHandler.post(new Runnable() {
11728 public void run() {
11729 mContext.startActivityAsUser(intent, userHandle);
11739 PackageManagerInternal getPackageManagerInternalLocked() {
11740 if (mPackageManagerInt == null) {
11741 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11743 return mPackageManagerInt;
11747 public final ContentProviderHolder getContentProvider(
11748 IApplicationThread caller, String name, int userId, boolean stable) {
11749 enforceNotIsolatedCaller("getContentProvider");
11750 if (caller == null) {
11751 String msg = "null IApplicationThread when getting content provider "
11754 throw new SecurityException(msg);
11756 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11757 // with cross-user grant.
11758 return getContentProviderImpl(caller, name, null, stable, userId);
11761 public ContentProviderHolder getContentProviderExternal(
11762 String name, int userId, IBinder token) {
11763 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11764 "Do not have permission in call getContentProviderExternal()");
11765 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11766 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11767 return getContentProviderExternalUnchecked(name, token, userId);
11770 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11771 IBinder token, int userId) {
11772 return getContentProviderImpl(null, name, token, true, userId);
11776 * Drop a content provider from a ProcessRecord's bookkeeping
11778 public void removeContentProvider(IBinder connection, boolean stable) {
11779 enforceNotIsolatedCaller("removeContentProvider");
11780 long ident = Binder.clearCallingIdentity();
11782 synchronized (this) {
11783 ContentProviderConnection conn;
11785 conn = (ContentProviderConnection)connection;
11786 } catch (ClassCastException e) {
11787 String msg ="removeContentProvider: " + connection
11788 + " not a ContentProviderConnection";
11790 throw new IllegalArgumentException(msg);
11792 if (conn == null) {
11793 throw new NullPointerException("connection is null");
11795 if (decProviderCountLocked(conn, null, null, stable)) {
11796 updateOomAdjLocked();
11800 Binder.restoreCallingIdentity(ident);
11804 public void removeContentProviderExternal(String name, IBinder token) {
11805 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11806 "Do not have permission in call removeContentProviderExternal()");
11807 int userId = UserHandle.getCallingUserId();
11808 long ident = Binder.clearCallingIdentity();
11810 removeContentProviderExternalUnchecked(name, token, userId);
11812 Binder.restoreCallingIdentity(ident);
11816 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11817 synchronized (this) {
11818 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11820 //remove from mProvidersByClass
11821 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11825 //update content provider record entry info
11826 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11827 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11828 if (localCpr.hasExternalProcessHandles()) {
11829 if (localCpr.removeExternalProcessHandleLocked(token)) {
11830 updateOomAdjLocked();
11832 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11833 + " with no external reference for token: "
11837 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11838 + " with no external references.");
11843 public final void publishContentProviders(IApplicationThread caller,
11844 List<ContentProviderHolder> providers) {
11845 if (providers == null) {
11849 enforceNotIsolatedCaller("publishContentProviders");
11850 synchronized (this) {
11851 final ProcessRecord r = getRecordForAppLocked(caller);
11852 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11854 throw new SecurityException(
11855 "Unable to find app for caller " + caller
11856 + " (pid=" + Binder.getCallingPid()
11857 + ") when publishing content providers");
11860 final long origId = Binder.clearCallingIdentity();
11862 final int N = providers.size();
11863 for (int i = 0; i < N; i++) {
11864 ContentProviderHolder src = providers.get(i);
11865 if (src == null || src.info == null || src.provider == null) {
11868 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11869 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11871 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11872 mProviderMap.putProviderByClass(comp, dst);
11873 String names[] = dst.info.authority.split(";");
11874 for (int j = 0; j < names.length; j++) {
11875 mProviderMap.putProviderByName(names[j], dst);
11878 int launchingCount = mLaunchingProviders.size();
11880 boolean wasInLaunchingProviders = false;
11881 for (j = 0; j < launchingCount; j++) {
11882 if (mLaunchingProviders.get(j) == dst) {
11883 mLaunchingProviders.remove(j);
11884 wasInLaunchingProviders = true;
11889 if (wasInLaunchingProviders) {
11890 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11892 synchronized (dst) {
11893 dst.provider = src.provider;
11897 updateOomAdjLocked(r, true);
11898 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11899 src.info.authority);
11903 Binder.restoreCallingIdentity(origId);
11907 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11908 ContentProviderConnection conn;
11910 conn = (ContentProviderConnection)connection;
11911 } catch (ClassCastException e) {
11912 String msg ="refContentProvider: " + connection
11913 + " not a ContentProviderConnection";
11915 throw new IllegalArgumentException(msg);
11917 if (conn == null) {
11918 throw new NullPointerException("connection is null");
11921 synchronized (this) {
11923 conn.numStableIncs += stable;
11925 stable = conn.stableCount + stable;
11927 throw new IllegalStateException("stableCount < 0: " + stable);
11930 if (unstable > 0) {
11931 conn.numUnstableIncs += unstable;
11933 unstable = conn.unstableCount + unstable;
11934 if (unstable < 0) {
11935 throw new IllegalStateException("unstableCount < 0: " + unstable);
11938 if ((stable+unstable) <= 0) {
11939 throw new IllegalStateException("ref counts can't go to zero here: stable="
11940 + stable + " unstable=" + unstable);
11942 conn.stableCount = stable;
11943 conn.unstableCount = unstable;
11948 public void unstableProviderDied(IBinder connection) {
11949 ContentProviderConnection conn;
11951 conn = (ContentProviderConnection)connection;
11952 } catch (ClassCastException e) {
11953 String msg ="refContentProvider: " + connection
11954 + " not a ContentProviderConnection";
11956 throw new IllegalArgumentException(msg);
11958 if (conn == null) {
11959 throw new NullPointerException("connection is null");
11962 // Safely retrieve the content provider associated with the connection.
11963 IContentProvider provider;
11964 synchronized (this) {
11965 provider = conn.provider.provider;
11968 if (provider == null) {
11969 // Um, yeah, we're way ahead of you.
11973 // Make sure the caller is being honest with us.
11974 if (provider.asBinder().pingBinder()) {
11975 // Er, no, still looks good to us.
11976 synchronized (this) {
11977 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11978 + " says " + conn + " died, but we don't agree");
11983 // Well look at that! It's dead!
11984 synchronized (this) {
11985 if (conn.provider.provider != provider) {
11986 // But something changed... good enough.
11990 ProcessRecord proc = conn.provider.proc;
11991 if (proc == null || proc.thread == null) {
11992 // Seems like the process is already cleaned up.
11996 // As far as we're concerned, this is just like receiving a
11997 // death notification... just a bit prematurely.
11998 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11999 + ") early provider death");
12000 final long ident = Binder.clearCallingIdentity();
12002 appDiedLocked(proc);
12004 Binder.restoreCallingIdentity(ident);
12010 public void appNotRespondingViaProvider(IBinder connection) {
12011 enforceCallingPermission(
12012 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12014 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12015 if (conn == null) {
12016 Slog.w(TAG, "ContentProviderConnection is null");
12020 final ProcessRecord host = conn.provider.proc;
12021 if (host == null) {
12022 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12026 mHandler.post(new Runnable() {
12028 public void run() {
12029 mAppErrors.appNotResponding(host, null, null, false,
12030 "ContentProvider not responding");
12035 public final void installSystemProviders() {
12036 List<ProviderInfo> providers;
12037 synchronized (this) {
12038 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12039 providers = generateApplicationProvidersLocked(app);
12040 if (providers != null) {
12041 for (int i=providers.size()-1; i>=0; i--) {
12042 ProviderInfo pi = (ProviderInfo)providers.get(i);
12043 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12044 Slog.w(TAG, "Not installing system proc provider " + pi.name
12045 + ": not system .apk");
12046 providers.remove(i);
12051 if (providers != null) {
12052 mSystemThread.installSystemProviders(providers);
12055 mConstants.start(mContext.getContentResolver());
12056 mCoreSettingsObserver = new CoreSettingsObserver(this);
12057 mFontScaleSettingObserver = new FontScaleSettingObserver();
12059 // Now that the settings provider is published we can consider sending
12060 // in a rescue party.
12061 RescueParty.onSettingsProviderPublished(mContext);
12063 //mUsageStatsService.monitorPackages();
12066 private void startPersistentApps(int matchFlags) {
12067 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12069 synchronized (this) {
12071 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12072 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12073 for (ApplicationInfo app : apps) {
12074 if (!"android".equals(app.packageName)) {
12075 addAppLocked(app, null, false, null /* ABI override */);
12078 } catch (RemoteException ex) {
12084 * When a user is unlocked, we need to install encryption-unaware providers
12085 * belonging to any running apps.
12087 private void installEncryptionUnawareProviders(int userId) {
12088 // We're only interested in providers that are encryption unaware, and
12089 // we don't care about uninstalled apps, since there's no way they're
12090 // running at this point.
12091 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12093 synchronized (this) {
12094 final int NP = mProcessNames.getMap().size();
12095 for (int ip = 0; ip < NP; ip++) {
12096 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12097 final int NA = apps.size();
12098 for (int ia = 0; ia < NA; ia++) {
12099 final ProcessRecord app = apps.valueAt(ia);
12100 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12102 final int NG = app.pkgList.size();
12103 for (int ig = 0; ig < NG; ig++) {
12105 final String pkgName = app.pkgList.keyAt(ig);
12106 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12107 .getPackageInfo(pkgName, matchFlags, userId);
12108 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12109 for (ProviderInfo pi : pkgInfo.providers) {
12110 // TODO: keep in sync with generateApplicationProvidersLocked
12111 final boolean processMatch = Objects.equals(pi.processName,
12112 app.processName) || pi.multiprocess;
12113 final boolean userMatch = isSingleton(pi.processName,
12114 pi.applicationInfo, pi.name, pi.flags)
12115 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12116 if (processMatch && userMatch) {
12117 Log.v(TAG, "Installing " + pi);
12118 app.thread.scheduleInstallProvider(pi);
12120 Log.v(TAG, "Skipping " + pi);
12124 } catch (RemoteException ignored) {
12133 * Allows apps to retrieve the MIME type of a URI.
12134 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12135 * users, then it does not need permission to access the ContentProvider.
12136 * Either, it needs cross-user uri grants.
12138 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12140 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12141 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12143 public String getProviderMimeType(Uri uri, int userId) {
12144 enforceNotIsolatedCaller("getProviderMimeType");
12145 final String name = uri.getAuthority();
12146 int callingUid = Binder.getCallingUid();
12147 int callingPid = Binder.getCallingPid();
12149 boolean clearedIdentity = false;
12150 synchronized (this) {
12151 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12153 if (canClearIdentity(callingPid, callingUid, userId)) {
12154 clearedIdentity = true;
12155 ident = Binder.clearCallingIdentity();
12157 ContentProviderHolder holder = null;
12159 holder = getContentProviderExternalUnchecked(name, null, userId);
12160 if (holder != null) {
12161 return holder.provider.getType(uri);
12163 } catch (RemoteException e) {
12164 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12166 } catch (Exception e) {
12167 Log.w(TAG, "Exception while determining type of " + uri, e);
12170 // We need to clear the identity to call removeContentProviderExternalUnchecked
12171 if (!clearedIdentity) {
12172 ident = Binder.clearCallingIdentity();
12175 if (holder != null) {
12176 removeContentProviderExternalUnchecked(name, null, userId);
12179 Binder.restoreCallingIdentity(ident);
12186 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12187 if (UserHandle.getUserId(callingUid) == userId) {
12190 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12191 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12192 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12193 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12199 // =========================================================
12200 // GLOBAL MANAGEMENT
12201 // =========================================================
12203 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12204 boolean isolated, int isolatedUid) {
12205 String proc = customProcess != null ? customProcess : info.processName;
12206 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12207 final int userId = UserHandle.getUserId(info.uid);
12208 int uid = info.uid;
12210 if (isolatedUid == 0) {
12211 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12213 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12214 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12215 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12217 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12218 mNextIsolatedProcessUid++;
12219 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12220 // No process for this uid, use it.
12224 if (stepsLeft <= 0) {
12229 // Special case for startIsolatedProcess (internal only), where
12230 // the uid of the isolated process is specified by the caller.
12233 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12235 // Register the isolated UID with this application so BatteryStats knows to
12236 // attribute resource usage to the application.
12238 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12239 // about the process state of the isolated UID *before* it is registered with the
12240 // owning application.
12241 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12243 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12244 if (!mBooted && !mBooting
12245 && userId == UserHandle.USER_SYSTEM
12246 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12247 r.persistent = true;
12248 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12250 addProcessNameLocked(r);
12254 private boolean uidOnBackgroundWhitelist(final int uid) {
12255 final int appId = UserHandle.getAppId(uid);
12256 final int[] whitelist = mBackgroundAppIdWhitelist;
12257 final int N = whitelist.length;
12258 for (int i = 0; i < N; i++) {
12259 if (appId == whitelist[i]) {
12267 public void backgroundWhitelistUid(final int uid) {
12268 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12269 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12272 if (DEBUG_BACKGROUND_CHECK) {
12273 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12275 synchronized (this) {
12276 final int N = mBackgroundAppIdWhitelist.length;
12277 int[] newList = new int[N+1];
12278 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12279 newList[N] = UserHandle.getAppId(uid);
12280 mBackgroundAppIdWhitelist = newList;
12284 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12285 String abiOverride) {
12288 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12295 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12296 updateLruProcessLocked(app, false, null);
12297 updateOomAdjLocked();
12300 // This package really, really can not be stopped.
12302 AppGlobals.getPackageManager().setPackageStoppedState(
12303 info.packageName, false, UserHandle.getUserId(app.uid));
12304 } catch (RemoteException e) {
12305 } catch (IllegalArgumentException e) {
12306 Slog.w(TAG, "Failed trying to unstop package "
12307 + info.packageName + ": " + e);
12310 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12311 app.persistent = true;
12312 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12314 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12315 mPersistentStartingProcesses.add(app);
12316 startProcessLocked(app, "added application",
12317 customProcess != null ? customProcess : app.processName, abiOverride,
12318 null /* entryPoint */, null /* entryPointArgs */);
12324 public void unhandledBack() {
12325 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12326 "unhandledBack()");
12328 synchronized(this) {
12329 final long origId = Binder.clearCallingIdentity();
12331 getFocusedStack().unhandledBackLocked();
12333 Binder.restoreCallingIdentity(origId);
12338 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12339 enforceNotIsolatedCaller("openContentUri");
12340 final int userId = UserHandle.getCallingUserId();
12341 final Uri uri = Uri.parse(uriString);
12342 String name = uri.getAuthority();
12343 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12344 ParcelFileDescriptor pfd = null;
12346 // We record the binder invoker's uid in thread-local storage before
12347 // going to the content provider to open the file. Later, in the code
12348 // that handles all permissions checks, we look for this uid and use
12349 // that rather than the Activity Manager's own uid. The effect is that
12350 // we do the check against the caller's permissions even though it looks
12351 // to the content provider like the Activity Manager itself is making
12353 Binder token = new Binder();
12354 sCallerIdentity.set(new Identity(
12355 token, Binder.getCallingPid(), Binder.getCallingUid()));
12357 pfd = cph.provider.openFile(null, uri, "r", null, token);
12358 } catch (FileNotFoundException e) {
12359 // do nothing; pfd will be returned null
12361 // Ensure that whatever happens, we clean up the identity state
12362 sCallerIdentity.remove();
12363 // Ensure we're done with the provider.
12364 removeContentProviderExternalUnchecked(name, null, userId);
12367 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12372 // Actually is sleeping or shutting down or whatever else in the future
12373 // is an inactive state.
12374 boolean isSleepingOrShuttingDownLocked() {
12375 return isSleepingLocked() || mShuttingDown;
12378 boolean isShuttingDownLocked() {
12379 return mShuttingDown;
12382 boolean isSleepingLocked() {
12386 void onWakefulnessChanged(int wakefulness) {
12387 synchronized(this) {
12388 mWakefulness = wakefulness;
12389 updateSleepIfNeededLocked();
12393 void finishRunningVoiceLocked() {
12394 if (mRunningVoice != null) {
12395 mRunningVoice = null;
12396 mVoiceWakeLock.release();
12397 updateSleepIfNeededLocked();
12401 void startTimeTrackingFocusedActivityLocked() {
12402 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12403 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12404 mCurAppTimeTracker.start(resumedActivity.packageName);
12408 void updateSleepIfNeededLocked() {
12409 final boolean shouldSleep = shouldSleepLocked();
12410 if (mSleeping && !shouldSleep) {
12412 startTimeTrackingFocusedActivityLocked();
12413 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12414 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12415 sendNotifyVrManagerOfSleepState(false);
12416 updateOomAdjLocked();
12417 } else if (!mSleeping && shouldSleep) {
12419 if (mCurAppTimeTracker != null) {
12420 mCurAppTimeTracker.stop();
12422 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12423 mStackSupervisor.goingToSleepLocked();
12424 sendNotifyVrManagerOfSleepState(true);
12425 updateOomAdjLocked();
12427 // Initialize the wake times of all processes.
12428 checkExcessivePowerUsageLocked(false);
12429 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12430 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12431 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12434 // Also update state in a special way for running foreground services UI.
12435 switch (mWakefulness) {
12436 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12437 case PowerManagerInternal.WAKEFULNESS_DREAMING:
12438 case PowerManagerInternal.WAKEFULNESS_DOZING:
12439 mServices.updateScreenStateLocked(false);
12441 case PowerManagerInternal.WAKEFULNESS_AWAKE:
12443 mServices.updateScreenStateLocked(true);
12448 private boolean shouldSleepLocked() {
12449 // Resume applications while running a voice interactor.
12450 if (mRunningVoice != null) {
12454 // TODO: Transform the lock screen state into a sleep token instead.
12455 switch (mWakefulness) {
12456 case PowerManagerInternal.WAKEFULNESS_AWAKE:
12457 case PowerManagerInternal.WAKEFULNESS_DREAMING:
12458 case PowerManagerInternal.WAKEFULNESS_DOZING:
12459 // Pause applications whenever the lock screen is shown or any sleep
12460 // tokens have been acquired.
12461 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12462 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12464 // If we're asleep then pause applications unconditionally.
12469 /** Pokes the task persister. */
12470 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12471 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12475 * Notifies all listeners when the pinned stack animation starts.
12478 public void notifyPinnedStackAnimationStarted() {
12479 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12483 * Notifies all listeners when the pinned stack animation ends.
12486 public void notifyPinnedStackAnimationEnded() {
12487 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12491 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12492 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12496 public boolean shutdown(int timeout) {
12497 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12498 != PackageManager.PERMISSION_GRANTED) {
12499 throw new SecurityException("Requires permission "
12500 + android.Manifest.permission.SHUTDOWN);
12503 boolean timedout = false;
12505 synchronized(this) {
12506 mShuttingDown = true;
12507 updateEventDispatchingLocked();
12508 timedout = mStackSupervisor.shutdownLocked(timeout);
12511 mAppOpsService.shutdown();
12512 if (mUsageStatsService != null) {
12513 mUsageStatsService.prepareShutdown();
12515 mBatteryStatsService.shutdown();
12516 synchronized (this) {
12517 mProcessStats.shutdownLocked();
12518 notifyTaskPersisterLocked(null, true);
12524 public final void activitySlept(IBinder token) {
12525 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12527 final long origId = Binder.clearCallingIdentity();
12529 synchronized (this) {
12530 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12532 mStackSupervisor.activitySleptLocked(r);
12536 Binder.restoreCallingIdentity(origId);
12539 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12540 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12541 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12542 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12543 boolean wasRunningVoice = mRunningVoice != null;
12544 mRunningVoice = session;
12545 if (!wasRunningVoice) {
12546 mVoiceWakeLock.acquire();
12547 updateSleepIfNeededLocked();
12552 private void updateEventDispatchingLocked() {
12553 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12557 public void setLockScreenShown(boolean showing) {
12558 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12559 != PackageManager.PERMISSION_GRANTED) {
12560 throw new SecurityException("Requires permission "
12561 + android.Manifest.permission.DEVICE_POWER);
12564 synchronized(this) {
12565 long ident = Binder.clearCallingIdentity();
12567 mKeyguardController.setKeyguardShown(showing);
12569 Binder.restoreCallingIdentity(ident);
12572 closeSystemDialogs("setLockScreenShown");
12576 public void notifyLockedProfile(@UserIdInt int userId) {
12578 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12579 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12581 } catch (RemoteException ex) {
12582 throw new SecurityException("Fail to check is caller a privileged app", ex);
12585 synchronized (this) {
12586 final long ident = Binder.clearCallingIdentity();
12588 if (mUserController.shouldConfirmCredentials(userId)) {
12589 if (mKeyguardController.isKeyguardLocked()) {
12590 // Showing launcher to avoid user entering credential twice.
12591 final int currentUserId = mUserController.getCurrentUserIdLocked();
12592 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12594 mStackSupervisor.lockAllProfileTasks(userId);
12597 Binder.restoreCallingIdentity(ident);
12603 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12604 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12605 synchronized (this) {
12606 final long ident = Binder.clearCallingIdentity();
12608 mActivityStarter.startConfirmCredentialIntent(intent, options);
12610 Binder.restoreCallingIdentity(ident);
12616 public void stopAppSwitches() {
12617 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12618 != PackageManager.PERMISSION_GRANTED) {
12619 throw new SecurityException("viewquires permission "
12620 + android.Manifest.permission.STOP_APP_SWITCHES);
12623 synchronized(this) {
12624 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12625 + APP_SWITCH_DELAY_TIME;
12626 mDidAppSwitch = false;
12627 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12628 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12629 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12633 public void resumeAppSwitches() {
12634 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12635 != PackageManager.PERMISSION_GRANTED) {
12636 throw new SecurityException("Requires permission "
12637 + android.Manifest.permission.STOP_APP_SWITCHES);
12640 synchronized(this) {
12641 // Note that we don't execute any pending app switches... we will
12642 // let those wait until either the timeout, or the next start
12643 // activity request.
12644 mAppSwitchesAllowedTime = 0;
12648 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12649 int callingPid, int callingUid, String name) {
12650 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12654 int perm = checkComponentPermission(
12655 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12656 sourceUid, -1, true);
12657 if (perm == PackageManager.PERMISSION_GRANTED) {
12661 // If the actual IPC caller is different from the logical source, then
12662 // also see if they are allowed to control app switches.
12663 if (callingUid != -1 && callingUid != sourceUid) {
12664 perm = checkComponentPermission(
12665 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12666 callingUid, -1, true);
12667 if (perm == PackageManager.PERMISSION_GRANTED) {
12672 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12676 public void setDebugApp(String packageName, boolean waitForDebugger,
12677 boolean persistent) {
12678 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12681 long ident = Binder.clearCallingIdentity();
12683 // Note that this is not really thread safe if there are multiple
12684 // callers into it at the same time, but that's not a situation we
12687 final ContentResolver resolver = mContext.getContentResolver();
12688 Settings.Global.putString(
12689 resolver, Settings.Global.DEBUG_APP,
12691 Settings.Global.putInt(
12692 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12693 waitForDebugger ? 1 : 0);
12696 synchronized (this) {
12698 mOrigDebugApp = mDebugApp;
12699 mOrigWaitForDebugger = mWaitForDebugger;
12701 mDebugApp = packageName;
12702 mWaitForDebugger = waitForDebugger;
12703 mDebugTransient = !persistent;
12704 if (packageName != null) {
12705 forceStopPackageLocked(packageName, -1, false, false, true, true,
12706 false, UserHandle.USER_ALL, "set debug app");
12710 Binder.restoreCallingIdentity(ident);
12714 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12715 synchronized (this) {
12716 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12717 if (!isDebuggable) {
12718 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12719 throw new SecurityException("Process not debuggable: " + app.packageName);
12723 mTrackAllocationApp = processName;
12727 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12728 synchronized (this) {
12729 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12730 if (!isDebuggable) {
12731 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12732 throw new SecurityException("Process not debuggable: " + app.packageName);
12735 mProfileApp = processName;
12736 mProfileFile = profilerInfo.profileFile;
12737 if (mProfileFd != null) {
12739 mProfileFd.close();
12740 } catch (IOException e) {
12744 mProfileFd = profilerInfo.profileFd;
12745 mSamplingInterval = profilerInfo.samplingInterval;
12746 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12747 mStreamingOutput = profilerInfo.streamingOutput;
12752 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12753 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12754 if (!isDebuggable) {
12755 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12756 throw new SecurityException("Process not debuggable: " + app.packageName);
12759 mNativeDebuggingApp = processName;
12763 public void setAlwaysFinish(boolean enabled) {
12764 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12765 "setAlwaysFinish()");
12767 long ident = Binder.clearCallingIdentity();
12769 Settings.Global.putInt(
12770 mContext.getContentResolver(),
12771 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12773 synchronized (this) {
12774 mAlwaysFinishActivities = enabled;
12777 Binder.restoreCallingIdentity(ident);
12782 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12783 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12784 "setActivityController()");
12785 synchronized (this) {
12786 mController = controller;
12787 mControllerIsAMonkey = imAMonkey;
12788 Watchdog.getInstance().setActivityController(controller);
12793 public void setUserIsMonkey(boolean userIsMonkey) {
12794 synchronized (this) {
12795 synchronized (mPidsSelfLocked) {
12796 final int callingPid = Binder.getCallingPid();
12797 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12798 if (proc == null) {
12799 throw new SecurityException("Unknown process: " + callingPid);
12801 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12802 throw new SecurityException("Only an instrumentation process "
12803 + "with a UiAutomation can call setUserIsMonkey");
12806 mUserIsMonkey = userIsMonkey;
12811 public boolean isUserAMonkey() {
12812 synchronized (this) {
12813 // If there is a controller also implies the user is a monkey.
12814 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12819 * @deprecated This method is only used by a few internal components and it will soon be
12820 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12821 * No new code should be calling it.
12825 public void requestBugReport(int bugreportType) {
12826 String extraOptions = null;
12827 switch (bugreportType) {
12828 case ActivityManager.BUGREPORT_OPTION_FULL:
12829 // Default options.
12831 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12832 extraOptions = "bugreportplus";
12834 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12835 extraOptions = "bugreportremote";
12837 case ActivityManager.BUGREPORT_OPTION_WEAR:
12838 extraOptions = "bugreportwear";
12840 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12841 extraOptions = "bugreporttelephony";
12844 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12847 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12848 if (extraOptions != null) {
12849 SystemProperties.set("dumpstate.options", extraOptions);
12851 SystemProperties.set("ctl.start", "bugreport");
12855 * @deprecated This method is only used by a few internal components and it will soon be
12856 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12857 * No new code should be calling it.
12861 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12863 if (!TextUtils.isEmpty(shareTitle)) {
12864 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12865 String errorStr = "shareTitle should be less than " +
12866 MAX_BUGREPORT_TITLE_SIZE + " characters";
12867 throw new IllegalArgumentException(errorStr);
12869 if (!TextUtils.isEmpty(shareDescription)) {
12872 length = shareDescription.getBytes("UTF-8").length;
12873 } catch (UnsupportedEncodingException e) {
12874 String errorStr = "shareDescription: UnsupportedEncodingException";
12875 throw new IllegalArgumentException(errorStr);
12877 if (length > SystemProperties.PROP_VALUE_MAX) {
12878 String errorStr = "shareTitle should be less than " +
12879 SystemProperties.PROP_VALUE_MAX + " bytes";
12880 throw new IllegalArgumentException(errorStr);
12882 SystemProperties.set("dumpstate.options.description", shareDescription);
12885 SystemProperties.set("dumpstate.options.title", shareTitle);
12889 Slog.d(TAG, "Bugreport notification title " + shareTitle
12890 + " description " + shareDescription);
12891 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12894 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12895 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12898 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12899 if (r != null && (r.instr != null || r.usingWrapper)) {
12900 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12902 return KEY_DISPATCHING_TIMEOUT;
12906 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12907 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12908 != PackageManager.PERMISSION_GRANTED) {
12909 throw new SecurityException("Requires permission "
12910 + android.Manifest.permission.FILTER_EVENTS);
12912 ProcessRecord proc;
12914 synchronized (this) {
12915 synchronized (mPidsSelfLocked) {
12916 proc = mPidsSelfLocked.get(pid);
12918 timeout = getInputDispatchingTimeoutLocked(proc);
12921 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12929 * Handle input dispatching timeouts.
12930 * Returns whether input dispatching should be aborted or not.
12932 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12933 final ActivityRecord activity, final ActivityRecord parent,
12934 final boolean aboveSystem, String reason) {
12935 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12936 != PackageManager.PERMISSION_GRANTED) {
12937 throw new SecurityException("Requires permission "
12938 + android.Manifest.permission.FILTER_EVENTS);
12941 final String annotation;
12942 if (reason == null) {
12943 annotation = "Input dispatching timed out";
12945 annotation = "Input dispatching timed out (" + reason + ")";
12948 if (proc != null) {
12949 synchronized (this) {
12950 if (proc.debugging) {
12954 if (proc.instr != null) {
12955 Bundle info = new Bundle();
12956 info.putString("shortMsg", "keyDispatchingTimedOut");
12957 info.putString("longMsg", annotation);
12958 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12962 mHandler.post(new Runnable() {
12964 public void run() {
12965 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12974 public Bundle getAssistContextExtras(int requestType) {
12975 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12976 null, null, true /* focused */, true /* newSessionId */,
12977 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12981 synchronized (pae) {
12982 while (!pae.haveResult) {
12985 } catch (InterruptedException e) {
12989 synchronized (this) {
12990 buildAssistBundleLocked(pae, pae.result);
12991 mPendingAssistExtras.remove(pae);
12992 mUiHandler.removeCallbacks(pae);
12998 public boolean isAssistDataAllowedOnCurrentActivity() {
13000 synchronized (this) {
13001 final ActivityStack focusedStack = getFocusedStack();
13002 if (focusedStack == null || focusedStack.isAssistantStack()) {
13006 final ActivityRecord activity = focusedStack.topActivity();
13007 if (activity == null) {
13010 userId = activity.userId;
13012 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13013 Context.DEVICE_POLICY_SERVICE);
13014 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13018 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13019 long ident = Binder.clearCallingIdentity();
13021 synchronized (this) {
13022 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13023 ActivityRecord top = getFocusedStack().topActivity();
13024 if (top != caller) {
13025 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13026 + " is not current top " + top);
13029 if (!top.nowVisible) {
13030 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13031 + " is not visible");
13035 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13038 Binder.restoreCallingIdentity(ident);
13043 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13044 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13045 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13046 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13047 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13051 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13052 IBinder activityToken, int flags) {
13053 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13054 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13055 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13058 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13059 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13060 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13062 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13063 "enqueueAssistContext()");
13065 synchronized (this) {
13066 ActivityRecord activity = getFocusedStack().topActivity();
13067 if (activity == null) {
13068 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13071 if (activity.app == null || activity.app.thread == null) {
13072 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13076 if (activityToken != null) {
13077 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13078 if (activity != caller) {
13079 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13080 + " is not current top " + activity);
13085 activity = ActivityRecord.forTokenLocked(activityToken);
13086 if (activity == null) {
13087 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13088 + " couldn't be found");
13093 PendingAssistExtras pae;
13094 Bundle extras = new Bundle();
13095 if (args != null) {
13096 extras.putAll(args);
13098 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13099 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13101 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13103 pae.isHome = activity.isHomeActivity();
13105 // Increment the sessionId if necessary
13106 if (newSessionId) {
13110 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13111 mViSessionId, flags);
13112 mPendingAssistExtras.add(pae);
13113 mUiHandler.postDelayed(pae, timeout);
13114 } catch (RemoteException e) {
13115 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13122 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13123 IResultReceiver receiver;
13124 synchronized (this) {
13125 mPendingAssistExtras.remove(pae);
13126 receiver = pae.receiver;
13128 if (receiver != null) {
13129 // Caller wants result sent back to them.
13130 Bundle sendBundle = new Bundle();
13131 // At least return the receiver extras
13132 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13133 pae.receiverExtras);
13135 pae.receiver.send(0, sendBundle);
13136 } catch (RemoteException e) {
13141 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13142 if (result != null) {
13143 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13145 if (pae.hint != null) {
13146 pae.extras.putBoolean(pae.hint, true);
13150 /** Called from an app when assist data is ready. */
13152 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13153 AssistContent content, Uri referrer) {
13154 PendingAssistExtras pae = (PendingAssistExtras)token;
13155 synchronized (pae) {
13156 pae.result = extras;
13157 pae.structure = structure;
13158 pae.content = content;
13159 if (referrer != null) {
13160 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13162 if (structure != null) {
13163 structure.setHomeActivity(pae.isHome);
13165 pae.haveResult = true;
13167 if (pae.intent == null && pae.receiver == null) {
13168 // Caller is just waiting for the result.
13173 // We are now ready to launch the assist activity.
13174 IResultReceiver sendReceiver = null;
13175 Bundle sendBundle = null;
13176 synchronized (this) {
13177 buildAssistBundleLocked(pae, extras);
13178 boolean exists = mPendingAssistExtras.remove(pae);
13179 mUiHandler.removeCallbacks(pae);
13184 if ((sendReceiver=pae.receiver) != null) {
13185 // Caller wants result sent back to them.
13186 sendBundle = new Bundle();
13187 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13188 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13189 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13190 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13191 pae.receiverExtras);
13194 if (sendReceiver != null) {
13196 sendReceiver.send(0, sendBundle);
13197 } catch (RemoteException e) {
13202 long ident = Binder.clearCallingIdentity();
13204 pae.intent.replaceExtras(pae.extras);
13205 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13206 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13207 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13208 closeSystemDialogs("assist");
13210 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13211 } catch (ActivityNotFoundException e) {
13212 Slog.w(TAG, "No activity to handle assist action.", e);
13215 Binder.restoreCallingIdentity(ident);
13219 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13221 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13222 true /* focused */, true /* newSessionId */, userHandle, args,
13223 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13226 public void registerProcessObserver(IProcessObserver observer) {
13227 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13228 "registerProcessObserver()");
13229 synchronized (this) {
13230 mProcessObservers.register(observer);
13235 public void unregisterProcessObserver(IProcessObserver observer) {
13236 synchronized (this) {
13237 mProcessObservers.unregister(observer);
13242 public int getUidProcessState(int uid, String callingPackage) {
13243 if (!hasUsageStatsPermission(callingPackage)) {
13244 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13245 "getUidProcessState");
13248 synchronized (this) {
13249 UidRecord uidRec = mActiveUids.get(uid);
13250 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13255 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13256 String callingPackage) {
13257 if (!hasUsageStatsPermission(callingPackage)) {
13258 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13259 "registerUidObserver");
13261 synchronized (this) {
13262 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13263 callingPackage, which, cutpoint));
13268 public void unregisterUidObserver(IUidObserver observer) {
13269 synchronized (this) {
13270 mUidObservers.unregister(observer);
13275 public boolean convertFromTranslucent(IBinder token) {
13276 final long origId = Binder.clearCallingIdentity();
13278 synchronized (this) {
13279 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13283 final boolean translucentChanged = r.changeWindowTranslucency(true);
13284 if (translucentChanged) {
13285 r.getStack().releaseBackgroundResources(r);
13286 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13288 mWindowManager.setAppFullscreen(token, true);
13289 return translucentChanged;
13292 Binder.restoreCallingIdentity(origId);
13297 public boolean convertToTranslucent(IBinder token, Bundle options) {
13298 final long origId = Binder.clearCallingIdentity();
13300 synchronized (this) {
13301 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13305 final TaskRecord task = r.getTask();
13306 int index = task.mActivities.lastIndexOf(r);
13308 ActivityRecord under = task.mActivities.get(index - 1);
13309 under.returningOptions = ActivityOptions.fromBundle(options);
13311 final boolean translucentChanged = r.changeWindowTranslucency(false);
13312 if (translucentChanged) {
13313 r.getStack().convertActivityToTranslucent(r);
13315 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13316 mWindowManager.setAppFullscreen(token, false);
13317 return translucentChanged;
13320 Binder.restoreCallingIdentity(origId);
13325 public boolean requestVisibleBehind(IBinder token, boolean visible) {
13326 final long origId = Binder.clearCallingIdentity();
13328 synchronized (this) {
13329 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13331 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13336 Binder.restoreCallingIdentity(origId);
13341 public boolean isBackgroundVisibleBehind(IBinder token) {
13342 final long origId = Binder.clearCallingIdentity();
13344 synchronized (this) {
13345 final ActivityStack stack = ActivityRecord.getStackLocked(token);
13346 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13347 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13348 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13352 Binder.restoreCallingIdentity(origId);
13357 public Bundle getActivityOptions(IBinder token) {
13358 final long origId = Binder.clearCallingIdentity();
13360 synchronized (this) {
13361 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13363 final ActivityOptions activityOptions = r.pendingOptions;
13364 r.pendingOptions = null;
13365 return activityOptions == null ? null : activityOptions.toBundle();
13370 Binder.restoreCallingIdentity(origId);
13375 public void setImmersive(IBinder token, boolean immersive) {
13376 synchronized(this) {
13377 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13379 throw new IllegalArgumentException();
13381 r.immersive = immersive;
13383 // update associated state if we're frontmost
13384 if (r == mStackSupervisor.getResumedActivityLocked()) {
13385 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13386 applyUpdateLockStateLocked(r);
13392 public boolean isImmersive(IBinder token) {
13393 synchronized (this) {
13394 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13396 throw new IllegalArgumentException();
13398 return r.immersive;
13403 public void setVrThread(int tid) {
13404 enforceSystemHasVrFeature();
13405 synchronized (this) {
13406 synchronized (mPidsSelfLocked) {
13407 final int pid = Binder.getCallingPid();
13408 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13409 mVrController.setVrThreadLocked(tid, pid, proc);
13415 public void setPersistentVrThread(int tid) {
13416 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13417 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13418 + Binder.getCallingPid()
13419 + ", uid=" + Binder.getCallingUid()
13420 + " requires " + permission.RESTRICTED_VR_ACCESS;
13422 throw new SecurityException(msg);
13424 enforceSystemHasVrFeature();
13425 synchronized (this) {
13426 synchronized (mPidsSelfLocked) {
13427 final int pid = Binder.getCallingPid();
13428 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13429 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13435 * Schedule the given thread a normal scheduling priority.
13437 * @param newTid the tid of the thread to adjust the scheduling of.
13438 * @param suppressLogs {@code true} if any error logging should be disabled.
13440 * @return {@code true} if this succeeded.
13442 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13444 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13446 } catch (IllegalArgumentException e) {
13447 if (!suppressLogs) {
13448 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13455 * Schedule the given thread an FIFO scheduling priority.
13457 * @param newTid the tid of the thread to adjust the scheduling of.
13458 * @param suppressLogs {@code true} if any error logging should be disabled.
13460 * @return {@code true} if this succeeded.
13462 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13464 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13466 } catch (IllegalArgumentException e) {
13467 if (!suppressLogs) {
13468 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13475 * Check that we have the features required for VR-related API calls, and throw an exception if
13478 private void enforceSystemHasVrFeature() {
13479 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13480 throw new UnsupportedOperationException("VR mode not supported on this device!");
13485 public void setRenderThread(int tid) {
13486 synchronized (this) {
13487 ProcessRecord proc;
13488 int pid = Binder.getCallingPid();
13489 if (pid == Process.myPid()) {
13490 demoteSystemServerRenderThread(tid);
13493 synchronized (mPidsSelfLocked) {
13494 proc = mPidsSelfLocked.get(pid);
13495 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13496 // ensure the tid belongs to the process
13497 if (!isThreadInProcess(pid, tid)) {
13498 throw new IllegalArgumentException(
13499 "Render thread does not belong to process");
13501 proc.renderThreadTid = tid;
13502 if (DEBUG_OOM_ADJ) {
13503 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13505 // promote to FIFO now
13506 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13507 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13508 if (mUseFifoUiScheduling) {
13509 setThreadScheduler(proc.renderThreadTid,
13510 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13512 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13516 if (DEBUG_OOM_ADJ) {
13517 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13518 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13519 mUseFifoUiScheduling);
13527 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13528 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13530 * @param tid the tid of the RenderThread
13532 private void demoteSystemServerRenderThread(int tid) {
13533 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13537 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13538 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13539 throw new UnsupportedOperationException("VR mode not supported on this device!");
13542 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13545 synchronized (this) {
13546 r = ActivityRecord.isInStackLocked(token);
13550 throw new IllegalArgumentException();
13554 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13555 VrManagerInternal.NO_ERROR) {
13559 synchronized(this) {
13560 r.requestedVrComponent = (enabled) ? packageName : null;
13562 // Update associated state if this activity is currently focused
13563 if (r == mStackSupervisor.getResumedActivityLocked()) {
13564 applyUpdateVrModeLocked(r);
13571 public boolean isVrModePackageEnabled(ComponentName packageName) {
13572 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13573 throw new UnsupportedOperationException("VR mode not supported on this device!");
13576 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13578 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13579 VrManagerInternal.NO_ERROR;
13582 public boolean isTopActivityImmersive() {
13583 enforceNotIsolatedCaller("startActivity");
13584 synchronized (this) {
13585 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13586 return (r != null) ? r.immersive : false;
13591 * @return whether the system should disable UI modes incompatible with VR mode.
13593 boolean shouldDisableNonVrUiLocked() {
13594 return mVrController.shouldDisableNonVrUiLocked();
13598 public boolean isTopOfTask(IBinder token) {
13599 synchronized (this) {
13600 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13602 throw new IllegalArgumentException();
13604 return r.getTask().getTopActivity() == r;
13609 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13610 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13611 String msg = "Permission Denial: setHasTopUi() from pid="
13612 + Binder.getCallingPid()
13613 + ", uid=" + Binder.getCallingUid()
13614 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13616 throw new SecurityException(msg);
13618 final int pid = Binder.getCallingPid();
13619 final long origId = Binder.clearCallingIdentity();
13621 synchronized (this) {
13622 boolean changed = false;
13624 synchronized (mPidsSelfLocked) {
13625 pr = mPidsSelfLocked.get(pid);
13627 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13630 if (pr.hasTopUi != hasTopUi) {
13631 if (DEBUG_OOM_ADJ) {
13632 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13634 pr.hasTopUi = hasTopUi;
13639 updateOomAdjLocked(pr, true);
13643 Binder.restoreCallingIdentity(origId);
13647 public final void enterSafeMode() {
13648 synchronized(this) {
13649 // It only makes sense to do this before the system is ready
13650 // and started launching other packages.
13651 if (!mSystemReady) {
13653 AppGlobals.getPackageManager().enterSafeMode();
13654 } catch (RemoteException e) {
13662 public final void showSafeModeOverlay() {
13663 View v = LayoutInflater.from(mContext).inflate(
13664 com.android.internal.R.layout.safe_mode, null);
13665 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13666 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13667 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13668 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13669 lp.gravity = Gravity.BOTTOM | Gravity.START;
13670 lp.format = v.getBackground().getOpacity();
13671 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13672 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13673 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13674 ((WindowManager)mContext.getSystemService(
13675 Context.WINDOW_SERVICE)).addView(v, lp);
13678 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13679 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13682 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13683 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13684 synchronized (stats) {
13685 if (mBatteryStatsService.isOnBattery()) {
13686 mBatteryStatsService.enforceCallingPermission();
13687 int MY_UID = Binder.getCallingUid();
13689 if (sender == null) {
13692 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13694 BatteryStatsImpl.Uid.Pkg pkg =
13695 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13696 sourcePkg != null ? sourcePkg : rec.key.packageName);
13697 pkg.noteWakeupAlarmLocked(tag);
13702 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13703 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13706 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13707 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13708 synchronized (stats) {
13709 mBatteryStatsService.enforceCallingPermission();
13710 int MY_UID = Binder.getCallingUid();
13712 if (sender == null) {
13715 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13717 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13721 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13722 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13725 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13726 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13727 synchronized (stats) {
13728 mBatteryStatsService.enforceCallingPermission();
13729 int MY_UID = Binder.getCallingUid();
13731 if (sender == null) {
13734 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13736 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13740 public boolean killPids(int[] pids, String pReason, boolean secure) {
13741 if (Binder.getCallingUid() != SYSTEM_UID) {
13742 throw new SecurityException("killPids only available to the system");
13744 String reason = (pReason == null) ? "Unknown" : pReason;
13745 // XXX Note: don't acquire main activity lock here, because the window
13746 // manager calls in with its locks held.
13748 boolean killed = false;
13749 synchronized (mPidsSelfLocked) {
13751 for (int i=0; i<pids.length; i++) {
13752 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13753 if (proc != null) {
13754 int type = proc.setAdj;
13755 if (type > worstType) {
13761 // If the worst oom_adj is somewhere in the cached proc LRU range,
13762 // then constrain it so we will kill all cached procs.
13763 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13764 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13765 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13768 // If this is not a secure call, don't let it kill processes that
13770 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13771 worstType = ProcessList.SERVICE_ADJ;
13774 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13775 for (int i=0; i<pids.length; i++) {
13776 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13777 if (proc == null) {
13780 int adj = proc.setAdj;
13781 if (adj >= worstType && !proc.killedByAm) {
13782 proc.kill(reason, true);
13791 public void killUid(int appId, int userId, String reason) {
13792 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13793 synchronized (this) {
13794 final long identity = Binder.clearCallingIdentity();
13796 killPackageProcessesLocked(null, appId, userId,
13797 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13798 reason != null ? reason : "kill uid");
13800 Binder.restoreCallingIdentity(identity);
13806 public boolean killProcessesBelowForeground(String reason) {
13807 if (Binder.getCallingUid() != SYSTEM_UID) {
13808 throw new SecurityException("killProcessesBelowForeground() only available to system");
13811 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13814 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13815 if (Binder.getCallingUid() != SYSTEM_UID) {
13816 throw new SecurityException("killProcessesBelowAdj() only available to system");
13819 boolean killed = false;
13820 synchronized (mPidsSelfLocked) {
13821 final int size = mPidsSelfLocked.size();
13822 for (int i = 0; i < size; i++) {
13823 final int pid = mPidsSelfLocked.keyAt(i);
13824 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13825 if (proc == null) continue;
13827 final int adj = proc.setAdj;
13828 if (adj > belowAdj && !proc.killedByAm) {
13829 proc.kill(reason, true);
13838 public void hang(final IBinder who, boolean allowRestart) {
13839 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13840 != PackageManager.PERMISSION_GRANTED) {
13841 throw new SecurityException("Requires permission "
13842 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13845 final IBinder.DeathRecipient death = new DeathRecipient() {
13847 public void binderDied() {
13848 synchronized (this) {
13855 who.linkToDeath(death, 0);
13856 } catch (RemoteException e) {
13857 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13861 synchronized (this) {
13862 Watchdog.getInstance().setAllowRestart(allowRestart);
13863 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13864 synchronized (death) {
13865 while (who.isBinderAlive()) {
13868 } catch (InterruptedException e) {
13872 Watchdog.getInstance().setAllowRestart(true);
13877 public void restart() {
13878 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13879 != PackageManager.PERMISSION_GRANTED) {
13880 throw new SecurityException("Requires permission "
13881 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13884 Log.i(TAG, "Sending shutdown broadcast...");
13886 BroadcastReceiver br = new BroadcastReceiver() {
13887 @Override public void onReceive(Context context, Intent intent) {
13888 // Now the broadcast is done, finish up the low-level shutdown.
13889 Log.i(TAG, "Shutting down activity manager...");
13891 Log.i(TAG, "Shutdown complete, restarting!");
13892 killProcess(myPid());
13897 // First send the high-level shut down broadcast.
13898 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13899 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13900 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13901 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13902 mContext.sendOrderedBroadcastAsUser(intent,
13903 UserHandle.ALL, null, br, mHandler, 0, null, null);
13905 br.onReceive(mContext, intent);
13908 private long getLowRamTimeSinceIdle(long now) {
13909 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13913 public void performIdleMaintenance() {
13914 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13915 != PackageManager.PERMISSION_GRANTED) {
13916 throw new SecurityException("Requires permission "
13917 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13920 synchronized (this) {
13921 final long now = SystemClock.uptimeMillis();
13922 final long timeSinceLastIdle = now - mLastIdleTime;
13923 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13924 mLastIdleTime = now;
13925 mLowRamTimeSinceLastIdle = 0;
13926 if (mLowRamStartTime != 0) {
13927 mLowRamStartTime = now;
13930 StringBuilder sb = new StringBuilder(128);
13931 sb.append("Idle maintenance over ");
13932 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13933 sb.append(" low RAM for ");
13934 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13935 Slog.i(TAG, sb.toString());
13937 // If at least 1/3 of our time since the last idle period has been spent
13938 // with RAM low, then we want to kill processes.
13939 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13941 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13942 ProcessRecord proc = mLruProcesses.get(i);
13943 if (proc.notCachedSinceIdle) {
13944 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13945 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13946 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13947 if (doKilling && proc.initialIdlePss != 0
13948 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13949 sb = new StringBuilder(128);
13951 sb.append(proc.processName);
13952 sb.append(" in idle maint: pss=");
13953 sb.append(proc.lastPss);
13954 sb.append(", swapPss=");
13955 sb.append(proc.lastSwapPss);
13956 sb.append(", initialPss=");
13957 sb.append(proc.initialIdlePss);
13958 sb.append(", period=");
13959 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13960 sb.append(", lowRamPeriod=");
13961 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13962 Slog.wtfQuiet(TAG, sb.toString());
13963 proc.kill("idle maint (pss " + proc.lastPss
13964 + " from " + proc.initialIdlePss + ")", true);
13967 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13968 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13969 proc.notCachedSinceIdle = true;
13970 proc.initialIdlePss = 0;
13971 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13972 mTestPssMode, isSleepingLocked(), now);
13976 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13977 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13982 public void sendIdleJobTrigger() {
13983 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13984 != PackageManager.PERMISSION_GRANTED) {
13985 throw new SecurityException("Requires permission "
13986 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13989 final long ident = Binder.clearCallingIdentity();
13991 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13992 .setPackage("android")
13993 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13994 broadcastIntent(null, intent, null, null, 0, null, null, null,
13995 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13997 Binder.restoreCallingIdentity(ident);
14001 private void retrieveSettings() {
14002 final ContentResolver resolver = mContext.getContentResolver();
14003 final boolean freeformWindowManagement =
14004 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14005 || Settings.Global.getInt(
14006 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14007 final boolean supportsPictureInPicture =
14008 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14010 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14011 final boolean supportsSplitScreenMultiWindow =
14012 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14013 final boolean supportsMultiDisplay = mContext.getPackageManager()
14014 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14015 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14016 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14017 final boolean alwaysFinishActivities =
14018 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14019 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14020 final boolean forceResizable = Settings.Global.getInt(
14021 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14022 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14023 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14024 final boolean supportsLeanbackOnly =
14025 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14027 // Transfer any global setting for forcing RTL layout, into a System Property
14028 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14030 final Configuration configuration = new Configuration();
14031 Settings.System.getConfiguration(resolver, configuration);
14033 // This will take care of setting the correct layout direction flags
14034 configuration.setLayoutDirection(configuration.locale);
14037 synchronized (this) {
14038 mDebugApp = mOrigDebugApp = debugApp;
14039 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14040 mAlwaysFinishActivities = alwaysFinishActivities;
14041 mSupportsLeanbackOnly = supportsLeanbackOnly;
14042 mForceResizableActivities = forceResizable;
14043 final boolean multiWindowFormEnabled = freeformWindowManagement
14044 || supportsSplitScreenMultiWindow
14045 || supportsPictureInPicture
14046 || supportsMultiDisplay;
14047 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14048 mSupportsMultiWindow = true;
14049 mSupportsFreeformWindowManagement = freeformWindowManagement;
14050 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14051 mSupportsPictureInPicture = supportsPictureInPicture;
14052 mSupportsMultiDisplay = supportsMultiDisplay;
14054 mSupportsMultiWindow = false;
14055 mSupportsFreeformWindowManagement = false;
14056 mSupportsSplitScreenMultiWindow = false;
14057 mSupportsPictureInPicture = false;
14058 mSupportsMultiDisplay = false;
14060 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14061 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14062 // This happens before any activities are started, so we can change global configuration
14064 updateConfigurationLocked(configuration, null, true);
14065 final Configuration globalConfig = getGlobalConfiguration();
14066 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14068 // Load resources only after the current configuration has been set.
14069 final Resources res = mContext.getResources();
14070 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14071 mThumbnailWidth = res.getDimensionPixelSize(
14072 com.android.internal.R.dimen.thumbnail_width);
14073 mThumbnailHeight = res.getDimensionPixelSize(
14074 com.android.internal.R.dimen.thumbnail_height);
14075 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14076 com.android.internal.R.string.config_appsNotReportingCrashes));
14077 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14078 com.android.internal.R.bool.config_customUserSwitchUi);
14079 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14080 mFullscreenThumbnailScale = (float) res
14081 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14082 (float) globalConfig.screenWidthDp;
14084 mFullscreenThumbnailScale = res.getFraction(
14085 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14087 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14091 public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14092 traceLog.traceBegin("PhaseActivityManagerReady");
14093 synchronized(this) {
14094 if (mSystemReady) {
14095 // If we're done calling all the receivers, run the next "boot phase" passed in
14096 // by the SystemServer
14097 if (goingCallback != null) {
14098 goingCallback.run();
14103 mLocalDeviceIdleController
14104 = LocalServices.getService(DeviceIdleController.LocalService.class);
14105 mAssistUtils = new AssistUtils(mContext);
14106 mVrController.onSystemReady();
14107 // Make sure we have the current profile info, since it is needed for security checks.
14108 mUserController.onSystemReady();
14109 mRecentTasks.onSystemReadyLocked();
14110 mAppOpsService.systemReady();
14111 mSystemReady = true;
14114 ArrayList<ProcessRecord> procsToKill = null;
14115 synchronized(mPidsSelfLocked) {
14116 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14117 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14118 if (!isAllowedWhileBooting(proc.info)){
14119 if (procsToKill == null) {
14120 procsToKill = new ArrayList<ProcessRecord>();
14122 procsToKill.add(proc);
14127 synchronized(this) {
14128 if (procsToKill != null) {
14129 for (int i=procsToKill.size()-1; i>=0; i--) {
14130 ProcessRecord proc = procsToKill.get(i);
14131 Slog.i(TAG, "Removing system update proc: " + proc);
14132 removeProcessLocked(proc, true, false, "system update done");
14136 // Now that we have cleaned up any update processes, we
14137 // are ready to start launching real processes and know that
14138 // we won't trample on them any more.
14139 mProcessesReady = true;
14142 Slog.i(TAG, "System now ready");
14143 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14144 SystemClock.uptimeMillis());
14146 synchronized(this) {
14147 // Make sure we have no pre-ready processes sitting around.
14149 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14150 ResolveInfo ri = mContext.getPackageManager()
14151 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14153 CharSequence errorMsg = null;
14155 ActivityInfo ai = ri.activityInfo;
14156 ApplicationInfo app = ai.applicationInfo;
14157 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14158 mTopAction = Intent.ACTION_FACTORY_TEST;
14160 mTopComponent = new ComponentName(app.packageName,
14163 errorMsg = mContext.getResources().getText(
14164 com.android.internal.R.string.factorytest_not_system);
14167 errorMsg = mContext.getResources().getText(
14168 com.android.internal.R.string.factorytest_no_action);
14170 if (errorMsg != null) {
14173 mTopComponent = null;
14174 Message msg = Message.obtain();
14175 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14176 msg.getData().putCharSequence("msg", errorMsg);
14177 mUiHandler.sendMessage(msg);
14182 retrieveSettings();
14183 final int currentUserId;
14184 synchronized (this) {
14185 currentUserId = mUserController.getCurrentUserIdLocked();
14186 readGrantedUriPermissionsLocked();
14189 if (goingCallback != null) goingCallback.run();
14190 traceLog.traceBegin("ActivityManagerStartApps");
14191 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14192 Integer.toString(currentUserId), currentUserId);
14193 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14194 Integer.toString(currentUserId), currentUserId);
14195 mSystemServiceManager.startUser(currentUserId);
14197 synchronized (this) {
14198 // Only start up encryption-aware persistent apps; once user is
14199 // unlocked we'll come back around and start unaware apps
14200 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14202 // Start up initial activity.
14204 // Enable home activity for system user, so that the system can always boot. We don't
14205 // do this when the system user is not setup since the setup wizard should be the one
14206 // to handle home activity in this case.
14207 if (UserManager.isSplitSystemUser() &&
14208 Settings.Secure.getInt(mContext.getContentResolver(),
14209 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14210 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14212 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14213 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14214 UserHandle.USER_SYSTEM);
14215 } catch (RemoteException e) {
14216 throw e.rethrowAsRuntimeException();
14219 startHomeActivityLocked(currentUserId, "systemReady");
14222 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14223 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14224 + " data partition or your device will be unstable.");
14225 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14227 } catch (RemoteException e) {
14230 if (!Build.isBuildConsistent()) {
14231 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14232 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14235 long ident = Binder.clearCallingIdentity();
14237 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14238 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14239 | Intent.FLAG_RECEIVER_FOREGROUND);
14240 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14241 broadcastIntentLocked(null, null, intent,
14242 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14243 null, false, false, MY_PID, SYSTEM_UID,
14245 intent = new Intent(Intent.ACTION_USER_STARTING);
14246 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14247 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14248 broadcastIntentLocked(null, null, intent,
14249 null, new IIntentReceiver.Stub() {
14251 public void performReceive(Intent intent, int resultCode, String data,
14252 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14253 throws RemoteException {
14256 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14257 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14258 } catch (Throwable t) {
14259 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14261 Binder.restoreCallingIdentity(ident);
14263 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14264 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14265 traceLog.traceEnd(); // ActivityManagerStartApps
14266 traceLog.traceEnd(); // PhaseActivityManagerReady
14270 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14271 synchronized (this) {
14272 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14276 void skipCurrentReceiverLocked(ProcessRecord app) {
14277 for (BroadcastQueue queue : mBroadcastQueues) {
14278 queue.skipCurrentReceiverLocked(app);
14283 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14284 * The application process will exit immediately after this call returns.
14285 * @param app object of the crashing app, null for the system server
14286 * @param crashInfo describing the exception
14288 public void handleApplicationCrash(IBinder app,
14289 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14290 ProcessRecord r = findAppProcess(app, "Crash");
14291 final String processName = app == null ? "system_server"
14292 : (r == null ? "unknown" : r.processName);
14294 handleApplicationCrashInner("crash", r, processName, crashInfo);
14297 /* Native crash reporting uses this inner version because it needs to be somewhat
14298 * decoupled from the AM-managed cleanup lifecycle
14300 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14301 ApplicationErrorReport.CrashInfo crashInfo) {
14302 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14303 UserHandle.getUserId(Binder.getCallingUid()), processName,
14304 r == null ? -1 : r.info.flags,
14305 crashInfo.exceptionClassName,
14306 crashInfo.exceptionMessage,
14307 crashInfo.throwFileName,
14308 crashInfo.throwLineNumber);
14310 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14312 mAppErrors.crashApplication(r, crashInfo);
14315 public void handleApplicationStrictModeViolation(
14318 StrictMode.ViolationInfo info) {
14319 ProcessRecord r = findAppProcess(app, "StrictMode");
14324 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14325 Integer stackFingerprint = info.hashCode();
14326 boolean logIt = true;
14327 synchronized (mAlreadyLoggedViolatedStacks) {
14328 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14330 // TODO: sub-sample into EventLog for these, with
14331 // the info.durationMillis? Then we'd get
14332 // the relative pain numbers, without logging all
14333 // the stack traces repeatedly. We'd want to do
14334 // likewise in the client code, which also does
14335 // dup suppression, before the Binder call.
14337 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14338 mAlreadyLoggedViolatedStacks.clear();
14340 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14344 logStrictModeViolationToDropBox(r, info);
14348 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14349 AppErrorResult result = new AppErrorResult();
14350 synchronized (this) {
14351 final long origId = Binder.clearCallingIdentity();
14353 Message msg = Message.obtain();
14354 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14355 HashMap<String, Object> data = new HashMap<String, Object>();
14356 data.put("result", result);
14357 data.put("app", r);
14358 data.put("violationMask", violationMask);
14359 data.put("info", info);
14361 mUiHandler.sendMessage(msg);
14363 Binder.restoreCallingIdentity(origId);
14365 int res = result.get();
14366 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14370 // Depending on the policy in effect, there could be a bunch of
14371 // these in quick succession so we try to batch these together to
14372 // minimize disk writes, number of dropbox entries, and maximize
14373 // compression, by having more fewer, larger records.
14374 private void logStrictModeViolationToDropBox(
14375 ProcessRecord process,
14376 StrictMode.ViolationInfo info) {
14377 if (info == null) {
14380 final boolean isSystemApp = process == null ||
14381 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14382 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14383 final String processName = process == null ? "unknown" : process.processName;
14384 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14385 final DropBoxManager dbox = (DropBoxManager)
14386 mContext.getSystemService(Context.DROPBOX_SERVICE);
14388 // Exit early if the dropbox isn't configured to accept this report type.
14389 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14391 boolean bufferWasEmpty;
14392 boolean needsFlush;
14393 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14394 synchronized (sb) {
14395 bufferWasEmpty = sb.length() == 0;
14396 appendDropBoxProcessHeaders(process, processName, sb);
14397 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14398 sb.append("System-App: ").append(isSystemApp).append("\n");
14399 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14400 if (info.violationNumThisLoop != 0) {
14401 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14403 if (info.numAnimationsRunning != 0) {
14404 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14406 if (info.broadcastIntentAction != null) {
14407 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14409 if (info.durationMillis != -1) {
14410 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14412 if (info.numInstances != -1) {
14413 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14415 if (info.tags != null) {
14416 for (String tag : info.tags) {
14417 sb.append("Span-Tag: ").append(tag).append("\n");
14421 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14422 sb.append(info.crashInfo.stackTrace);
14425 if (info.message != null) {
14426 sb.append(info.message);
14430 // Only buffer up to ~64k. Various logging bits truncate
14432 needsFlush = (sb.length() > 64 * 1024);
14435 // Flush immediately if the buffer's grown too large, or this
14436 // is a non-system app. Non-system apps are isolated with a
14437 // different tag & policy and not batched.
14439 // Batching is useful during internal testing with
14440 // StrictMode settings turned up high. Without batching,
14441 // thousands of separate files could be created on boot.
14442 if (!isSystemApp || needsFlush) {
14443 new Thread("Error dump: " + dropboxTag) {
14445 public void run() {
14447 synchronized (sb) {
14448 report = sb.toString();
14449 sb.delete(0, sb.length());
14452 if (report.length() != 0) {
14453 dbox.addText(dropboxTag, report);
14460 // System app batching:
14461 if (!bufferWasEmpty) {
14462 // An existing dropbox-writing thread is outstanding, so
14463 // we don't need to start it up. The existing thread will
14464 // catch the buffer appends we just did.
14468 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14469 // (After this point, we shouldn't access AMS internal data structures.)
14470 new Thread("Error dump: " + dropboxTag) {
14472 public void run() {
14473 // 5 second sleep to let stacks arrive and be batched together
14475 Thread.sleep(5000); // 5 seconds
14476 } catch (InterruptedException e) {}
14478 String errorReport;
14479 synchronized (mStrictModeBuffer) {
14480 errorReport = mStrictModeBuffer.toString();
14481 if (errorReport.length() == 0) {
14484 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14485 mStrictModeBuffer.trimToSize();
14487 dbox.addText(dropboxTag, errorReport);
14493 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14494 * @param app object of the crashing app, null for the system server
14495 * @param tag reported by the caller
14496 * @param system whether this wtf is coming from the system
14497 * @param crashInfo describing the context of the error
14498 * @return true if the process should exit immediately (WTF is fatal)
14500 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14501 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14502 final int callingUid = Binder.getCallingUid();
14503 final int callingPid = Binder.getCallingPid();
14506 // If this is coming from the system, we could very well have low-level
14507 // system locks held, so we want to do this all asynchronously. And we
14508 // never want this to become fatal, so there is that too.
14509 mHandler.post(new Runnable() {
14510 @Override public void run() {
14511 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14517 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14520 final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14521 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14522 final boolean isSystem = (r == null) || r.persistent;
14524 if (isFatal && !isSystem) {
14525 mAppErrors.crashApplication(r, crashInfo);
14532 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14533 final ApplicationErrorReport.CrashInfo crashInfo) {
14534 final ProcessRecord r = findAppProcess(app, "WTF");
14535 final String processName = app == null ? "system_server"
14536 : (r == null ? "unknown" : r.processName);
14538 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14539 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14541 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14547 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14548 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14550 private ProcessRecord findAppProcess(IBinder app, String reason) {
14555 synchronized (this) {
14556 final int NP = mProcessNames.getMap().size();
14557 for (int ip=0; ip<NP; ip++) {
14558 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14559 final int NA = apps.size();
14560 for (int ia=0; ia<NA; ia++) {
14561 ProcessRecord p = apps.valueAt(ia);
14562 if (p.thread != null && p.thread.asBinder() == app) {
14568 Slog.w(TAG, "Can't find mystery application for " + reason
14569 + " from pid=" + Binder.getCallingPid()
14570 + " uid=" + Binder.getCallingUid() + ": " + app);
14576 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14577 * to append various headers to the dropbox log text.
14579 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14580 StringBuilder sb) {
14581 // Watchdog thread ends up invoking this function (with
14582 // a null ProcessRecord) to add the stack file to dropbox.
14583 // Do not acquire a lock on this (am) in such cases, as it
14584 // could cause a potential deadlock, if and when watchdog
14585 // is invoked due to unavailability of lock on am and it
14586 // would prevent watchdog from killing system_server.
14587 if (process == null) {
14588 sb.append("Process: ").append(processName).append("\n");
14591 // Note: ProcessRecord 'process' is guarded by the service
14592 // instance. (notably process.pkgList, which could otherwise change
14593 // concurrently during execution of this method)
14594 synchronized (this) {
14595 sb.append("Process: ").append(processName).append("\n");
14596 sb.append("PID: ").append(process.pid).append("\n");
14597 int flags = process.info.flags;
14598 IPackageManager pm = AppGlobals.getPackageManager();
14599 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14600 for (int ip=0; ip<process.pkgList.size(); ip++) {
14601 String pkg = process.pkgList.keyAt(ip);
14602 sb.append("Package: ").append(pkg);
14604 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14606 sb.append(" v").append(pi.versionCode);
14607 if (pi.versionName != null) {
14608 sb.append(" (").append(pi.versionName).append(")");
14611 } catch (RemoteException e) {
14612 Slog.e(TAG, "Error getting package info: " + pkg, e);
14619 private static String processClass(ProcessRecord process) {
14620 if (process == null || process.pid == MY_PID) {
14621 return "system_server";
14622 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14623 return "system_app";
14629 private volatile long mWtfClusterStart;
14630 private volatile int mWtfClusterCount;
14633 * Write a description of an error (crash, WTF, ANR) to the drop box.
14634 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14635 * @param process which caused the error, null means the system server
14636 * @param activity which triggered the error, null if unknown
14637 * @param parent activity related to the error, null if unknown
14638 * @param subject line related to the error, null if absent
14639 * @param report in long form describing the error, null if absent
14640 * @param dataFile text file to include in the report, null if none
14641 * @param crashInfo giving an application stack trace, null if absent
14643 public void addErrorToDropBox(String eventType,
14644 ProcessRecord process, String processName, ActivityRecord activity,
14645 ActivityRecord parent, String subject,
14646 final String report, final File dataFile,
14647 final ApplicationErrorReport.CrashInfo crashInfo) {
14648 // NOTE -- this must never acquire the ActivityManagerService lock,
14649 // otherwise the watchdog may be prevented from resetting the system.
14651 // Bail early if not published yet
14652 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14653 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14655 // Exit early if the dropbox isn't configured to accept this report type.
14656 final String dropboxTag = processClass(process) + "_" + eventType;
14657 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14659 // Rate-limit how often we're willing to do the heavy lifting below to
14660 // collect and record logs; currently 5 logs per 10 second period.
14661 final long now = SystemClock.elapsedRealtime();
14662 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14663 mWtfClusterStart = now;
14664 mWtfClusterCount = 1;
14666 if (mWtfClusterCount++ >= 5) return;
14669 final StringBuilder sb = new StringBuilder(1024);
14670 appendDropBoxProcessHeaders(process, processName, sb);
14671 if (process != null) {
14672 sb.append("Foreground: ")
14673 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14676 if (activity != null) {
14677 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14679 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14680 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14682 if (parent != null && parent != activity) {
14683 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14685 if (subject != null) {
14686 sb.append("Subject: ").append(subject).append("\n");
14688 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14689 if (Debug.isDebuggerConnected()) {
14690 sb.append("Debugger: Connected\n");
14694 // Do the rest in a worker thread to avoid blocking the caller on I/O
14695 // (After this point, we shouldn't access AMS internal data structures.)
14696 Thread worker = new Thread("Error dump: " + dropboxTag) {
14698 public void run() {
14699 if (report != null) {
14703 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14704 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14705 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14706 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14708 if (dataFile != null && maxDataFileSize > 0) {
14710 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14711 "\n\n[[TRUNCATED]]"));
14712 } catch (IOException e) {
14713 Slog.e(TAG, "Error reading " + dataFile, e);
14716 if (crashInfo != null && crashInfo.stackTrace != null) {
14717 sb.append(crashInfo.stackTrace);
14723 // Merge several logcat streams, and take the last N lines
14724 InputStreamReader input = null;
14726 java.lang.Process logcat = new ProcessBuilder(
14727 "/system/bin/timeout", "-k", "15s", "10s",
14728 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14729 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14730 .redirectErrorStream(true).start();
14732 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14733 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14734 input = new InputStreamReader(logcat.getInputStream());
14737 char[] buf = new char[8192];
14738 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14739 } catch (IOException e) {
14740 Slog.e(TAG, "Error running logcat", e);
14742 if (input != null) try { input.close(); } catch (IOException e) {}
14746 dbox.addText(dropboxTag, sb.toString());
14750 if (process == null) {
14751 // If process is null, we are being called from some internal code
14752 // and may be about to die -- run this synchronously.
14760 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14761 enforceNotIsolatedCaller("getProcessesInErrorState");
14762 // assume our apps are happy - lazy create the list
14763 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14765 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14766 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14767 int userId = UserHandle.getUserId(Binder.getCallingUid());
14769 synchronized (this) {
14771 // iterate across all processes
14772 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14773 ProcessRecord app = mLruProcesses.get(i);
14774 if (!allUsers && app.userId != userId) {
14777 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14778 // This one's in trouble, so we'll generate a report for it
14779 // crashes are higher priority (in case there's a crash *and* an anr)
14780 ActivityManager.ProcessErrorStateInfo report = null;
14781 if (app.crashing) {
14782 report = app.crashingReport;
14783 } else if (app.notResponding) {
14784 report = app.notRespondingReport;
14787 if (report != null) {
14788 if (errList == null) {
14789 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14791 errList.add(report);
14793 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14794 " crashing = " + app.crashing +
14795 " notResponding = " + app.notResponding);
14804 static int procStateToImportance(int procState, int memAdj,
14805 ActivityManager.RunningAppProcessInfo currApp,
14806 int clientTargetSdk) {
14807 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14808 procState, clientTargetSdk);
14809 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14810 currApp.lru = memAdj;
14817 private void fillInProcMemInfo(ProcessRecord app,
14818 ActivityManager.RunningAppProcessInfo outInfo,
14819 int clientTargetSdk) {
14820 outInfo.pid = app.pid;
14821 outInfo.uid = app.info.uid;
14822 if (mHeavyWeightProcess == app) {
14823 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14825 if (app.persistent) {
14826 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14828 if (app.activities.size() > 0) {
14829 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14831 outInfo.lastTrimLevel = app.trimMemoryLevel;
14832 int adj = app.curAdj;
14833 int procState = app.curProcState;
14834 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14835 outInfo.importanceReasonCode = app.adjTypeCode;
14836 outInfo.processState = app.curProcState;
14840 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14841 enforceNotIsolatedCaller("getRunningAppProcesses");
14843 final int callingUid = Binder.getCallingUid();
14844 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14846 // Lazy instantiation of list
14847 List<ActivityManager.RunningAppProcessInfo> runList = null;
14848 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14849 callingUid) == PackageManager.PERMISSION_GRANTED;
14850 final int userId = UserHandle.getUserId(callingUid);
14851 final boolean allUids = isGetTasksAllowed(
14852 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14854 synchronized (this) {
14855 // Iterate across all processes
14856 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14857 ProcessRecord app = mLruProcesses.get(i);
14858 if ((!allUsers && app.userId != userId)
14859 || (!allUids && app.uid != callingUid)) {
14862 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14863 // Generate process state info for running application
14864 ActivityManager.RunningAppProcessInfo currApp =
14865 new ActivityManager.RunningAppProcessInfo(app.processName,
14866 app.pid, app.getPackageList());
14867 fillInProcMemInfo(app, currApp, clientTargetSdk);
14868 if (app.adjSource instanceof ProcessRecord) {
14869 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14870 currApp.importanceReasonImportance =
14871 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14872 app.adjSourceProcState);
14873 } else if (app.adjSource instanceof ActivityRecord) {
14874 ActivityRecord r = (ActivityRecord)app.adjSource;
14875 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14877 if (app.adjTarget instanceof ComponentName) {
14878 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14880 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14881 // + " lru=" + currApp.lru);
14882 if (runList == null) {
14883 runList = new ArrayList<>();
14885 runList.add(currApp);
14893 public List<ApplicationInfo> getRunningExternalApplications() {
14894 enforceNotIsolatedCaller("getRunningExternalApplications");
14895 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14896 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14897 if (runningApps != null && runningApps.size() > 0) {
14898 Set<String> extList = new HashSet<String>();
14899 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14900 if (app.pkgList != null) {
14901 for (String pkg : app.pkgList) {
14906 IPackageManager pm = AppGlobals.getPackageManager();
14907 for (String pkg : extList) {
14909 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14910 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14913 } catch (RemoteException e) {
14921 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14922 enforceNotIsolatedCaller("getMyMemoryState");
14924 final int callingUid = Binder.getCallingUid();
14925 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14927 synchronized (this) {
14928 ProcessRecord proc;
14929 synchronized (mPidsSelfLocked) {
14930 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14932 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14937 public int getMemoryTrimLevel() {
14938 enforceNotIsolatedCaller("getMyMemoryState");
14939 synchronized (this) {
14940 return mLastMemoryLevel;
14945 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14946 FileDescriptor err, String[] args, ShellCallback callback,
14947 ResultReceiver resultReceiver) {
14948 (new ActivityManagerShellCommand(this, false)).exec(
14949 this, in, out, err, args, callback, resultReceiver);
14953 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14954 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14956 boolean dumpAll = false;
14957 boolean dumpClient = false;
14958 boolean dumpCheckin = false;
14959 boolean dumpCheckinFormat = false;
14960 boolean dumpVisibleStacksOnly = false;
14961 boolean dumpFocusedStackOnly = false;
14962 String dumpPackage = null;
14965 while (opti < args.length) {
14966 String opt = args[opti];
14967 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14971 if ("-a".equals(opt)) {
14973 } else if ("-c".equals(opt)) {
14975 } else if ("-v".equals(opt)) {
14976 dumpVisibleStacksOnly = true;
14977 } else if ("-f".equals(opt)) {
14978 dumpFocusedStackOnly = true;
14979 } else if ("-p".equals(opt)) {
14980 if (opti < args.length) {
14981 dumpPackage = args[opti];
14984 pw.println("Error: -p option requires package argument");
14988 } else if ("--checkin".equals(opt)) {
14989 dumpCheckin = dumpCheckinFormat = true;
14990 } else if ("-C".equals(opt)) {
14991 dumpCheckinFormat = true;
14992 } else if ("-h".equals(opt)) {
14993 ActivityManagerShellCommand.dumpHelp(pw, true);
14996 pw.println("Unknown argument: " + opt + "; use -h for help");
15000 long origId = Binder.clearCallingIdentity();
15001 boolean more = false;
15002 // Is the caller requesting to dump a particular piece of data?
15003 if (opti < args.length) {
15004 String cmd = args[opti];
15006 if ("activities".equals(cmd) || "a".equals(cmd)) {
15007 synchronized (this) {
15008 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15010 } else if ("lastanr".equals(cmd)) {
15011 synchronized (this) {
15012 dumpLastANRLocked(pw);
15014 } else if ("starter".equals(cmd)) {
15015 synchronized (this) {
15016 dumpActivityStarterLocked(pw);
15018 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15019 synchronized (this) {
15020 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15022 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15025 if (opti >= args.length) {
15027 newArgs = EMPTY_STRING_ARRAY;
15029 dumpPackage = args[opti];
15031 newArgs = new String[args.length - opti];
15032 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15033 args.length - opti);
15035 synchronized (this) {
15036 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15038 } else if ("broadcast-stats".equals(cmd)) {
15041 if (opti >= args.length) {
15043 newArgs = EMPTY_STRING_ARRAY;
15045 dumpPackage = args[opti];
15047 newArgs = new String[args.length - opti];
15048 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15049 args.length - opti);
15051 synchronized (this) {
15052 if (dumpCheckinFormat) {
15053 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15056 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15059 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15062 if (opti >= args.length) {
15064 newArgs = EMPTY_STRING_ARRAY;
15066 dumpPackage = args[opti];
15068 newArgs = new String[args.length - opti];
15069 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15070 args.length - opti);
15072 synchronized (this) {
15073 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15075 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15078 if (opti >= args.length) {
15080 newArgs = EMPTY_STRING_ARRAY;
15082 dumpPackage = args[opti];
15084 newArgs = new String[args.length - opti];
15085 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15086 args.length - opti);
15088 synchronized (this) {
15089 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15091 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15092 synchronized (this) {
15093 dumpOomLocked(fd, pw, args, opti, true);
15095 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15096 synchronized (this) {
15097 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15099 } else if ("provider".equals(cmd)) {
15102 if (opti >= args.length) {
15104 newArgs = EMPTY_STRING_ARRAY;
15108 newArgs = new String[args.length - opti];
15109 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15111 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15112 pw.println("No providers match: " + name);
15113 pw.println("Use -h for help.");
15115 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15116 synchronized (this) {
15117 dumpProvidersLocked(fd, pw, args, opti, true, null);
15119 } else if ("service".equals(cmd)) {
15122 if (opti >= args.length) {
15124 newArgs = EMPTY_STRING_ARRAY;
15128 newArgs = new String[args.length - opti];
15129 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15130 args.length - opti);
15132 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15133 pw.println("No services match: " + name);
15134 pw.println("Use -h for help.");
15136 } else if ("package".equals(cmd)) {
15138 if (opti >= args.length) {
15139 pw.println("package: no package name specified");
15140 pw.println("Use -h for help.");
15142 dumpPackage = args[opti];
15144 newArgs = new String[args.length - opti];
15145 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15146 args.length - opti);
15151 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15152 synchronized (this) {
15153 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15155 } else if ("settings".equals(cmd)) {
15156 synchronized (this) {
15157 mConstants.dump(pw);
15159 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15161 ActiveServices.ServiceDumper dumper;
15162 synchronized (this) {
15163 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15166 dumper.dumpWithClient();
15168 synchronized (this) {
15169 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15170 dumpPackage).dumpLocked();
15173 } else if ("locks".equals(cmd)) {
15174 LockGuard.dump(fd, pw, args);
15176 // Dumping a single activity?
15177 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15178 dumpFocusedStackOnly)) {
15179 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15180 int res = shell.exec(this, null, fd, null, args, null,
15181 new ResultReceiver(null));
15183 pw.println("Bad activity command, or no activities match: " + cmd);
15184 pw.println("Use -h for help.");
15189 Binder.restoreCallingIdentity(origId);
15194 // No piece of data specified, dump everything.
15195 if (dumpCheckinFormat) {
15196 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15197 } else if (dumpClient) {
15198 ActiveServices.ServiceDumper sdumper;
15199 synchronized (this) {
15200 mConstants.dump(pw);
15203 pw.println("-------------------------------------------------------------------------------");
15205 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15208 pw.println("-------------------------------------------------------------------------------");
15210 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15213 pw.println("-------------------------------------------------------------------------------");
15215 if (dumpAll || dumpPackage != null) {
15216 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15219 pw.println("-------------------------------------------------------------------------------");
15222 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15225 pw.println("-------------------------------------------------------------------------------");
15227 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15230 pw.println("-------------------------------------------------------------------------------");
15232 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15235 sdumper.dumpWithClient();
15237 synchronized (this) {
15239 pw.println("-------------------------------------------------------------------------------");
15241 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15244 pw.println("-------------------------------------------------------------------------------");
15246 dumpLastANRLocked(pw);
15249 pw.println("-------------------------------------------------------------------------------");
15251 dumpActivityStarterLocked(pw);
15254 pw.println("-------------------------------------------------------------------------------");
15256 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15257 if (mAssociations.size() > 0) {
15260 pw.println("-------------------------------------------------------------------------------");
15262 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15266 pw.println("-------------------------------------------------------------------------------");
15268 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15272 synchronized (this) {
15273 mConstants.dump(pw);
15276 pw.println("-------------------------------------------------------------------------------");
15278 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15281 pw.println("-------------------------------------------------------------------------------");
15283 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15286 pw.println("-------------------------------------------------------------------------------");
15288 if (dumpAll || dumpPackage != null) {
15289 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15292 pw.println("-------------------------------------------------------------------------------");
15295 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15298 pw.println("-------------------------------------------------------------------------------");
15300 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15303 pw.println("-------------------------------------------------------------------------------");
15305 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15309 pw.println("-------------------------------------------------------------------------------");
15311 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15314 pw.println("-------------------------------------------------------------------------------");
15316 dumpLastANRLocked(pw);
15319 pw.println("-------------------------------------------------------------------------------");
15321 dumpActivityStarterLocked(pw);
15324 pw.println("-------------------------------------------------------------------------------");
15326 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15327 if (mAssociations.size() > 0) {
15330 pw.println("-------------------------------------------------------------------------------");
15332 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15336 pw.println("-------------------------------------------------------------------------------");
15338 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15341 Binder.restoreCallingIdentity(origId);
15344 private void dumpLastANRLocked(PrintWriter pw) {
15345 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
15346 if (mLastANRState == null) {
15347 pw.println(" <no ANR has occurred since boot>");
15349 pw.println(mLastANRState);
15353 private void dumpActivityStarterLocked(PrintWriter pw) {
15354 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
15355 mActivityStarter.dump(pw, "");
15358 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15359 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15360 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15361 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15364 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15365 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15366 pw.println(header);
15368 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15370 boolean needSep = printedAnything;
15372 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15373 mStackSupervisor.getResumedActivityLocked(),
15374 dumpPackage, needSep, " ResumedActivity: ");
15376 printedAnything = true;
15380 if (dumpPackage == null) {
15384 printedAnything = true;
15385 mStackSupervisor.dump(pw, " ");
15388 if (!printedAnything) {
15389 pw.println(" (nothing)");
15393 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15394 int opti, boolean dumpAll, String dumpPackage) {
15395 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15397 boolean printedAnything = false;
15399 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15400 boolean printedHeader = false;
15402 final int N = mRecentTasks.size();
15403 for (int i=0; i<N; i++) {
15404 TaskRecord tr = mRecentTasks.get(i);
15405 if (dumpPackage != null) {
15406 if (tr.realActivity == null ||
15407 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15411 if (!printedHeader) {
15412 pw.println(" Recent tasks:");
15413 printedHeader = true;
15414 printedAnything = true;
15416 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15419 mRecentTasks.get(i).dump(pw, " ");
15424 if (!printedAnything) {
15425 pw.println(" (nothing)");
15429 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15430 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15431 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15434 if (dumpPackage != null) {
15435 IPackageManager pm = AppGlobals.getPackageManager();
15437 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15438 } catch (RemoteException e) {
15442 boolean printedAnything = false;
15444 final long now = SystemClock.uptimeMillis();
15446 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15447 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15448 = mAssociations.valueAt(i1);
15449 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15450 SparseArray<ArrayMap<String, Association>> sourceUids
15451 = targetComponents.valueAt(i2);
15452 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15453 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15454 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15455 Association ass = sourceProcesses.valueAt(i4);
15456 if (dumpPackage != null) {
15457 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15458 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15462 printedAnything = true;
15464 pw.print(ass.mTargetProcess);
15466 UserHandle.formatUid(pw, ass.mTargetUid);
15468 pw.print(ass.mSourceProcess);
15470 UserHandle.formatUid(pw, ass.mSourceUid);
15473 pw.print(ass.mTargetComponent.flattenToShortString());
15476 long dur = ass.mTime;
15477 if (ass.mNesting > 0) {
15478 dur += now - ass.mStartTime;
15480 TimeUtils.formatDuration(dur, pw);
15482 pw.print(ass.mCount);
15483 pw.print(" times)");
15485 for (int i=0; i<ass.mStateTimes.length; i++) {
15486 long amt = ass.mStateTimes[i];
15487 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15488 amt += now - ass.mLastStateUptime;
15492 pw.print(ProcessList.makeProcStateString(
15493 i + ActivityManager.MIN_PROCESS_STATE));
15495 TimeUtils.formatDuration(amt, pw);
15496 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15502 if (ass.mNesting > 0) {
15503 pw.print(" Currently active: ");
15504 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15513 if (!printedAnything) {
15514 pw.println(" (nothing)");
15518 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15519 String header, boolean needSep) {
15520 boolean printed = false;
15521 int whichAppId = -1;
15522 if (dumpPackage != null) {
15524 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15526 whichAppId = UserHandle.getAppId(info.uid);
15527 } catch (NameNotFoundException e) {
15528 e.printStackTrace();
15531 for (int i=0; i<uids.size(); i++) {
15532 UidRecord uidRec = uids.valueAt(i);
15533 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15542 pw.println(header);
15545 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15546 pw.print(": "); pw.println(uidRec);
15551 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15552 int opti, boolean dumpAll, String dumpPackage) {
15553 boolean needSep = false;
15554 boolean printedAnything = false;
15557 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15560 final int NP = mProcessNames.getMap().size();
15561 for (int ip=0; ip<NP; ip++) {
15562 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15563 final int NA = procs.size();
15564 for (int ia=0; ia<NA; ia++) {
15565 ProcessRecord r = procs.valueAt(ia);
15566 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15570 pw.println(" All known processes:");
15572 printedAnything = true;
15574 pw.print(r.persistent ? " *PERS*" : " *APP*");
15575 pw.print(" UID "); pw.print(procs.keyAt(ia));
15576 pw.print(" "); pw.println(r);
15578 if (r.persistent) {
15585 if (mIsolatedProcesses.size() > 0) {
15586 boolean printed = false;
15587 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15588 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15589 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15596 pw.println(" Isolated process list (sorted by uid):");
15597 printedAnything = true;
15601 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15606 if (mActiveInstrumentation.size() > 0) {
15607 boolean printed = false;
15608 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15609 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15610 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15611 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15618 pw.println(" Active instrumentation:");
15619 printedAnything = true;
15623 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15629 if (mActiveUids.size() > 0) {
15630 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15631 printedAnything = needSep = true;
15635 if (mValidateUids.size() > 0) {
15636 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15637 printedAnything = needSep = true;
15642 if (mLruProcesses.size() > 0) {
15646 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15647 pw.print(" total, non-act at ");
15648 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15649 pw.print(", non-svc at ");
15650 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15652 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15654 printedAnything = true;
15657 if (dumpAll || dumpPackage != null) {
15658 synchronized (mPidsSelfLocked) {
15659 boolean printed = false;
15660 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15661 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15662 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15666 if (needSep) pw.println();
15668 pw.println(" PID mappings:");
15670 printedAnything = true;
15672 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15673 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15678 if (mImportantProcesses.size() > 0) {
15679 synchronized (mPidsSelfLocked) {
15680 boolean printed = false;
15681 for (int i = 0; i< mImportantProcesses.size(); i++) {
15682 ProcessRecord r = mPidsSelfLocked.get(
15683 mImportantProcesses.valueAt(i).pid);
15684 if (dumpPackage != null && (r == null
15685 || !r.pkgList.containsKey(dumpPackage))) {
15689 if (needSep) pw.println();
15691 pw.println(" Foreground Processes:");
15693 printedAnything = true;
15695 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15696 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15701 if (mPersistentStartingProcesses.size() > 0) {
15702 if (needSep) pw.println();
15704 printedAnything = true;
15705 pw.println(" Persisent processes that are starting:");
15706 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15707 "Starting Norm", "Restarting PERS", dumpPackage);
15710 if (mRemovedProcesses.size() > 0) {
15711 if (needSep) pw.println();
15713 printedAnything = true;
15714 pw.println(" Processes that are being removed:");
15715 dumpProcessList(pw, this, mRemovedProcesses, " ",
15716 "Removed Norm", "Removed PERS", dumpPackage);
15719 if (mProcessesOnHold.size() > 0) {
15720 if (needSep) pw.println();
15722 printedAnything = true;
15723 pw.println(" Processes that are on old until the system is ready:");
15724 dumpProcessList(pw, this, mProcessesOnHold, " ",
15725 "OnHold Norm", "OnHold PERS", dumpPackage);
15728 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15730 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15732 printedAnything = true;
15735 if (dumpPackage == null) {
15738 mUserController.dump(pw, dumpAll);
15740 if (mHomeProcess != null && (dumpPackage == null
15741 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15746 pw.println(" mHomeProcess: " + mHomeProcess);
15748 if (mPreviousProcess != null && (dumpPackage == null
15749 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15754 pw.println(" mPreviousProcess: " + mPreviousProcess);
15757 StringBuilder sb = new StringBuilder(128);
15758 sb.append(" mPreviousProcessVisibleTime: ");
15759 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15762 if (mHeavyWeightProcess != null && (dumpPackage == null
15763 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15768 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15770 if (dumpPackage == null) {
15771 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15772 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15775 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15776 if (mCompatModePackages.getPackages().size() > 0) {
15777 boolean printed = false;
15778 for (Map.Entry<String, Integer> entry
15779 : mCompatModePackages.getPackages().entrySet()) {
15780 String pkg = entry.getKey();
15781 int mode = entry.getValue();
15782 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15786 pw.println(" mScreenCompatPackages:");
15789 pw.print(" "); pw.print(pkg); pw.print(": ");
15790 pw.print(mode); pw.println();
15793 final int NI = mUidObservers.getRegisteredCallbackCount();
15794 boolean printed = false;
15795 for (int i=0; i<NI; i++) {
15796 final UidObserverRegistration reg = (UidObserverRegistration)
15797 mUidObservers.getRegisteredCallbackCookie(i);
15798 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15800 pw.println(" mUidObservers:");
15803 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15804 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15805 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15808 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15811 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15814 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15815 pw.print(" STATE");
15816 pw.print(" (cut="); pw.print(reg.cutpoint);
15820 if (reg.lastProcStates != null) {
15821 final int NJ = reg.lastProcStates.size();
15822 for (int j=0; j<NJ; j++) {
15823 pw.print(" Last ");
15824 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15825 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15830 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15831 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15832 if (mPendingTempWhitelist.size() > 0) {
15833 pw.println(" mPendingTempWhitelist:");
15834 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15835 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15837 UserHandle.formatUid(pw, ptw.targetUid);
15839 TimeUtils.formatDuration(ptw.duration, pw);
15841 pw.println(ptw.tag);
15845 if (dumpPackage == null) {
15846 pw.println(" mWakefulness="
15847 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15848 pw.println(" mSleepTokens=" + mSleepTokens);
15849 pw.println(" mSleeping=" + mSleeping);
15850 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15851 if (mRunningVoice != null) {
15852 pw.println(" mRunningVoice=" + mRunningVoice);
15853 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15856 pw.println(" mVrController=" + mVrController);
15857 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15858 || mOrigWaitForDebugger) {
15859 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15860 || dumpPackage.equals(mOrigDebugApp)) {
15865 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15866 + " mDebugTransient=" + mDebugTransient
15867 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15870 if (mCurAppTimeTracker != null) {
15871 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15873 if (mMemWatchProcesses.getMap().size() > 0) {
15874 pw.println(" Mem watch processes:");
15875 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15876 = mMemWatchProcesses.getMap();
15877 for (int i=0; i<procs.size(); i++) {
15878 final String proc = procs.keyAt(i);
15879 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15880 for (int j=0; j<uids.size(); j++) {
15885 StringBuilder sb = new StringBuilder();
15886 sb.append(" ").append(proc).append('/');
15887 UserHandle.formatUid(sb, uids.keyAt(j));
15888 Pair<Long, String> val = uids.valueAt(j);
15889 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15890 if (val.second != null) {
15891 sb.append(", report to ").append(val.second);
15893 pw.println(sb.toString());
15896 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15897 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15898 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15899 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15901 if (mTrackAllocationApp != null) {
15902 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15907 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15910 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15911 || mProfileFd != null) {
15912 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15917 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15918 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15919 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15920 + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15921 pw.println(" mProfileType=" + mProfileType);
15924 if (mNativeDebuggingApp != null) {
15925 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15930 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
15933 if (dumpPackage == null) {
15934 if (mAlwaysFinishActivities) {
15935 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15937 if (mController != null) {
15938 pw.println(" mController=" + mController
15939 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15942 pw.println(" Total persistent processes: " + numPers);
15943 pw.println(" mProcessesReady=" + mProcessesReady
15944 + " mSystemReady=" + mSystemReady
15945 + " mBooted=" + mBooted
15946 + " mFactoryTest=" + mFactoryTest);
15947 pw.println(" mBooting=" + mBooting
15948 + " mCallFinishBooting=" + mCallFinishBooting
15949 + " mBootAnimationComplete=" + mBootAnimationComplete);
15950 pw.print(" mLastPowerCheckRealtime=");
15951 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15953 pw.print(" mLastPowerCheckUptime=");
15954 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15956 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15957 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15958 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15959 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
15960 + " (" + mLruProcesses.size() + " total)"
15961 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15962 + " mNumServiceProcs=" + mNumServiceProcs
15963 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15964 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
15965 + " mLastMemoryLevel=" + mLastMemoryLevel
15966 + " mLastNumProcesses=" + mLastNumProcesses);
15967 long now = SystemClock.uptimeMillis();
15968 pw.print(" mLastIdleTime=");
15969 TimeUtils.formatDuration(now, mLastIdleTime, pw);
15970 pw.print(" mLowRamSinceLastIdle=");
15971 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15976 if (!printedAnything) {
15977 pw.println(" (nothing)");
15981 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15982 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15983 if (mProcessesToGc.size() > 0) {
15984 boolean printed = false;
15985 long now = SystemClock.uptimeMillis();
15986 for (int i=0; i<mProcessesToGc.size(); i++) {
15987 ProcessRecord proc = mProcessesToGc.get(i);
15988 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15992 if (needSep) pw.println();
15994 pw.println(" Processes that are waiting to GC:");
15997 pw.print(" Process "); pw.println(proc);
15998 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
15999 pw.print(", last gced=");
16000 pw.print(now-proc.lastRequestedGc);
16001 pw.print(" ms ago, last lowMem=");
16002 pw.print(now-proc.lastLowMemory);
16003 pw.println(" ms ago");
16010 void printOomLevel(PrintWriter pw, String name, int adj) {
16014 if (adj < 10) pw.print(' ');
16016 if (adj > -10) pw.print(' ');
16022 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16026 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16027 int opti, boolean dumpAll) {
16028 boolean needSep = false;
16030 if (mLruProcesses.size() > 0) {
16031 if (needSep) pw.println();
16033 pw.println(" OOM levels:");
16034 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16035 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16036 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16037 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16038 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16039 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16040 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16041 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16042 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16043 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16044 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16045 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16046 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16047 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16049 if (needSep) pw.println();
16050 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16051 pw.print(" total, non-act at ");
16052 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16053 pw.print(", non-svc at ");
16054 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16056 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16060 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16063 pw.println(" mHomeProcess: " + mHomeProcess);
16064 pw.println(" mPreviousProcess: " + mPreviousProcess);
16065 if (mHeavyWeightProcess != null) {
16066 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16073 * There are three ways to call this:
16074 * - no provider specified: dump all the providers
16075 * - a flattened component name that matched an existing provider was specified as the
16076 * first arg: dump that one provider
16077 * - the first arg isn't the flattened component name of an existing provider:
16078 * dump all providers whose component contains the first arg as a substring
16080 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16081 int opti, boolean dumpAll) {
16082 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16085 static class ItemMatcher {
16086 ArrayList<ComponentName> components;
16087 ArrayList<String> strings;
16088 ArrayList<Integer> objects;
16095 void build(String name) {
16096 ComponentName componentName = ComponentName.unflattenFromString(name);
16097 if (componentName != null) {
16098 if (components == null) {
16099 components = new ArrayList<ComponentName>();
16101 components.add(componentName);
16105 // Not a '/' separated full component name; maybe an object ID?
16107 objectId = Integer.parseInt(name, 16);
16108 if (objects == null) {
16109 objects = new ArrayList<Integer>();
16111 objects.add(objectId);
16113 } catch (RuntimeException e) {
16114 // Not an integer; just do string match.
16115 if (strings == null) {
16116 strings = new ArrayList<String>();
16124 int build(String[] args, int opti) {
16125 for (; opti<args.length; opti++) {
16126 String name = args[opti];
16127 if ("--".equals(name)) {
16135 boolean match(Object object, ComponentName comp) {
16139 if (components != null) {
16140 for (int i=0; i<components.size(); i++) {
16141 if (components.get(i).equals(comp)) {
16146 if (objects != null) {
16147 for (int i=0; i<objects.size(); i++) {
16148 if (System.identityHashCode(object) == objects.get(i)) {
16153 if (strings != null) {
16154 String flat = comp.flattenToString();
16155 for (int i=0; i<strings.size(); i++) {
16156 if (flat.contains(strings.get(i))) {
16166 * There are three things that cmd can be:
16167 * - a flattened component name that matches an existing activity
16168 * - the cmd arg isn't the flattened component name of an existing activity:
16169 * dump all activity whose component contains the cmd as a substring
16170 * - A hex number of the ActivityRecord object instance.
16172 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16173 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16175 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16176 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16177 ArrayList<ActivityRecord> activities;
16179 synchronized (this) {
16180 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16181 dumpFocusedStackOnly);
16184 if (activities.size() <= 0) {
16188 String[] newArgs = new String[args.length - opti];
16189 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16191 TaskRecord lastTask = null;
16192 boolean needSep = false;
16193 for (int i=activities.size()-1; i>=0; i--) {
16194 ActivityRecord r = activities.get(i);
16199 synchronized (this) {
16200 final TaskRecord task = r.getTask();
16201 if (lastTask != task) {
16203 pw.print("TASK "); pw.print(lastTask.affinity);
16204 pw.print(" id="); pw.print(lastTask.taskId);
16205 pw.print(" userId="); pw.println(lastTask.userId);
16207 lastTask.dump(pw, " ");
16211 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16217 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16218 * there is a thread associated with the activity.
16220 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16221 final ActivityRecord r, String[] args, boolean dumpAll) {
16222 String innerPrefix = prefix + " ";
16223 synchronized (this) {
16224 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16225 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16227 if (r.app != null) pw.println(r.app.pid);
16228 else pw.println("(not running)");
16230 r.dump(pw, innerPrefix);
16233 if (r.app != null && r.app.thread != null) {
16234 // flush anything that is already in the PrintWriter since the thread is going
16235 // to write to the file descriptor directly
16238 TransferPipe tp = new TransferPipe();
16240 r.app.thread.dumpActivity(tp.getWriteFd(),
16241 r.appToken, innerPrefix, args);
16246 } catch (IOException e) {
16247 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16248 } catch (RemoteException e) {
16249 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16254 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16255 int opti, boolean dumpAll, String dumpPackage) {
16256 boolean needSep = false;
16257 boolean onlyHistory = false;
16258 boolean printedAnything = false;
16260 if ("history".equals(dumpPackage)) {
16261 if (opti < args.length && "-s".equals(args[opti])) {
16264 onlyHistory = true;
16265 dumpPackage = null;
16268 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16269 if (!onlyHistory && dumpAll) {
16270 if (mRegisteredReceivers.size() > 0) {
16271 boolean printed = false;
16272 Iterator it = mRegisteredReceivers.values().iterator();
16273 while (it.hasNext()) {
16274 ReceiverList r = (ReceiverList)it.next();
16275 if (dumpPackage != null && (r.app == null ||
16276 !dumpPackage.equals(r.app.info.packageName))) {
16280 pw.println(" Registered Receivers:");
16283 printedAnything = true;
16285 pw.print(" * "); pw.println(r);
16290 if (mReceiverResolver.dump(pw, needSep ?
16291 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16292 " ", dumpPackage, false, false)) {
16294 printedAnything = true;
16298 for (BroadcastQueue q : mBroadcastQueues) {
16299 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16300 printedAnything |= needSep;
16305 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16306 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16311 printedAnything = true;
16312 pw.print(" Sticky broadcasts for user ");
16313 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16314 StringBuilder sb = new StringBuilder(128);
16315 for (Map.Entry<String, ArrayList<Intent>> ent
16316 : mStickyBroadcasts.valueAt(user).entrySet()) {
16317 pw.print(" * Sticky action "); pw.print(ent.getKey());
16320 ArrayList<Intent> intents = ent.getValue();
16321 final int N = intents.size();
16322 for (int i=0; i<N; i++) {
16324 sb.append(" Intent: ");
16325 intents.get(i).toShortString(sb, false, true, false, false);
16326 pw.println(sb.toString());
16327 Bundle bundle = intents.get(i).getExtras();
16328 if (bundle != null) {
16330 pw.println(bundle.toString());
16340 if (!onlyHistory && dumpAll) {
16342 for (BroadcastQueue queue : mBroadcastQueues) {
16343 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16344 + queue.mBroadcastsScheduled);
16346 pw.println(" mHandler:");
16347 mHandler.dump(new PrintWriterPrinter(pw), " ");
16349 printedAnything = true;
16352 if (!printedAnything) {
16353 pw.println(" (nothing)");
16357 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16358 int opti, boolean dumpAll, String dumpPackage) {
16359 if (mCurBroadcastStats == null) {
16363 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16364 final long now = SystemClock.elapsedRealtime();
16365 if (mLastBroadcastStats != null) {
16366 pw.print(" Last stats (from ");
16367 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16369 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16371 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16372 - mLastBroadcastStats.mStartUptime, pw);
16373 pw.println(" uptime):");
16374 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16375 pw.println(" (nothing)");
16379 pw.print(" Current stats (from ");
16380 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16381 pw.print(" to now, ");
16382 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16383 - mCurBroadcastStats.mStartUptime, pw);
16384 pw.println(" uptime):");
16385 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16386 pw.println(" (nothing)");
16390 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16391 int opti, boolean fullCheckin, String dumpPackage) {
16392 if (mCurBroadcastStats == null) {
16396 if (mLastBroadcastStats != null) {
16397 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16399 mLastBroadcastStats = null;
16403 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16405 mCurBroadcastStats = null;
16409 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16410 int opti, boolean dumpAll, String dumpPackage) {
16412 boolean printedAnything = false;
16414 ItemMatcher matcher = new ItemMatcher();
16415 matcher.build(args, opti);
16417 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16419 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16420 printedAnything |= needSep;
16422 if (mLaunchingProviders.size() > 0) {
16423 boolean printed = false;
16424 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16425 ContentProviderRecord r = mLaunchingProviders.get(i);
16426 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16430 if (needSep) pw.println();
16432 pw.println(" Launching content providers:");
16434 printedAnything = true;
16436 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16441 if (!printedAnything) {
16442 pw.println(" (nothing)");
16446 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16447 int opti, boolean dumpAll, String dumpPackage) {
16448 boolean needSep = false;
16449 boolean printedAnything = false;
16451 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16453 if (mGrantedUriPermissions.size() > 0) {
16454 boolean printed = false;
16456 if (dumpPackage != null) {
16458 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16459 MATCH_ANY_USER, 0);
16460 } catch (NameNotFoundException e) {
16464 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16465 int uid = mGrantedUriPermissions.keyAt(i);
16466 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16469 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16471 if (needSep) pw.println();
16473 pw.println(" Granted Uri Permissions:");
16475 printedAnything = true;
16477 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16478 for (UriPermission perm : perms.values()) {
16479 pw.print(" "); pw.println(perm);
16481 perm.dump(pw, " ");
16487 if (!printedAnything) {
16488 pw.println(" (nothing)");
16492 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16493 int opti, boolean dumpAll, String dumpPackage) {
16494 boolean printed = false;
16496 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16498 if (mIntentSenderRecords.size() > 0) {
16499 // Organize these by package name, so they are easier to read.
16500 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16501 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16502 final Iterator<WeakReference<PendingIntentRecord>> it
16503 = mIntentSenderRecords.values().iterator();
16504 while (it.hasNext()) {
16505 WeakReference<PendingIntentRecord> ref = it.next();
16506 PendingIntentRecord rec = ref != null ? ref.get() : null;
16511 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16514 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16515 if (list == null) {
16516 list = new ArrayList<>();
16517 byPackage.put(rec.key.packageName, list);
16521 for (int i = 0; i < byPackage.size(); i++) {
16522 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16524 pw.print(" * "); pw.print(byPackage.keyAt(i));
16525 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16526 for (int j = 0; j < intents.size(); j++) {
16527 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16529 intents.get(j).dump(pw, " ");
16533 if (weakRefs.size() > 0) {
16535 pw.println(" * WEAK REFS:");
16536 for (int i = 0; i < weakRefs.size(); i++) {
16537 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16543 pw.println(" (nothing)");
16547 private static final int dumpProcessList(PrintWriter pw,
16548 ActivityManagerService service, List list,
16549 String prefix, String normalLabel, String persistentLabel,
16550 String dumpPackage) {
16552 final int N = list.size()-1;
16553 for (int i=N; i>=0; i--) {
16554 ProcessRecord r = (ProcessRecord)list.get(i);
16555 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16558 pw.println(String.format("%s%s #%2d: %s",
16559 prefix, (r.persistent ? persistentLabel : normalLabel),
16561 if (r.persistent) {
16568 private static final boolean dumpProcessOomList(PrintWriter pw,
16569 ActivityManagerService service, List<ProcessRecord> origList,
16570 String prefix, String normalLabel, String persistentLabel,
16571 boolean inclDetails, String dumpPackage) {
16573 ArrayList<Pair<ProcessRecord, Integer>> list
16574 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16575 for (int i=0; i<origList.size(); i++) {
16576 ProcessRecord r = origList.get(i);
16577 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16580 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16583 if (list.size() <= 0) {
16587 Comparator<Pair<ProcessRecord, Integer>> comparator
16588 = new Comparator<Pair<ProcessRecord, Integer>>() {
16590 public int compare(Pair<ProcessRecord, Integer> object1,
16591 Pair<ProcessRecord, Integer> object2) {
16592 if (object1.first.setAdj != object2.first.setAdj) {
16593 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16595 if (object1.first.setProcState != object2.first.setProcState) {
16596 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16598 if (object1.second.intValue() != object2.second.intValue()) {
16599 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16605 Collections.sort(list, comparator);
16607 final long curRealtime = SystemClock.elapsedRealtime();
16608 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16609 final long curUptime = SystemClock.uptimeMillis();
16610 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16612 for (int i=list.size()-1; i>=0; i--) {
16613 ProcessRecord r = list.get(i).first;
16614 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16616 switch (r.setSchedGroup) {
16617 case ProcessList.SCHED_GROUP_BACKGROUND:
16620 case ProcessList.SCHED_GROUP_DEFAULT:
16623 case ProcessList.SCHED_GROUP_TOP_APP:
16631 if (r.foregroundActivities) {
16633 } else if (r.foregroundServices) {
16638 String procState = ProcessList.makeProcStateString(r.curProcState);
16640 pw.print(r.persistent ? persistentLabel : normalLabel);
16642 int num = (origList.size()-1)-list.get(i).second;
16643 if (num < 10) pw.print(' ');
16648 pw.print(schedGroup);
16650 pw.print(foreground);
16652 pw.print(procState);
16654 if (r.trimMemoryLevel < 10) pw.print(' ');
16655 pw.print(r.trimMemoryLevel);
16657 pw.print(r.toShortString());
16659 pw.print(r.adjType);
16661 if (r.adjSource != null || r.adjTarget != null) {
16664 if (r.adjTarget instanceof ComponentName) {
16665 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16666 } else if (r.adjTarget != null) {
16667 pw.print(r.adjTarget.toString());
16669 pw.print("{null}");
16672 if (r.adjSource instanceof ProcessRecord) {
16674 pw.print(((ProcessRecord)r.adjSource).toShortString());
16676 } else if (r.adjSource != null) {
16677 pw.println(r.adjSource.toString());
16679 pw.println("{null}");
16685 pw.print("oom: max="); pw.print(r.maxAdj);
16686 pw.print(" curRaw="); pw.print(r.curRawAdj);
16687 pw.print(" setRaw="); pw.print(r.setRawAdj);
16688 pw.print(" cur="); pw.print(r.curAdj);
16689 pw.print(" set="); pw.println(r.setAdj);
16692 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16693 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16694 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16695 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16696 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16700 pw.print("cached="); pw.print(r.cached);
16701 pw.print(" empty="); pw.print(r.empty);
16702 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16704 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16705 if (r.lastWakeTime != 0) {
16707 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16708 synchronized (stats) {
16709 wtime = stats.getProcessWakeTime(r.info.uid,
16710 r.pid, curRealtime);
16712 long timeUsed = wtime - r.lastWakeTime;
16715 pw.print("keep awake over ");
16716 TimeUtils.formatDuration(realtimeSince, pw);
16717 pw.print(" used ");
16718 TimeUtils.formatDuration(timeUsed, pw);
16720 pw.print((timeUsed*100)/realtimeSince);
16723 if (r.lastCpuTime != 0) {
16724 long timeUsed = r.curCpuTime - r.lastCpuTime;
16727 pw.print("run cpu over ");
16728 TimeUtils.formatDuration(uptimeSince, pw);
16729 pw.print(" used ");
16730 TimeUtils.formatDuration(timeUsed, pw);
16732 pw.print((timeUsed*100)/uptimeSince);
16741 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16743 ArrayList<ProcessRecord> procs;
16744 synchronized (this) {
16745 if (args != null && args.length > start
16746 && args[start].charAt(0) != '-') {
16747 procs = new ArrayList<ProcessRecord>();
16750 pid = Integer.parseInt(args[start]);
16751 } catch (NumberFormatException e) {
16753 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16754 ProcessRecord proc = mLruProcesses.get(i);
16755 if (proc.pid == pid) {
16757 } else if (allPkgs && proc.pkgList != null
16758 && proc.pkgList.containsKey(args[start])) {
16760 } else if (proc.processName.equals(args[start])) {
16764 if (procs.size() <= 0) {
16768 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16774 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16775 PrintWriter pw, String[] args) {
16776 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16777 if (procs == null) {
16778 pw.println("No process found for: " + args[0]);
16782 long uptime = SystemClock.uptimeMillis();
16783 long realtime = SystemClock.elapsedRealtime();
16784 pw.println("Applications Graphics Acceleration Info:");
16785 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16787 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16788 ProcessRecord r = procs.get(i);
16789 if (r.thread != null) {
16790 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16793 TransferPipe tp = new TransferPipe();
16795 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16800 } catch (IOException e) {
16801 pw.println("Failure while dumping the app: " + r);
16803 } catch (RemoteException e) {
16804 pw.println("Got a RemoteException while dumping the app " + r);
16811 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16812 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16813 if (procs == null) {
16814 pw.println("No process found for: " + args[0]);
16818 pw.println("Applications Database Info:");
16820 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16821 ProcessRecord r = procs.get(i);
16822 if (r.thread != null) {
16823 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16826 TransferPipe tp = new TransferPipe();
16828 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16833 } catch (IOException e) {
16834 pw.println("Failure while dumping the app: " + r);
16836 } catch (RemoteException e) {
16837 pw.println("Got a RemoteException while dumping the app " + r);
16844 final static class MemItem {
16845 final boolean isProc;
16846 final String label;
16847 final String shortLabel;
16849 final long swapPss;
16851 final boolean hasActivities;
16852 ArrayList<MemItem> subitems;
16854 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16855 boolean _hasActivities) {
16858 shortLabel = _shortLabel;
16860 swapPss = _swapPss;
16862 hasActivities = _hasActivities;
16865 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16868 shortLabel = _shortLabel;
16870 swapPss = _swapPss;
16872 hasActivities = false;
16876 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16877 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16878 if (sort && !isCompact) {
16879 Collections.sort(items, new Comparator<MemItem>() {
16881 public int compare(MemItem lhs, MemItem rhs) {
16882 if (lhs.pss < rhs.pss) {
16884 } else if (lhs.pss > rhs.pss) {
16892 for (int i=0; i<items.size(); i++) {
16893 MemItem mi = items.get(i);
16896 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16897 mi.label, stringifyKBSize(mi.swapPss));
16899 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16901 } else if (mi.isProc) {
16902 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16903 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16904 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16905 pw.println(mi.hasActivities ? ",a" : ",e");
16907 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16908 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16910 if (mi.subitems != null) {
16911 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16912 true, isCompact, dumpSwapPss);
16917 // These are in KB.
16918 static final long[] DUMP_MEM_BUCKETS = new long[] {
16919 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16920 120*1024, 160*1024, 200*1024,
16921 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16922 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16925 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16926 boolean stackLike) {
16927 int start = label.lastIndexOf('.');
16928 if (start >= 0) start++;
16930 int end = label.length();
16931 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16932 if (DUMP_MEM_BUCKETS[i] >= memKB) {
16933 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16934 out.append(bucket);
16935 out.append(stackLike ? "MB." : "MB ");
16936 out.append(label, start, end);
16940 out.append(memKB/1024);
16941 out.append(stackLike ? "MB." : "MB ");
16942 out.append(label, start, end);
16945 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16946 ProcessList.NATIVE_ADJ,
16947 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16948 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16949 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16950 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16951 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16952 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16954 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16956 "System", "Persistent", "Persistent Service", "Foreground",
16957 "Visible", "Perceptible",
16958 "Heavy Weight", "Backup",
16959 "A Services", "Home",
16960 "Previous", "B Services", "Cached"
16962 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16964 "sys", "pers", "persvc", "fore",
16967 "servicea", "home",
16968 "prev", "serviceb", "cached"
16971 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16972 long realtime, boolean isCheckinRequest, boolean isCompact) {
16974 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16976 if (isCheckinRequest || isCompact) {
16977 // short checkin version
16978 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16980 pw.println("Applications Memory Usage (in Kilobytes):");
16981 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16985 private static final int KSM_SHARED = 0;
16986 private static final int KSM_SHARING = 1;
16987 private static final int KSM_UNSHARED = 2;
16988 private static final int KSM_VOLATILE = 3;
16990 private final long[] getKsmInfo() {
16991 long[] longOut = new long[4];
16992 final int[] SINGLE_LONG_FORMAT = new int[] {
16993 PROC_SPACE_TERM| PROC_OUT_LONG
16995 long[] longTmp = new long[1];
16996 readProcFile("/sys/kernel/mm/ksm/pages_shared",
16997 SINGLE_LONG_FORMAT, null, longTmp, null);
16998 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17000 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17001 SINGLE_LONG_FORMAT, null, longTmp, null);
17002 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17004 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17005 SINGLE_LONG_FORMAT, null, longTmp, null);
17006 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17008 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17009 SINGLE_LONG_FORMAT, null, longTmp, null);
17010 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17014 private static String stringifySize(long size, int order) {
17015 Locale locale = Locale.US;
17018 return String.format(locale, "%,13d", size);
17020 return String.format(locale, "%,9dK", size / 1024);
17022 return String.format(locale, "%,5dM", size / 1024 / 1024);
17023 case 1024 * 1024 * 1024:
17024 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17026 throw new IllegalArgumentException("Invalid size order");
17030 private static String stringifyKBSize(long size) {
17031 return stringifySize(size * 1024, 1024);
17034 // Update this version number in case you change the 'compact' format
17035 private static final int MEMINFO_COMPACT_VERSION = 1;
17037 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17038 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17039 boolean dumpDetails = false;
17040 boolean dumpFullDetails = false;
17041 boolean dumpDalvik = false;
17042 boolean dumpSummaryOnly = false;
17043 boolean dumpUnreachable = false;
17044 boolean oomOnly = false;
17045 boolean isCompact = false;
17046 boolean localOnly = false;
17047 boolean packages = false;
17048 boolean isCheckinRequest = false;
17049 boolean dumpSwapPss = false;
17052 while (opti < args.length) {
17053 String opt = args[opti];
17054 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17058 if ("-a".equals(opt)) {
17059 dumpDetails = true;
17060 dumpFullDetails = true;
17062 dumpSwapPss = true;
17063 } else if ("-d".equals(opt)) {
17065 } else if ("-c".equals(opt)) {
17067 } else if ("-s".equals(opt)) {
17068 dumpDetails = true;
17069 dumpSummaryOnly = true;
17070 } else if ("-S".equals(opt)) {
17071 dumpSwapPss = true;
17072 } else if ("--unreachable".equals(opt)) {
17073 dumpUnreachable = true;
17074 } else if ("--oom".equals(opt)) {
17076 } else if ("--local".equals(opt)) {
17078 } else if ("--package".equals(opt)) {
17080 } else if ("--checkin".equals(opt)) {
17081 isCheckinRequest = true;
17083 } else if ("-h".equals(opt)) {
17084 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17085 pw.println(" -a: include all available information for each process.");
17086 pw.println(" -d: include dalvik details.");
17087 pw.println(" -c: dump in a compact machine-parseable representation.");
17088 pw.println(" -s: dump only summary of application memory usage.");
17089 pw.println(" -S: dump also SwapPss.");
17090 pw.println(" --oom: only show processes organized by oom adj.");
17091 pw.println(" --local: only collect details locally, don't call process.");
17092 pw.println(" --package: interpret process arg as package, dumping all");
17093 pw.println(" processes that have loaded that package.");
17094 pw.println(" --checkin: dump data for a checkin");
17095 pw.println("If [process] is specified it can be the name or ");
17096 pw.println("pid of a specific process to dump.");
17099 pw.println("Unknown argument: " + opt + "; use -h for help");
17103 long uptime = SystemClock.uptimeMillis();
17104 long realtime = SystemClock.elapsedRealtime();
17105 final long[] tmpLong = new long[1];
17107 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17108 if (procs == null) {
17109 // No Java processes. Maybe they want to print a native process.
17110 if (args != null && args.length > opti
17111 && args[opti].charAt(0) != '-') {
17112 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17113 = new ArrayList<ProcessCpuTracker.Stats>();
17114 updateCpuStatsNow();
17117 findPid = Integer.parseInt(args[opti]);
17118 } catch (NumberFormatException e) {
17120 synchronized (mProcessCpuTracker) {
17121 final int N = mProcessCpuTracker.countStats();
17122 for (int i=0; i<N; i++) {
17123 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17124 if (st.pid == findPid || (st.baseName != null
17125 && st.baseName.equals(args[opti]))) {
17126 nativeProcs.add(st);
17130 if (nativeProcs.size() > 0) {
17131 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17133 Debug.MemoryInfo mi = null;
17134 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17135 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17136 final int pid = r.pid;
17137 if (!isCheckinRequest && dumpDetails) {
17138 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17141 mi = new Debug.MemoryInfo();
17143 if (dumpDetails || (!brief && !oomOnly)) {
17144 Debug.getMemoryInfo(pid, mi);
17146 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17147 mi.dalvikPrivateDirty = (int)tmpLong[0];
17149 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17150 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17151 if (isCheckinRequest) {
17158 pw.println("No process found for: " + args[opti]);
17162 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17163 dumpDetails = true;
17166 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17168 String[] innerArgs = new String[args.length-opti];
17169 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17171 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17172 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17173 long nativePss = 0;
17174 long nativeSwapPss = 0;
17175 long dalvikPss = 0;
17176 long dalvikSwapPss = 0;
17177 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17179 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17182 long otherSwapPss = 0;
17183 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17184 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17186 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17187 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17188 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17189 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17192 long totalSwapPss = 0;
17193 long cachedPss = 0;
17194 long cachedSwapPss = 0;
17195 boolean hasSwapPss = false;
17197 Debug.MemoryInfo mi = null;
17198 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17199 final ProcessRecord r = procs.get(i);
17200 final IApplicationThread thread;
17203 final boolean hasActivities;
17204 synchronized (this) {
17207 oomAdj = r.getSetAdjWithServices();
17208 hasActivities = r.activities.size() > 0;
17210 if (thread != null) {
17211 if (!isCheckinRequest && dumpDetails) {
17212 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17215 mi = new Debug.MemoryInfo();
17217 if (dumpDetails || (!brief && !oomOnly)) {
17218 Debug.getMemoryInfo(pid, mi);
17219 hasSwapPss = mi.hasSwappedOutPss;
17221 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17222 mi.dalvikPrivateDirty = (int)tmpLong[0];
17226 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17227 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17228 if (isCheckinRequest) {
17234 TransferPipe tp = new TransferPipe();
17236 thread.dumpMemInfo(tp.getWriteFd(),
17237 mi, isCheckinRequest, dumpFullDetails,
17238 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17243 } catch (IOException e) {
17244 if (!isCheckinRequest) {
17245 pw.println("Got IoException!");
17248 } catch (RemoteException e) {
17249 if (!isCheckinRequest) {
17250 pw.println("Got RemoteException!");
17257 final long myTotalPss = mi.getTotalPss();
17258 final long myTotalUss = mi.getTotalUss();
17259 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17261 synchronized (this) {
17262 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17263 // Record this for posterity if the process has been stable.
17264 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17268 if (!isCheckinRequest && mi != null) {
17269 totalPss += myTotalPss;
17270 totalSwapPss += myTotalSwapPss;
17271 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17272 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17273 myTotalSwapPss, pid, hasActivities);
17274 procMems.add(pssItem);
17275 procMemsMap.put(pid, pssItem);
17277 nativePss += mi.nativePss;
17278 nativeSwapPss += mi.nativeSwappedOutPss;
17279 dalvikPss += mi.dalvikPss;
17280 dalvikSwapPss += mi.dalvikSwappedOutPss;
17281 for (int j=0; j<dalvikSubitemPss.length; j++) {
17282 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17283 dalvikSubitemSwapPss[j] +=
17284 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17286 otherPss += mi.otherPss;
17287 otherSwapPss += mi.otherSwappedOutPss;
17288 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17289 long mem = mi.getOtherPss(j);
17292 mem = mi.getOtherSwappedOutPss(j);
17293 miscSwapPss[j] += mem;
17294 otherSwapPss -= mem;
17297 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17298 cachedPss += myTotalPss;
17299 cachedSwapPss += myTotalSwapPss;
17302 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17303 if (oomIndex == (oomPss.length - 1)
17304 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17305 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17306 oomPss[oomIndex] += myTotalPss;
17307 oomSwapPss[oomIndex] += myTotalSwapPss;
17308 if (oomProcs[oomIndex] == null) {
17309 oomProcs[oomIndex] = new ArrayList<MemItem>();
17311 oomProcs[oomIndex].add(pssItem);
17319 long nativeProcTotalPss = 0;
17321 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17322 // If we are showing aggregations, also look for native processes to
17323 // include so that our aggregations are more accurate.
17324 updateCpuStatsNow();
17326 synchronized (mProcessCpuTracker) {
17327 final int N = mProcessCpuTracker.countStats();
17328 for (int i=0; i<N; i++) {
17329 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17330 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17332 mi = new Debug.MemoryInfo();
17334 if (!brief && !oomOnly) {
17335 Debug.getMemoryInfo(st.pid, mi);
17337 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17338 mi.nativePrivateDirty = (int)tmpLong[0];
17341 final long myTotalPss = mi.getTotalPss();
17342 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17343 totalPss += myTotalPss;
17344 nativeProcTotalPss += myTotalPss;
17346 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17347 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17348 procMems.add(pssItem);
17350 nativePss += mi.nativePss;
17351 nativeSwapPss += mi.nativeSwappedOutPss;
17352 dalvikPss += mi.dalvikPss;
17353 dalvikSwapPss += mi.dalvikSwappedOutPss;
17354 for (int j=0; j<dalvikSubitemPss.length; j++) {
17355 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17356 dalvikSubitemSwapPss[j] +=
17357 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17359 otherPss += mi.otherPss;
17360 otherSwapPss += mi.otherSwappedOutPss;
17361 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17362 long mem = mi.getOtherPss(j);
17365 mem = mi.getOtherSwappedOutPss(j);
17366 miscSwapPss[j] += mem;
17367 otherSwapPss -= mem;
17369 oomPss[0] += myTotalPss;
17370 oomSwapPss[0] += myTotalSwapPss;
17371 if (oomProcs[0] == null) {
17372 oomProcs[0] = new ArrayList<MemItem>();
17374 oomProcs[0].add(pssItem);
17379 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17381 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17382 final MemItem dalvikItem =
17383 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17384 if (dalvikSubitemPss.length > 0) {
17385 dalvikItem.subitems = new ArrayList<MemItem>();
17386 for (int j=0; j<dalvikSubitemPss.length; j++) {
17387 final String name = Debug.MemoryInfo.getOtherLabel(
17388 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17389 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17390 dalvikSubitemSwapPss[j], j));
17393 catMems.add(dalvikItem);
17394 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17395 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17396 String label = Debug.MemoryInfo.getOtherLabel(j);
17397 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17400 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17401 for (int j=0; j<oomPss.length; j++) {
17402 if (oomPss[j] != 0) {
17403 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17404 : DUMP_MEM_OOM_LABEL[j];
17405 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17406 DUMP_MEM_OOM_ADJ[j]);
17407 item.subitems = oomProcs[j];
17412 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17413 if (!brief && !oomOnly && !isCompact) {
17415 pw.println("Total PSS by process:");
17416 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17420 pw.println("Total PSS by OOM adjustment:");
17422 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17423 if (!brief && !oomOnly) {
17424 PrintWriter out = categoryPw != null ? categoryPw : pw;
17427 out.println("Total PSS by category:");
17429 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17434 MemInfoReader memInfo = new MemInfoReader();
17435 memInfo.readMemInfo();
17436 if (nativeProcTotalPss > 0) {
17437 synchronized (this) {
17438 final long cachedKb = memInfo.getCachedSizeKb();
17439 final long freeKb = memInfo.getFreeSizeKb();
17440 final long zramKb = memInfo.getZramTotalSizeKb();
17441 final long kernelKb = memInfo.getKernelUsedSizeKb();
17442 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17443 kernelKb*1024, nativeProcTotalPss*1024);
17444 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17445 nativeProcTotalPss);
17450 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17451 pw.print(" (status ");
17452 switch (mLastMemoryLevel) {
17453 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17454 pw.println("normal)");
17456 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17457 pw.println("moderate)");
17459 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17460 pw.println("low)");
17462 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17463 pw.println("critical)");
17466 pw.print(mLastMemoryLevel);
17470 pw.print(" Free RAM: ");
17471 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17472 + memInfo.getFreeSizeKb()));
17474 pw.print(stringifyKBSize(cachedPss));
17475 pw.print(" cached pss + ");
17476 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17477 pw.print(" cached kernel + ");
17478 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17479 pw.println(" free)");
17481 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17482 pw.print(cachedPss + memInfo.getCachedSizeKb()
17483 + memInfo.getFreeSizeKb()); pw.print(",");
17484 pw.println(totalPss - cachedPss);
17487 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17488 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17489 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17491 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17492 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17493 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17494 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17495 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17497 pw.print("lostram,"); pw.println(lostRAM);
17500 if (memInfo.getZramTotalSizeKb() != 0) {
17502 pw.print(" ZRAM: ");
17503 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17504 pw.print(" physical used for ");
17505 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17506 - memInfo.getSwapFreeSizeKb()));
17507 pw.print(" in swap (");
17508 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17509 pw.println(" total swap)");
17511 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17512 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17513 pw.println(memInfo.getSwapFreeSizeKb());
17516 final long[] ksm = getKsmInfo();
17518 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17519 || ksm[KSM_VOLATILE] != 0) {
17520 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17521 pw.print(" saved from shared ");
17522 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17523 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17524 pw.print(" unshared; ");
17525 pw.print(stringifyKBSize(
17526 ksm[KSM_VOLATILE])); pw.println(" volatile");
17528 pw.print(" Tuning: ");
17529 pw.print(ActivityManager.staticGetMemoryClass());
17530 pw.print(" (large ");
17531 pw.print(ActivityManager.staticGetLargeMemoryClass());
17532 pw.print("), oom ");
17533 pw.print(stringifySize(
17534 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17535 pw.print(", restore limit ");
17536 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17537 if (ActivityManager.isLowRamDeviceStatic()) {
17538 pw.print(" (low-ram)");
17540 if (ActivityManager.isHighEndGfx()) {
17541 pw.print(" (high-end-gfx)");
17545 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17546 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17547 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17548 pw.print("tuning,");
17549 pw.print(ActivityManager.staticGetMemoryClass());
17551 pw.print(ActivityManager.staticGetLargeMemoryClass());
17553 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17554 if (ActivityManager.isLowRamDeviceStatic()) {
17555 pw.print(",low-ram");
17557 if (ActivityManager.isHighEndGfx()) {
17558 pw.print(",high-end-gfx");
17566 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17567 long memtrack, String name) {
17569 sb.append(ProcessList.makeOomAdjString(oomAdj));
17571 sb.append(ProcessList.makeProcStateString(procState));
17573 ProcessList.appendRamKb(sb, pss);
17576 if (memtrack > 0) {
17578 sb.append(stringifyKBSize(memtrack));
17579 sb.append(" memtrack)");
17583 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17584 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17585 sb.append(" (pid ");
17588 sb.append(mi.adjType);
17590 if (mi.adjReason != null) {
17592 sb.append(mi.adjReason);
17597 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17598 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17599 for (int i=0, N=memInfos.size(); i<N; i++) {
17600 ProcessMemInfo mi = memInfos.get(i);
17601 infoMap.put(mi.pid, mi);
17603 updateCpuStatsNow();
17604 long[] memtrackTmp = new long[1];
17605 final List<ProcessCpuTracker.Stats> stats;
17606 // Get a list of Stats that have vsize > 0
17607 synchronized (mProcessCpuTracker) {
17608 stats = mProcessCpuTracker.getStats((st) -> {
17609 return st.vsize > 0;
17612 final int statsCount = stats.size();
17613 for (int i = 0; i < statsCount; i++) {
17614 ProcessCpuTracker.Stats st = stats.get(i);
17615 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17617 if (infoMap.indexOfKey(st.pid) < 0) {
17618 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17619 ProcessList.NATIVE_ADJ, -1, "native", null);
17621 mi.memtrack = memtrackTmp[0];
17628 long totalMemtrack = 0;
17629 for (int i=0, N=memInfos.size(); i<N; i++) {
17630 ProcessMemInfo mi = memInfos.get(i);
17632 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17633 mi.memtrack = memtrackTmp[0];
17635 totalPss += mi.pss;
17636 totalMemtrack += mi.memtrack;
17638 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17639 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17640 if (lhs.oomAdj != rhs.oomAdj) {
17641 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17643 if (lhs.pss != rhs.pss) {
17644 return lhs.pss < rhs.pss ? 1 : -1;
17650 StringBuilder tag = new StringBuilder(128);
17651 StringBuilder stack = new StringBuilder(128);
17652 tag.append("Low on memory -- ");
17653 appendMemBucket(tag, totalPss, "total", false);
17654 appendMemBucket(stack, totalPss, "total", true);
17656 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17657 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17658 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17660 boolean firstLine = true;
17661 int lastOomAdj = Integer.MIN_VALUE;
17662 long extraNativeRam = 0;
17663 long extraNativeMemtrack = 0;
17664 long cachedPss = 0;
17665 for (int i=0, N=memInfos.size(); i<N; i++) {
17666 ProcessMemInfo mi = memInfos.get(i);
17668 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17669 cachedPss += mi.pss;
17672 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17673 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17674 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17675 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17676 if (lastOomAdj != mi.oomAdj) {
17677 lastOomAdj = mi.oomAdj;
17678 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17681 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17686 stack.append("\n\t at ");
17694 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17695 appendMemBucket(tag, mi.pss, mi.name, false);
17697 appendMemBucket(stack, mi.pss, mi.name, true);
17698 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17699 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17701 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17702 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17703 stack.append(DUMP_MEM_OOM_LABEL[k]);
17705 stack.append(DUMP_MEM_OOM_ADJ[k]);
17712 appendMemInfo(fullNativeBuilder, mi);
17713 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17714 // The short form only has native processes that are >= 512K.
17715 if (mi.pss >= 512) {
17716 appendMemInfo(shortNativeBuilder, mi);
17718 extraNativeRam += mi.pss;
17719 extraNativeMemtrack += mi.memtrack;
17722 // Short form has all other details, but if we have collected RAM
17723 // from smaller native processes let's dump a summary of that.
17724 if (extraNativeRam > 0) {
17725 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17726 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17727 shortNativeBuilder.append('\n');
17728 extraNativeRam = 0;
17730 appendMemInfo(fullJavaBuilder, mi);
17734 fullJavaBuilder.append(" ");
17735 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17736 fullJavaBuilder.append(": TOTAL");
17737 if (totalMemtrack > 0) {
17738 fullJavaBuilder.append(" (");
17739 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17740 fullJavaBuilder.append(" memtrack)");
17743 fullJavaBuilder.append("\n");
17745 MemInfoReader memInfo = new MemInfoReader();
17746 memInfo.readMemInfo();
17747 final long[] infos = memInfo.getRawInfo();
17749 StringBuilder memInfoBuilder = new StringBuilder(1024);
17750 Debug.getMemInfo(infos);
17751 memInfoBuilder.append(" MemInfo: ");
17752 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17753 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17754 memInfoBuilder.append(stringifyKBSize(
17755 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17756 memInfoBuilder.append(stringifyKBSize(
17757 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17758 memInfoBuilder.append(stringifyKBSize(
17759 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17760 memInfoBuilder.append(" ");
17761 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17762 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17763 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17764 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17765 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17766 memInfoBuilder.append(" ZRAM: ");
17767 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17768 memInfoBuilder.append(" RAM, ");
17769 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17770 memInfoBuilder.append(" swap total, ");
17771 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17772 memInfoBuilder.append(" swap free\n");
17774 final long[] ksm = getKsmInfo();
17775 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17776 || ksm[KSM_VOLATILE] != 0) {
17777 memInfoBuilder.append(" KSM: ");
17778 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17779 memInfoBuilder.append(" saved from shared ");
17780 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17781 memInfoBuilder.append("\n ");
17782 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17783 memInfoBuilder.append(" unshared; ");
17784 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17785 memInfoBuilder.append(" volatile\n");
17787 memInfoBuilder.append(" Free RAM: ");
17788 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17789 + memInfo.getFreeSizeKb()));
17790 memInfoBuilder.append("\n");
17791 memInfoBuilder.append(" Used RAM: ");
17792 memInfoBuilder.append(stringifyKBSize(
17793 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17794 memInfoBuilder.append("\n");
17795 memInfoBuilder.append(" Lost RAM: ");
17796 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17797 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17798 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17799 memInfoBuilder.append("\n");
17800 Slog.i(TAG, "Low on memory:");
17801 Slog.i(TAG, shortNativeBuilder.toString());
17802 Slog.i(TAG, fullJavaBuilder.toString());
17803 Slog.i(TAG, memInfoBuilder.toString());
17805 StringBuilder dropBuilder = new StringBuilder(1024);
17807 StringWriter oomSw = new StringWriter();
17808 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17809 StringWriter catSw = new StringWriter();
17810 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17811 String[] emptyArgs = new String[] { };
17812 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17814 String oomString = oomSw.toString();
17816 dropBuilder.append("Low on memory:");
17817 dropBuilder.append(stack);
17818 dropBuilder.append('\n');
17819 dropBuilder.append(fullNativeBuilder);
17820 dropBuilder.append(fullJavaBuilder);
17821 dropBuilder.append('\n');
17822 dropBuilder.append(memInfoBuilder);
17823 dropBuilder.append('\n');
17825 dropBuilder.append(oomString);
17826 dropBuilder.append('\n');
17828 StringWriter catSw = new StringWriter();
17829 synchronized (ActivityManagerService.this) {
17830 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17831 String[] emptyArgs = new String[] { };
17833 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17835 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17836 false, null).dumpLocked();
17838 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17841 dropBuilder.append(catSw.toString());
17842 addErrorToDropBox("lowmem", null, "system_server", null,
17843 null, tag.toString(), dropBuilder.toString(), null, null);
17844 //Slog.i(TAG, "Sent to dropbox:");
17845 //Slog.i(TAG, dropBuilder.toString());
17846 synchronized (ActivityManagerService.this) {
17847 long now = SystemClock.uptimeMillis();
17848 if (mLastMemUsageReportTime < now) {
17849 mLastMemUsageReportTime = now;
17855 * Searches array of arguments for the specified string
17856 * @param args array of argument strings
17857 * @param value value to search for
17858 * @return true if the value is contained in the array
17860 private static boolean scanArgs(String[] args, String value) {
17861 if (args != null) {
17862 for (String arg : args) {
17863 if (value.equals(arg)) {
17871 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17872 ContentProviderRecord cpr, boolean always) {
17873 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17875 if (!inLaunching || always) {
17876 synchronized (cpr) {
17877 cpr.launchingApp = null;
17880 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17881 String names[] = cpr.info.authority.split(";");
17882 for (int j = 0; j < names.length; j++) {
17883 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17887 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17888 ContentProviderConnection conn = cpr.connections.get(i);
17889 if (conn.waiting) {
17890 // If this connection is waiting for the provider, then we don't
17891 // need to mess with its process unless we are always removing
17892 // or for some reason the provider is not currently launching.
17893 if (inLaunching && !always) {
17897 ProcessRecord capp = conn.client;
17899 if (conn.stableCount > 0) {
17900 if (!capp.persistent && capp.thread != null
17902 && capp.pid != MY_PID) {
17903 capp.kill("depends on provider "
17904 + cpr.name.flattenToShortString()
17905 + " in dying proc " + (proc != null ? proc.processName : "??")
17906 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17908 } else if (capp.thread != null && conn.provider.provider != null) {
17910 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17911 } catch (RemoteException e) {
17913 // In the protocol here, we don't expect the client to correctly
17914 // clean up this connection, we'll just remove it.
17915 cpr.connections.remove(i);
17916 if (conn.client.conProviders.remove(conn)) {
17917 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17922 if (inLaunching && always) {
17923 mLaunchingProviders.remove(cpr);
17925 return inLaunching;
17929 * Main code for cleaning up a process when it has gone away. This is
17930 * called both as a result of the process dying, or directly when stopping
17931 * a process when running in single process mode.
17933 * @return Returns true if the given process has been restarted, so the
17934 * app that was passed in must remain on the process lists.
17936 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17937 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17939 removeLruProcessLocked(app);
17940 ProcessList.remove(app.pid);
17943 mProcessesToGc.remove(app);
17944 mPendingPssProcesses.remove(app);
17946 // Dismiss any open dialogs.
17947 if (app.crashDialog != null && !app.forceCrashReport) {
17948 app.crashDialog.dismiss();
17949 app.crashDialog = null;
17951 if (app.anrDialog != null) {
17952 app.anrDialog.dismiss();
17953 app.anrDialog = null;
17955 if (app.waitDialog != null) {
17956 app.waitDialog.dismiss();
17957 app.waitDialog = null;
17960 app.crashing = false;
17961 app.notResponding = false;
17963 app.resetPackageList(mProcessStats);
17964 app.unlinkDeathRecipient();
17965 app.makeInactive(mProcessStats);
17966 app.waitingToKill = null;
17967 app.forcingToImportant = null;
17968 updateProcessForegroundLocked(app, false, false);
17969 app.foregroundActivities = false;
17970 app.hasShownUi = false;
17971 app.treatLikeActivity = false;
17972 app.hasAboveClient = false;
17973 app.hasClientActivities = false;
17975 mServices.killServicesLocked(app, allowRestart);
17977 boolean restart = false;
17979 // Remove published content providers.
17980 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17981 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17982 final boolean always = app.bad || !allowRestart;
17983 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17984 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17985 // We left the provider in the launching list, need to
17990 cpr.provider = null;
17993 app.pubProviders.clear();
17995 // Take care of any launching providers waiting for this process.
17996 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18000 // Unregister from connected content providers.
18001 if (!app.conProviders.isEmpty()) {
18002 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18003 ContentProviderConnection conn = app.conProviders.get(i);
18004 conn.provider.connections.remove(conn);
18005 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18006 conn.provider.name);
18008 app.conProviders.clear();
18011 // At this point there may be remaining entries in mLaunchingProviders
18012 // where we were the only one waiting, so they are no longer of use.
18013 // Look for these and clean up if found.
18014 // XXX Commented out for now. Trying to figure out a way to reproduce
18015 // the actual situation to identify what is actually going on.
18017 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18018 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18019 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18020 synchronized (cpr) {
18021 cpr.launchingApp = null;
18028 skipCurrentReceiverLocked(app);
18030 // Unregister any receivers.
18031 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18032 removeReceiverLocked(app.receivers.valueAt(i));
18034 app.receivers.clear();
18036 // If the app is undergoing backup, tell the backup manager about it
18037 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18038 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18039 + mBackupTarget.appInfo + " died during backup");
18040 mHandler.post(new Runnable() {
18044 IBackupManager bm = IBackupManager.Stub.asInterface(
18045 ServiceManager.getService(Context.BACKUP_SERVICE));
18046 bm.agentDisconnected(app.info.packageName);
18047 } catch (RemoteException e) {
18048 // can't happen; backup manager is local
18054 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18055 ProcessChangeItem item = mPendingProcessChanges.get(i);
18056 if (item.pid == app.pid) {
18057 mPendingProcessChanges.remove(i);
18058 mAvailProcessChanges.add(item);
18061 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18062 null).sendToTarget();
18064 // If the caller is restarting this app, then leave it in its
18065 // current lists and let the caller take care of it.
18070 if (!app.persistent || app.isolated) {
18071 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18072 "Removing non-persistent process during cleanup: " + app);
18073 if (!replacingPid) {
18074 removeProcessNameLocked(app.processName, app.uid, app);
18076 if (mHeavyWeightProcess == app) {
18077 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18078 mHeavyWeightProcess.userId, 0));
18079 mHeavyWeightProcess = null;
18081 } else if (!app.removed) {
18082 // This app is persistent, so we need to keep its record around.
18083 // If it is not already on the pending app list, add it there
18084 // and start a new process for it.
18085 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18086 mPersistentStartingProcesses.add(app);
18090 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18091 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18092 mProcessesOnHold.remove(app);
18094 if (app == mHomeProcess) {
18095 mHomeProcess = null;
18097 if (app == mPreviousProcess) {
18098 mPreviousProcess = null;
18101 if (restart && !app.isolated) {
18102 // We have components that still need to be running in the
18103 // process, so re-launch it.
18105 ProcessList.remove(app.pid);
18107 addProcessNameLocked(app);
18108 startProcessLocked(app, "restart", app.processName);
18110 } else if (app.pid > 0 && app.pid != MY_PID) {
18113 synchronized (mPidsSelfLocked) {
18114 mPidsSelfLocked.remove(app.pid);
18115 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18117 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18118 if (app.isolated) {
18119 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18126 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18127 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18128 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18129 if (cpr.launchingApp == app) {
18136 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18137 // Look through the content providers we are waiting to have launched,
18138 // and if any run in this process then either schedule a restart of
18139 // the process or kill the client waiting for it if this process has
18141 boolean restart = false;
18142 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18143 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18144 if (cpr.launchingApp == app) {
18145 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18148 removeDyingProviderLocked(app, cpr, true);
18155 // =========================================================
18157 // =========================================================
18160 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18162 enforceNotIsolatedCaller("getServices");
18164 final int callingUid = Binder.getCallingUid();
18165 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18166 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18167 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18169 synchronized (this) {
18170 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18171 allowed, canInteractAcrossUsers);
18176 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18177 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18178 synchronized (this) {
18179 return mServices.getRunningServiceControlPanelLocked(name);
18184 public ComponentName startService(IApplicationThread caller, Intent service,
18185 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18186 throws TransactionTooLargeException {
18187 enforceNotIsolatedCaller("startService");
18188 // Refuse possible leaked file descriptors
18189 if (service != null && service.hasFileDescriptors() == true) {
18190 throw new IllegalArgumentException("File descriptors passed in Intent");
18193 if (callingPackage == null) {
18194 throw new IllegalArgumentException("callingPackage cannot be null");
18197 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18198 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18199 synchronized(this) {
18200 final int callingPid = Binder.getCallingPid();
18201 final int callingUid = Binder.getCallingUid();
18202 final long origId = Binder.clearCallingIdentity();
18205 res = mServices.startServiceLocked(caller, service,
18206 resolvedType, callingPid, callingUid,
18207 requireForeground, callingPackage, userId);
18209 Binder.restoreCallingIdentity(origId);
18215 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18216 boolean fgRequired, String callingPackage, int userId)
18217 throws TransactionTooLargeException {
18218 synchronized(this) {
18219 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18220 "startServiceInPackage: " + service + " type=" + resolvedType);
18221 final long origId = Binder.clearCallingIdentity();
18224 res = mServices.startServiceLocked(null, service,
18225 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18227 Binder.restoreCallingIdentity(origId);
18234 public int stopService(IApplicationThread caller, Intent service,
18235 String resolvedType, int userId) {
18236 enforceNotIsolatedCaller("stopService");
18237 // Refuse possible leaked file descriptors
18238 if (service != null && service.hasFileDescriptors() == true) {
18239 throw new IllegalArgumentException("File descriptors passed in Intent");
18242 synchronized(this) {
18243 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18248 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18249 enforceNotIsolatedCaller("peekService");
18250 // Refuse possible leaked file descriptors
18251 if (service != null && service.hasFileDescriptors() == true) {
18252 throw new IllegalArgumentException("File descriptors passed in Intent");
18255 if (callingPackage == null) {
18256 throw new IllegalArgumentException("callingPackage cannot be null");
18259 synchronized(this) {
18260 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18265 public boolean stopServiceToken(ComponentName className, IBinder token,
18267 synchronized(this) {
18268 return mServices.stopServiceTokenLocked(className, token, startId);
18273 public void setServiceForeground(ComponentName className, IBinder token,
18274 int id, Notification notification, int flags) {
18275 synchronized(this) {
18276 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18281 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18282 boolean requireFull, String name, String callerPackage) {
18283 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18284 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18287 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18288 String className, int flags) {
18289 boolean result = false;
18290 // For apps that don't have pre-defined UIDs, check for permission
18291 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18292 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18293 if (ActivityManager.checkUidPermission(
18294 INTERACT_ACROSS_USERS,
18295 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18296 ComponentName comp = new ComponentName(aInfo.packageName, className);
18297 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18298 + " requests FLAG_SINGLE_USER, but app does not hold "
18299 + INTERACT_ACROSS_USERS;
18301 throw new SecurityException(msg);
18303 // Permission passed
18306 } else if ("system".equals(componentProcessName)) {
18308 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18309 // Phone app and persistent apps are allowed to export singleuser providers.
18310 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18311 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18313 if (DEBUG_MU) Slog.v(TAG_MU,
18314 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18315 + Integer.toHexString(flags) + ") = " + result);
18320 * Checks to see if the caller is in the same app as the singleton
18321 * component, or the component is in a special app. It allows special apps
18322 * to export singleton components but prevents exporting singleton
18323 * components for regular apps.
18325 boolean isValidSingletonCall(int callingUid, int componentUid) {
18326 int componentAppId = UserHandle.getAppId(componentUid);
18327 return UserHandle.isSameApp(callingUid, componentUid)
18328 || componentAppId == SYSTEM_UID
18329 || componentAppId == PHONE_UID
18330 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18331 == PackageManager.PERMISSION_GRANTED;
18334 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18335 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18336 int userId) throws TransactionTooLargeException {
18337 enforceNotIsolatedCaller("bindService");
18339 // Refuse possible leaked file descriptors
18340 if (service != null && service.hasFileDescriptors() == true) {
18341 throw new IllegalArgumentException("File descriptors passed in Intent");
18344 if (callingPackage == null) {
18345 throw new IllegalArgumentException("callingPackage cannot be null");
18348 synchronized(this) {
18349 return mServices.bindServiceLocked(caller, token, service,
18350 resolvedType, connection, flags, callingPackage, userId);
18354 public boolean unbindService(IServiceConnection connection) {
18355 synchronized (this) {
18356 return mServices.unbindServiceLocked(connection);
18360 public void publishService(IBinder token, Intent intent, IBinder service) {
18361 // Refuse possible leaked file descriptors
18362 if (intent != null && intent.hasFileDescriptors() == true) {
18363 throw new IllegalArgumentException("File descriptors passed in Intent");
18366 synchronized(this) {
18367 if (!(token instanceof ServiceRecord)) {
18368 throw new IllegalArgumentException("Invalid service token");
18370 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18374 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18375 // Refuse possible leaked file descriptors
18376 if (intent != null && intent.hasFileDescriptors() == true) {
18377 throw new IllegalArgumentException("File descriptors passed in Intent");
18380 synchronized(this) {
18381 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18385 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18386 synchronized(this) {
18387 if (!(token instanceof ServiceRecord)) {
18388 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18389 throw new IllegalArgumentException("Invalid service token");
18391 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18395 // =========================================================
18396 // BACKUP AND RESTORE
18397 // =========================================================
18399 // Cause the target app to be launched if necessary and its backup agent
18400 // instantiated. The backup agent will invoke backupAgentCreated() on the
18401 // activity manager to announce its creation.
18402 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18403 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18404 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18406 IPackageManager pm = AppGlobals.getPackageManager();
18407 ApplicationInfo app = null;
18409 app = pm.getApplicationInfo(packageName, 0, userId);
18410 } catch (RemoteException e) {
18411 // can't happen; package manager is process-local
18414 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18421 synchronized(this) {
18422 // !!! TODO: currently no check here that we're already bound
18423 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18424 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18425 synchronized (stats) {
18426 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18429 // Backup agent is now in use, its package can't be stopped.
18431 AppGlobals.getPackageManager().setPackageStoppedState(
18432 app.packageName, false, UserHandle.getUserId(app.uid));
18433 } catch (RemoteException e) {
18434 } catch (IllegalArgumentException e) {
18435 Slog.w(TAG, "Failed trying to unstop package "
18436 + app.packageName + ": " + e);
18439 BackupRecord r = new BackupRecord(ss, app, backupMode);
18440 ComponentName hostingName =
18441 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18442 ? new ComponentName(app.packageName, app.backupAgentName)
18443 : new ComponentName("android", "FullBackupAgent");
18444 // startProcessLocked() returns existing proc's record if it's already running
18445 ProcessRecord proc = startProcessLocked(app.processName, app,
18446 false, 0, "backup", hostingName, false, false, false);
18447 if (proc == null) {
18448 Slog.e(TAG, "Unable to start backup agent process " + r);
18452 // If the app is a regular app (uid >= 10000) and not the system server or phone
18453 // process, etc, then mark it as being in full backup so that certain calls to the
18454 // process can be blocked. This is not reset to false anywhere because we kill the
18455 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18456 if (UserHandle.isApp(app.uid) &&
18457 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18458 proc.inFullBackup = true;
18461 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18462 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18464 mBackupAppName = app.packageName;
18466 // Try not to kill the process during backup
18467 updateOomAdjLocked(proc, true);
18469 // If the process is already attached, schedule the creation of the backup agent now.
18470 // If it is not yet live, this will be done when it attaches to the framework.
18471 if (proc.thread != null) {
18472 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18474 proc.thread.scheduleCreateBackupAgent(app,
18475 compatibilityInfoForPackageLocked(app), backupMode);
18476 } catch (RemoteException e) {
18477 // Will time out on the backup manager side
18480 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18482 // Invariants: at this point, the target app process exists and the application
18483 // is either already running or in the process of coming up. mBackupTarget and
18484 // mBackupAppName describe the app, so that when it binds back to the AM we
18485 // know that it's scheduled for a backup-agent operation.
18488 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18489 if (oldBackupUid != -1) {
18490 js.removeBackingUpUid(oldBackupUid);
18492 if (newBackupUid != -1) {
18493 js.addBackingUpUid(newBackupUid);
18500 public void clearPendingBackup() {
18501 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18502 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18504 synchronized (this) {
18505 mBackupTarget = null;
18506 mBackupAppName = null;
18509 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18510 js.clearAllBackingUpUids();
18513 // A backup agent has just come up
18514 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18515 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18518 synchronized(this) {
18519 if (!agentPackageName.equals(mBackupAppName)) {
18520 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18525 long oldIdent = Binder.clearCallingIdentity();
18527 IBackupManager bm = IBackupManager.Stub.asInterface(
18528 ServiceManager.getService(Context.BACKUP_SERVICE));
18529 bm.agentConnected(agentPackageName, agent);
18530 } catch (RemoteException e) {
18531 // can't happen; the backup manager service is local
18532 } catch (Exception e) {
18533 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18534 e.printStackTrace();
18536 Binder.restoreCallingIdentity(oldIdent);
18540 // done with this agent
18541 public void unbindBackupAgent(ApplicationInfo appInfo) {
18542 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18543 if (appInfo == null) {
18544 Slog.w(TAG, "unbind backup agent for null app");
18550 synchronized(this) {
18552 if (mBackupAppName == null) {
18553 Slog.w(TAG, "Unbinding backup agent with no active backup");
18557 if (!mBackupAppName.equals(appInfo.packageName)) {
18558 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18562 // Not backing this app up any more; reset its OOM adjustment
18563 final ProcessRecord proc = mBackupTarget.app;
18564 updateOomAdjLocked(proc, true);
18565 proc.inFullBackup = false;
18567 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18569 // If the app crashed during backup, 'thread' will be null here
18570 if (proc.thread != null) {
18572 proc.thread.scheduleDestroyBackupAgent(appInfo,
18573 compatibilityInfoForPackageLocked(appInfo));
18574 } catch (Exception e) {
18575 Slog.e(TAG, "Exception when unbinding backup agent:");
18576 e.printStackTrace();
18580 mBackupTarget = null;
18581 mBackupAppName = null;
18585 if (oldBackupUid != -1) {
18586 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18587 js.removeBackingUpUid(oldBackupUid);
18591 // =========================================================
18593 // =========================================================
18595 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18596 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18599 // Easy case -- we have the app's ProcessRecord.
18600 if (record != null) {
18601 return record.info.isInstantApp();
18603 // Otherwise check with PackageManager.
18604 if (callerPackage == null) {
18605 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18606 throw new IllegalArgumentException("Calling application did not provide package name");
18608 mAppOpsService.checkPackage(uid, callerPackage);
18610 IPackageManager pm = AppGlobals.getPackageManager();
18611 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18612 } catch (RemoteException e) {
18613 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18618 boolean isPendingBroadcastProcessLocked(int pid) {
18619 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18620 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18623 void skipPendingBroadcastLocked(int pid) {
18624 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18625 for (BroadcastQueue queue : mBroadcastQueues) {
18626 queue.skipPendingBroadcastLocked(pid);
18630 // The app just attached; send any pending broadcasts that it should receive
18631 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18632 boolean didSomething = false;
18633 for (BroadcastQueue queue : mBroadcastQueues) {
18634 didSomething |= queue.sendPendingBroadcastsLocked(app);
18636 return didSomething;
18639 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18640 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18642 enforceNotIsolatedCaller("registerReceiver");
18643 ArrayList<Intent> stickyIntents = null;
18644 ProcessRecord callerApp = null;
18645 final boolean visibleToInstantApps
18646 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18649 boolean instantApp;
18650 synchronized(this) {
18651 if (caller != null) {
18652 callerApp = getRecordForAppLocked(caller);
18653 if (callerApp == null) {
18654 throw new SecurityException(
18655 "Unable to find app for caller " + caller
18656 + " (pid=" + Binder.getCallingPid()
18657 + ") when registering receiver " + receiver);
18659 if (callerApp.info.uid != SYSTEM_UID &&
18660 !callerApp.pkgList.containsKey(callerPackage) &&
18661 !"android".equals(callerPackage)) {
18662 throw new SecurityException("Given caller package " + callerPackage
18663 + " is not running in process " + callerApp);
18665 callingUid = callerApp.info.uid;
18666 callingPid = callerApp.pid;
18668 callerPackage = null;
18669 callingUid = Binder.getCallingUid();
18670 callingPid = Binder.getCallingPid();
18673 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18674 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18675 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18677 Iterator<String> actions = filter.actionsIterator();
18678 if (actions == null) {
18679 ArrayList<String> noAction = new ArrayList<String>(1);
18680 noAction.add(null);
18681 actions = noAction.iterator();
18684 // Collect stickies of users
18685 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18686 while (actions.hasNext()) {
18687 String action = actions.next();
18688 for (int id : userIds) {
18689 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18690 if (stickies != null) {
18691 ArrayList<Intent> intents = stickies.get(action);
18692 if (intents != null) {
18693 if (stickyIntents == null) {
18694 stickyIntents = new ArrayList<Intent>();
18696 stickyIntents.addAll(intents);
18703 ArrayList<Intent> allSticky = null;
18704 if (stickyIntents != null) {
18705 final ContentResolver resolver = mContext.getContentResolver();
18706 // Look for any matching sticky broadcasts...
18707 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18708 Intent intent = stickyIntents.get(i);
18709 // Don't provided intents that aren't available to instant apps.
18711 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18714 // If intent has scheme "content", it will need to acccess
18715 // provider that needs to lock mProviderMap in ActivityThread
18716 // and also it may need to wait application response, so we
18717 // cannot lock ActivityManagerService here.
18718 if (filter.match(resolver, intent, true, TAG) >= 0) {
18719 if (allSticky == null) {
18720 allSticky = new ArrayList<Intent>();
18722 allSticky.add(intent);
18727 // The first sticky in the list is returned directly back to the client.
18728 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18729 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18730 if (receiver == null) {
18734 synchronized (this) {
18735 if (callerApp != null && (callerApp.thread == null
18736 || callerApp.thread.asBinder() != caller.asBinder())) {
18737 // Original caller already died
18740 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18742 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18744 if (rl.app != null) {
18745 rl.app.receivers.add(rl);
18748 receiver.asBinder().linkToDeath(rl, 0);
18749 } catch (RemoteException e) {
18752 rl.linkedToDeath = true;
18754 mRegisteredReceivers.put(receiver.asBinder(), rl);
18755 } else if (rl.uid != callingUid) {
18756 throw new IllegalArgumentException(
18757 "Receiver requested to register for uid " + callingUid
18758 + " was previously registered for uid " + rl.uid
18759 + " callerPackage is " + callerPackage);
18760 } else if (rl.pid != callingPid) {
18761 throw new IllegalArgumentException(
18762 "Receiver requested to register for pid " + callingPid
18763 + " was previously registered for pid " + rl.pid
18764 + " callerPackage is " + callerPackage);
18765 } else if (rl.userId != userId) {
18766 throw new IllegalArgumentException(
18767 "Receiver requested to register for user " + userId
18768 + " was previously registered for user " + rl.userId
18769 + " callerPackage is " + callerPackage);
18771 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18772 permission, callingUid, userId, instantApp, visibleToInstantApps);
18774 if (!bf.debugCheck()) {
18775 Slog.w(TAG, "==> For Dynamic broadcast");
18777 mReceiverResolver.addFilter(bf);
18779 // Enqueue broadcasts for all existing stickies that match
18781 if (allSticky != null) {
18782 ArrayList receivers = new ArrayList();
18785 final int stickyCount = allSticky.size();
18786 for (int i = 0; i < stickyCount; i++) {
18787 Intent intent = allSticky.get(i);
18788 BroadcastQueue queue = broadcastQueueForIntent(intent);
18789 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18790 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18791 null, 0, null, null, false, true, true, -1);
18792 queue.enqueueParallelBroadcastLocked(r);
18793 queue.scheduleBroadcastsLocked();
18801 public void unregisterReceiver(IIntentReceiver receiver) {
18802 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18804 final long origId = Binder.clearCallingIdentity();
18806 boolean doTrim = false;
18808 synchronized(this) {
18809 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18811 final BroadcastRecord r = rl.curBroadcast;
18812 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18813 final boolean doNext = r.queue.finishReceiverLocked(
18814 r, r.resultCode, r.resultData, r.resultExtras,
18815 r.resultAbort, false);
18818 r.queue.processNextBroadcast(false);
18822 if (rl.app != null) {
18823 rl.app.receivers.remove(rl);
18825 removeReceiverLocked(rl);
18826 if (rl.linkedToDeath) {
18827 rl.linkedToDeath = false;
18828 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18833 // If we actually concluded any broadcasts, we might now be able
18834 // to trim the recipients' apps from our working set
18836 trimApplications();
18841 Binder.restoreCallingIdentity(origId);
18845 void removeReceiverLocked(ReceiverList rl) {
18846 mRegisteredReceivers.remove(rl.receiver.asBinder());
18847 for (int i = rl.size() - 1; i >= 0; i--) {
18848 mReceiverResolver.removeFilter(rl.get(i));
18852 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18853 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18854 ProcessRecord r = mLruProcesses.get(i);
18855 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18857 r.thread.dispatchPackageBroadcast(cmd, packages);
18858 } catch (RemoteException ex) {
18864 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18865 int callingUid, int[] users) {
18866 // TODO: come back and remove this assumption to triage all broadcasts
18867 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18869 List<ResolveInfo> receivers = null;
18871 HashSet<ComponentName> singleUserReceivers = null;
18872 boolean scannedFirstReceivers = false;
18873 for (int user : users) {
18874 // Skip users that have Shell restrictions, with exception of always permitted
18875 // Shell broadcasts
18876 if (callingUid == SHELL_UID
18877 && mUserController.hasUserRestriction(
18878 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18879 && !isPermittedShellBroadcast(intent)) {
18882 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18883 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18884 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18885 // If this is not the system user, we need to check for
18886 // any receivers that should be filtered out.
18887 for (int i=0; i<newReceivers.size(); i++) {
18888 ResolveInfo ri = newReceivers.get(i);
18889 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18890 newReceivers.remove(i);
18895 if (newReceivers != null && newReceivers.size() == 0) {
18896 newReceivers = null;
18898 if (receivers == null) {
18899 receivers = newReceivers;
18900 } else if (newReceivers != null) {
18901 // We need to concatenate the additional receivers
18902 // found with what we have do far. This would be easy,
18903 // but we also need to de-dup any receivers that are
18905 if (!scannedFirstReceivers) {
18906 // Collect any single user receivers we had already retrieved.
18907 scannedFirstReceivers = true;
18908 for (int i=0; i<receivers.size(); i++) {
18909 ResolveInfo ri = receivers.get(i);
18910 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18911 ComponentName cn = new ComponentName(
18912 ri.activityInfo.packageName, ri.activityInfo.name);
18913 if (singleUserReceivers == null) {
18914 singleUserReceivers = new HashSet<ComponentName>();
18916 singleUserReceivers.add(cn);
18920 // Add the new results to the existing results, tracking
18921 // and de-dupping single user receivers.
18922 for (int i=0; i<newReceivers.size(); i++) {
18923 ResolveInfo ri = newReceivers.get(i);
18924 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18925 ComponentName cn = new ComponentName(
18926 ri.activityInfo.packageName, ri.activityInfo.name);
18927 if (singleUserReceivers == null) {
18928 singleUserReceivers = new HashSet<ComponentName>();
18930 if (!singleUserReceivers.contains(cn)) {
18931 singleUserReceivers.add(cn);
18940 } catch (RemoteException ex) {
18941 // pm is in same process, this will never happen.
18946 private boolean isPermittedShellBroadcast(Intent intent) {
18947 // remote bugreport should always be allowed to be taken
18948 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18951 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18952 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18953 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18954 // Don't yell about broadcasts sent via shell
18958 final String action = intent.getAction();
18959 if (isProtectedBroadcast
18960 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18961 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18962 || Intent.ACTION_MEDIA_BUTTON.equals(action)
18963 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18964 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18965 || Intent.ACTION_MASTER_CLEAR.equals(action)
18966 || Intent.ACTION_FACTORY_RESET.equals(action)
18967 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18968 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18969 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18970 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18971 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18972 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18973 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18974 // Broadcast is either protected, or it's a public action that
18975 // we've relaxed, so it's fine for system internals to send.
18979 // This broadcast may be a problem... but there are often system components that
18980 // want to send an internal broadcast to themselves, which is annoying to have to
18981 // explicitly list each action as a protected broadcast, so we will check for that
18982 // one safe case and allow it: an explicit broadcast, only being received by something
18983 // that has protected itself.
18984 if (receivers != null && receivers.size() > 0
18985 && (intent.getPackage() != null || intent.getComponent() != null)) {
18986 boolean allProtected = true;
18987 for (int i = receivers.size()-1; i >= 0; i--) {
18988 Object target = receivers.get(i);
18989 if (target instanceof ResolveInfo) {
18990 ResolveInfo ri = (ResolveInfo)target;
18991 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18992 allProtected = false;
18996 BroadcastFilter bf = (BroadcastFilter)target;
18997 if (bf.requiredPermission == null) {
18998 allProtected = false;
19003 if (allProtected) {
19009 // The vast majority of broadcasts sent from system internals
19010 // should be protected to avoid security holes, so yell loudly
19011 // to ensure we examine these cases.
19012 if (callerApp != null) {
19013 Log.wtf(TAG, "Sending non-protected broadcast " + action
19014 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19017 Log.wtf(TAG, "Sending non-protected broadcast " + action
19018 + " from system uid " + UserHandle.formatUid(callingUid)
19019 + " pkg " + callerPackage,
19024 final int broadcastIntentLocked(ProcessRecord callerApp,
19025 String callerPackage, Intent intent, String resolvedType,
19026 IIntentReceiver resultTo, int resultCode, String resultData,
19027 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19028 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19029 intent = new Intent(intent);
19031 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19032 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19033 if (callerInstantApp) {
19034 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19037 // By default broadcasts do not go to stopped apps.
19038 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19040 // If we have not finished booting, don't allow this to launch new processes.
19041 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19042 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19045 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19046 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19047 + " ordered=" + ordered + " userid=" + userId);
19048 if ((resultTo != null) && !ordered) {
19049 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19052 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19053 ALLOW_NON_FULL, "broadcast", callerPackage);
19055 // Make sure that the user who is receiving this broadcast is running.
19056 // If not, we will just skip it. Make an exception for shutdown broadcasts
19057 // and upgrade steps.
19059 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19060 if ((callingUid != SYSTEM_UID
19061 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19062 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19063 Slog.w(TAG, "Skipping broadcast of " + intent
19064 + ": user " + userId + " is stopped");
19065 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19069 BroadcastOptions brOptions = null;
19070 if (bOptions != null) {
19071 brOptions = new BroadcastOptions(bOptions);
19072 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19073 // See if the caller is allowed to do this. Note we are checking against
19074 // the actual real caller (not whoever provided the operation as say a
19075 // PendingIntent), because that who is actually supplied the arguments.
19076 if (checkComponentPermission(
19077 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19078 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19079 != PackageManager.PERMISSION_GRANTED) {
19080 String msg = "Permission Denial: " + intent.getAction()
19081 + " broadcast from " + callerPackage + " (pid=" + callingPid
19082 + ", uid=" + callingUid + ")"
19084 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19086 throw new SecurityException(msg);
19091 // Verify that protected broadcasts are only being sent by system code,
19092 // and that system code is only sending protected broadcasts.
19093 final String action = intent.getAction();
19094 final boolean isProtectedBroadcast;
19096 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19097 } catch (RemoteException e) {
19098 Slog.w(TAG, "Remote exception", e);
19099 return ActivityManager.BROADCAST_SUCCESS;
19102 final boolean isCallerSystem;
19103 switch (UserHandle.getAppId(callingUid)) {
19107 case BLUETOOTH_UID:
19109 isCallerSystem = true;
19112 isCallerSystem = (callerApp != null) && callerApp.persistent;
19116 // First line security check before anything else: stop non-system apps from
19117 // sending protected broadcasts.
19118 if (!isCallerSystem) {
19119 if (isProtectedBroadcast) {
19120 String msg = "Permission Denial: not allowed to send broadcast "
19121 + action + " from pid="
19122 + callingPid + ", uid=" + callingUid;
19124 throw new SecurityException(msg);
19126 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19127 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19128 // Special case for compatibility: we don't want apps to send this,
19129 // but historically it has not been protected and apps may be using it
19130 // to poke their own app widget. So, instead of making it protected,
19131 // just limit it to the caller.
19132 if (callerPackage == null) {
19133 String msg = "Permission Denial: not allowed to send broadcast "
19134 + action + " from unknown caller.";
19136 throw new SecurityException(msg);
19137 } else if (intent.getComponent() != null) {
19138 // They are good enough to send to an explicit component... verify
19139 // it is being sent to the calling app.
19140 if (!intent.getComponent().getPackageName().equals(
19142 String msg = "Permission Denial: not allowed to send broadcast "
19144 + intent.getComponent().getPackageName() + " from "
19147 throw new SecurityException(msg);
19150 // Limit broadcast to their own package.
19151 intent.setPackage(callerPackage);
19156 if (action != null) {
19157 if (getBackgroundLaunchBroadcasts().contains(action)) {
19158 if (DEBUG_BACKGROUND_CHECK) {
19159 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19161 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19165 case Intent.ACTION_UID_REMOVED:
19166 case Intent.ACTION_PACKAGE_REMOVED:
19167 case Intent.ACTION_PACKAGE_CHANGED:
19168 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19169 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19170 case Intent.ACTION_PACKAGES_SUSPENDED:
19171 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19172 // Handle special intents: if this broadcast is from the package
19173 // manager about a package being removed, we need to remove all of
19174 // its activities from the history stack.
19175 if (checkComponentPermission(
19176 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19177 callingPid, callingUid, -1, true)
19178 != PackageManager.PERMISSION_GRANTED) {
19179 String msg = "Permission Denial: " + intent.getAction()
19180 + " broadcast from " + callerPackage + " (pid=" + callingPid
19181 + ", uid=" + callingUid + ")"
19183 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19185 throw new SecurityException(msg);
19188 case Intent.ACTION_UID_REMOVED:
19189 final int uid = getUidFromIntent(intent);
19191 mBatteryStatsService.removeUid(uid);
19192 mAppOpsService.uidRemoved(uid);
19195 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19196 // If resources are unavailable just force stop all those packages
19197 // and flush the attribute cache as well.
19199 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19200 if (list != null && list.length > 0) {
19201 for (int i = 0; i < list.length; i++) {
19202 forceStopPackageLocked(list[i], -1, false, true, true,
19203 false, false, userId, "storage unmount");
19205 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19206 sendPackageBroadcastLocked(
19207 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19211 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19212 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19214 case Intent.ACTION_PACKAGE_REMOVED:
19215 case Intent.ACTION_PACKAGE_CHANGED:
19216 Uri data = intent.getData();
19218 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19219 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19220 final boolean replacing =
19221 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19222 final boolean killProcess =
19223 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19224 final boolean fullUninstall = removed && !replacing;
19227 forceStopPackageLocked(ssp, UserHandle.getAppId(
19228 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19229 false, true, true, false, fullUninstall, userId,
19230 removed ? "pkg removed" : "pkg changed");
19232 final int cmd = killProcess
19233 ? ApplicationThreadConstants.PACKAGE_REMOVED
19234 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19235 sendPackageBroadcastLocked(cmd,
19236 new String[] {ssp}, userId);
19237 if (fullUninstall) {
19238 mAppOpsService.packageRemoved(
19239 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19241 // Remove all permissions granted from/to this package
19242 removeUriPermissionsForPackageLocked(ssp, userId, true);
19244 removeTasksByPackageNameLocked(ssp, userId);
19246 mServices.forceStopPackageLocked(ssp, userId);
19248 // Hide the "unsupported display" dialog if necessary.
19249 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19250 mUnsupportedDisplaySizeDialog.getPackageName())) {
19251 mUnsupportedDisplaySizeDialog.dismiss();
19252 mUnsupportedDisplaySizeDialog = null;
19254 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19255 mBatteryStatsService.notePackageUninstalled(ssp);
19259 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19260 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19261 userId, ProcessList.INVALID_ADJ,
19262 false, true, true, false, "change " + ssp);
19264 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19265 intent.getStringArrayExtra(
19266 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19270 case Intent.ACTION_PACKAGES_SUSPENDED:
19271 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19272 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19273 intent.getAction());
19274 final String[] packageNames = intent.getStringArrayExtra(
19275 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19276 final int userHandle = intent.getIntExtra(
19277 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19279 synchronized(ActivityManagerService.this) {
19280 mRecentTasks.onPackagesSuspendedChanged(
19281 packageNames, suspended, userHandle);
19286 case Intent.ACTION_PACKAGE_REPLACED:
19288 final Uri data = intent.getData();
19290 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19291 ApplicationInfo aInfo = null;
19293 aInfo = AppGlobals.getPackageManager()
19294 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19295 } catch (RemoteException ignore) {}
19296 if (aInfo == null) {
19297 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19298 + " ssp=" + ssp + " data=" + data);
19299 return ActivityManager.BROADCAST_SUCCESS;
19301 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19302 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19303 new String[] {ssp}, userId);
19307 case Intent.ACTION_PACKAGE_ADDED:
19309 // Special case for adding a package: by default turn on compatibility mode.
19310 Uri data = intent.getData();
19312 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19313 final boolean replacing =
19314 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19315 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19318 ApplicationInfo ai = AppGlobals.getPackageManager().
19319 getApplicationInfo(ssp, 0, 0);
19320 mBatteryStatsService.notePackageInstalled(ssp,
19321 ai != null ? ai.versionCode : 0);
19322 } catch (RemoteException e) {
19327 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19329 Uri data = intent.getData();
19331 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19332 // Hide the "unsupported display" dialog if necessary.
19333 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19334 mUnsupportedDisplaySizeDialog.getPackageName())) {
19335 mUnsupportedDisplaySizeDialog.dismiss();
19336 mUnsupportedDisplaySizeDialog = null;
19338 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19342 case Intent.ACTION_TIMEZONE_CHANGED:
19343 // If this is the time zone changed action, queue up a message that will reset
19344 // the timezone of all currently running processes. This message will get
19345 // queued up before the broadcast happens.
19346 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19348 case Intent.ACTION_TIME_CHANGED:
19349 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19350 // the tri-state value it may contain and "unknown".
19351 // For convenience we re-use the Intent extra values.
19352 final int NO_EXTRA_VALUE_FOUND = -1;
19353 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19354 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19355 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19356 // Only send a message if the time preference is available.
19357 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19358 Message updateTimePreferenceMsg =
19359 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19360 timeFormatPreferenceMsgValue, 0);
19361 mHandler.sendMessage(updateTimePreferenceMsg);
19363 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19364 synchronized (stats) {
19365 stats.noteCurrentTimeChangedLocked();
19368 case Intent.ACTION_CLEAR_DNS_CACHE:
19369 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19371 case Proxy.PROXY_CHANGE_ACTION:
19372 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19373 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19375 case android.hardware.Camera.ACTION_NEW_PICTURE:
19376 case android.hardware.Camera.ACTION_NEW_VIDEO:
19377 // In N we just turned these off; in O we are turing them back on partly,
19378 // only for registered receivers. This will still address the main problem
19379 // (a spam of apps waking up when a picture is taken putting significant
19380 // memory pressure on the system at a bad point), while still allowing apps
19381 // that are already actively running to know about this happening.
19382 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19384 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19385 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19387 case "com.android.launcher.action.INSTALL_SHORTCUT":
19388 // As of O, we no longer support this broadcasts, even for pre-O apps.
19389 // Apps should now be using ShortcutManager.pinRequestShortcut().
19390 Log.w(TAG, "Broadcast " + action
19391 + " no longer supported. It will not be delivered.");
19392 return ActivityManager.BROADCAST_SUCCESS;
19395 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19396 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19397 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19398 final int uid = getUidFromIntent(intent);
19400 final UidRecord uidRec = mActiveUids.get(uid);
19401 if (uidRec != null) {
19402 uidRec.updateHasInternetPermission();
19408 // Add to the sticky list if requested.
19410 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19411 callingPid, callingUid)
19412 != PackageManager.PERMISSION_GRANTED) {
19413 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19414 + callingPid + ", uid=" + callingUid
19415 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19417 throw new SecurityException(msg);
19419 if (requiredPermissions != null && requiredPermissions.length > 0) {
19420 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19421 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19422 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19424 if (intent.getComponent() != null) {
19425 throw new SecurityException(
19426 "Sticky broadcasts can't target a specific component");
19428 // We use userId directly here, since the "all" target is maintained
19429 // as a separate set of sticky broadcasts.
19430 if (userId != UserHandle.USER_ALL) {
19431 // But first, if this is not a broadcast to all users, then
19432 // make sure it doesn't conflict with an existing broadcast to
19434 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19435 UserHandle.USER_ALL);
19436 if (stickies != null) {
19437 ArrayList<Intent> list = stickies.get(intent.getAction());
19438 if (list != null) {
19439 int N = list.size();
19441 for (i=0; i<N; i++) {
19442 if (intent.filterEquals(list.get(i))) {
19443 throw new IllegalArgumentException(
19444 "Sticky broadcast " + intent + " for user "
19445 + userId + " conflicts with existing global broadcast");
19451 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19452 if (stickies == null) {
19453 stickies = new ArrayMap<>();
19454 mStickyBroadcasts.put(userId, stickies);
19456 ArrayList<Intent> list = stickies.get(intent.getAction());
19457 if (list == null) {
19458 list = new ArrayList<>();
19459 stickies.put(intent.getAction(), list);
19461 final int stickiesCount = list.size();
19463 for (i = 0; i < stickiesCount; i++) {
19464 if (intent.filterEquals(list.get(i))) {
19465 // This sticky already exists, replace it.
19466 list.set(i, new Intent(intent));
19470 if (i >= stickiesCount) {
19471 list.add(new Intent(intent));
19476 if (userId == UserHandle.USER_ALL) {
19477 // Caller wants broadcast to go to all started users.
19478 users = mUserController.getStartedUserArrayLocked();
19480 // Caller wants broadcast to go to one specific user.
19481 users = new int[] {userId};
19484 // Figure out who all will receive this broadcast.
19485 List receivers = null;
19486 List<BroadcastFilter> registeredReceivers = null;
19487 // Need to resolve the intent to interested receivers...
19488 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19490 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19492 if (intent.getComponent() == null) {
19493 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19494 // Query one target user at a time, excluding shell-restricted users
19495 for (int i = 0; i < users.length; i++) {
19496 if (mUserController.hasUserRestriction(
19497 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19500 List<BroadcastFilter> registeredReceiversForUser =
19501 mReceiverResolver.queryIntent(intent,
19502 resolvedType, false /*defaultOnly*/, users[i]);
19503 if (registeredReceivers == null) {
19504 registeredReceivers = registeredReceiversForUser;
19505 } else if (registeredReceiversForUser != null) {
19506 registeredReceivers.addAll(registeredReceiversForUser);
19510 registeredReceivers = mReceiverResolver.queryIntent(intent,
19511 resolvedType, false /*defaultOnly*/, userId);
19515 final boolean replacePending =
19516 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19518 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19519 + " replacePending=" + replacePending);
19521 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19522 if (!ordered && NR > 0) {
19523 // If we are not serializing this broadcast, then send the
19524 // registered receivers separately so they don't wait for the
19525 // components to be launched.
19526 if (isCallerSystem) {
19527 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19528 isProtectedBroadcast, registeredReceivers);
19530 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19531 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19532 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19533 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19534 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19535 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19536 final boolean replaced = replacePending
19537 && (queue.replaceParallelBroadcastLocked(r) != null);
19538 // Note: We assume resultTo is null for non-ordered broadcasts.
19540 queue.enqueueParallelBroadcastLocked(r);
19541 queue.scheduleBroadcastsLocked();
19543 registeredReceivers = null;
19547 // Merge into one list.
19549 if (receivers != null) {
19550 // A special case for PACKAGE_ADDED: do not allow the package
19551 // being added to see this broadcast. This prevents them from
19552 // using this as a back door to get run as soon as they are
19553 // installed. Maybe in the future we want to have a special install
19554 // broadcast or such for apps, but we'd like to deliberately make
19556 String skipPackages[] = null;
19557 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19558 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19559 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19560 Uri data = intent.getData();
19561 if (data != null) {
19562 String pkgName = data.getSchemeSpecificPart();
19563 if (pkgName != null) {
19564 skipPackages = new String[] { pkgName };
19567 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19568 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19570 if (skipPackages != null && (skipPackages.length > 0)) {
19571 for (String skipPackage : skipPackages) {
19572 if (skipPackage != null) {
19573 int NT = receivers.size();
19574 for (int it=0; it<NT; it++) {
19575 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19576 if (curt.activityInfo.packageName.equals(skipPackage)) {
19577 receivers.remove(it);
19586 int NT = receivers != null ? receivers.size() : 0;
19588 ResolveInfo curt = null;
19589 BroadcastFilter curr = null;
19590 while (it < NT && ir < NR) {
19591 if (curt == null) {
19592 curt = (ResolveInfo)receivers.get(it);
19594 if (curr == null) {
19595 curr = registeredReceivers.get(ir);
19597 if (curr.getPriority() >= curt.priority) {
19598 // Insert this broadcast record into the final list.
19599 receivers.add(it, curr);
19605 // Skip to the next ResolveInfo in the final list.
19612 if (receivers == null) {
19613 receivers = new ArrayList();
19615 receivers.add(registeredReceivers.get(ir));
19619 if (isCallerSystem) {
19620 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19621 isProtectedBroadcast, receivers);
19624 if ((receivers != null && receivers.size() > 0)
19625 || resultTo != null) {
19626 BroadcastQueue queue = broadcastQueueForIntent(intent);
19627 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19628 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19629 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19630 resultData, resultExtras, ordered, sticky, false, userId);
19632 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19633 + ": prev had " + queue.mOrderedBroadcasts.size());
19634 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19635 "Enqueueing broadcast " + r.intent.getAction());
19637 final BroadcastRecord oldRecord =
19638 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19639 if (oldRecord != null) {
19640 // Replaced, fire the result-to receiver.
19641 if (oldRecord.resultTo != null) {
19642 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19644 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19646 Activity.RESULT_CANCELED, null, null,
19647 false, false, oldRecord.userId);
19648 } catch (RemoteException e) {
19649 Slog.w(TAG, "Failure ["
19650 + queue.mQueueName + "] sending broadcast result of "
19656 queue.enqueueOrderedBroadcastLocked(r);
19657 queue.scheduleBroadcastsLocked();
19660 // There was nobody interested in the broadcast, but we still want to record
19661 // that it happened.
19662 if (intent.getComponent() == null && intent.getPackage() == null
19663 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19664 // This was an implicit broadcast... let's record it for posterity.
19665 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19669 return ActivityManager.BROADCAST_SUCCESS;
19673 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19675 private int getUidFromIntent(Intent intent) {
19676 if (intent == null) {
19679 final Bundle intentExtras = intent.getExtras();
19680 return intent.hasExtra(Intent.EXTRA_UID)
19681 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19684 final void rotateBroadcastStatsIfNeededLocked() {
19685 final long now = SystemClock.elapsedRealtime();
19686 if (mCurBroadcastStats == null ||
19687 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19688 mLastBroadcastStats = mCurBroadcastStats;
19689 if (mLastBroadcastStats != null) {
19690 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19691 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19693 mCurBroadcastStats = new BroadcastStats();
19697 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19698 int skipCount, long dispatchTime) {
19699 rotateBroadcastStatsIfNeededLocked();
19700 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19703 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19704 rotateBroadcastStatsIfNeededLocked();
19705 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19708 final Intent verifyBroadcastLocked(Intent intent) {
19709 // Refuse possible leaked file descriptors
19710 if (intent != null && intent.hasFileDescriptors() == true) {
19711 throw new IllegalArgumentException("File descriptors passed in Intent");
19714 int flags = intent.getFlags();
19716 if (!mProcessesReady) {
19717 // if the caller really truly claims to know what they're doing, go
19718 // ahead and allow the broadcast without launching any receivers
19719 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19720 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19721 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19722 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19723 + " before boot completion");
19724 throw new IllegalStateException("Cannot broadcast before boot completed");
19728 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19729 throw new IllegalArgumentException(
19730 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19733 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19734 switch (Binder.getCallingUid()) {
19739 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19740 + Binder.getCallingUid());
19741 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19749 public final int broadcastIntent(IApplicationThread caller,
19750 Intent intent, String resolvedType, IIntentReceiver resultTo,
19751 int resultCode, String resultData, Bundle resultExtras,
19752 String[] requiredPermissions, int appOp, Bundle bOptions,
19753 boolean serialized, boolean sticky, int userId) {
19754 enforceNotIsolatedCaller("broadcastIntent");
19755 synchronized(this) {
19756 intent = verifyBroadcastLocked(intent);
19758 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19759 final int callingPid = Binder.getCallingPid();
19760 final int callingUid = Binder.getCallingUid();
19761 final long origId = Binder.clearCallingIdentity();
19762 int res = broadcastIntentLocked(callerApp,
19763 callerApp != null ? callerApp.info.packageName : null,
19764 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19765 requiredPermissions, appOp, bOptions, serialized, sticky,
19766 callingPid, callingUid, userId);
19767 Binder.restoreCallingIdentity(origId);
19773 int broadcastIntentInPackage(String packageName, int uid,
19774 Intent intent, String resolvedType, IIntentReceiver resultTo,
19775 int resultCode, String resultData, Bundle resultExtras,
19776 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19778 synchronized(this) {
19779 intent = verifyBroadcastLocked(intent);
19781 final long origId = Binder.clearCallingIdentity();
19782 String[] requiredPermissions = requiredPermission == null ? null
19783 : new String[] {requiredPermission};
19784 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19785 resultTo, resultCode, resultData, resultExtras,
19786 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19787 sticky, -1, uid, userId);
19788 Binder.restoreCallingIdentity(origId);
19793 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19794 // Refuse possible leaked file descriptors
19795 if (intent != null && intent.hasFileDescriptors() == true) {
19796 throw new IllegalArgumentException("File descriptors passed in Intent");
19799 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19800 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19802 synchronized(this) {
19803 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19804 != PackageManager.PERMISSION_GRANTED) {
19805 String msg = "Permission Denial: unbroadcastIntent() from pid="
19806 + Binder.getCallingPid()
19807 + ", uid=" + Binder.getCallingUid()
19808 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19810 throw new SecurityException(msg);
19812 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19813 if (stickies != null) {
19814 ArrayList<Intent> list = stickies.get(intent.getAction());
19815 if (list != null) {
19816 int N = list.size();
19818 for (i=0; i<N; i++) {
19819 if (intent.filterEquals(list.get(i))) {
19824 if (list.size() <= 0) {
19825 stickies.remove(intent.getAction());
19828 if (stickies.size() <= 0) {
19829 mStickyBroadcasts.remove(userId);
19835 void backgroundServicesFinishedLocked(int userId) {
19836 for (BroadcastQueue queue : mBroadcastQueues) {
19837 queue.backgroundServicesFinishedLocked(userId);
19841 public void finishReceiver(IBinder who, int resultCode, String resultData,
19842 Bundle resultExtras, boolean resultAbort, int flags) {
19843 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19845 // Refuse possible leaked file descriptors
19846 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19847 throw new IllegalArgumentException("File descriptors passed in Bundle");
19850 final long origId = Binder.clearCallingIdentity();
19852 boolean doNext = false;
19855 synchronized(this) {
19856 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19857 ? mFgBroadcastQueue : mBgBroadcastQueue;
19858 r = queue.getMatchingOrderedReceiver(who);
19860 doNext = r.queue.finishReceiverLocked(r, resultCode,
19861 resultData, resultExtras, resultAbort, true);
19866 r.queue.processNextBroadcast(false);
19868 trimApplications();
19870 Binder.restoreCallingIdentity(origId);
19874 // =========================================================
19876 // =========================================================
19878 public boolean startInstrumentation(ComponentName className,
19879 String profileFile, int flags, Bundle arguments,
19880 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19881 int userId, String abiOverride) {
19882 enforceNotIsolatedCaller("startInstrumentation");
19883 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19884 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19885 // Refuse possible leaked file descriptors
19886 if (arguments != null && arguments.hasFileDescriptors()) {
19887 throw new IllegalArgumentException("File descriptors passed in Bundle");
19890 synchronized(this) {
19891 InstrumentationInfo ii = null;
19892 ApplicationInfo ai = null;
19894 ii = mContext.getPackageManager().getInstrumentationInfo(
19895 className, STOCK_PM_FLAGS);
19896 ai = AppGlobals.getPackageManager().getApplicationInfo(
19897 ii.targetPackage, STOCK_PM_FLAGS, userId);
19898 } catch (PackageManager.NameNotFoundException e) {
19899 } catch (RemoteException e) {
19902 reportStartInstrumentationFailureLocked(watcher, className,
19903 "Unable to find instrumentation info for: " + className);
19907 reportStartInstrumentationFailureLocked(watcher, className,
19908 "Unable to find instrumentation target package: " + ii.targetPackage);
19911 if (!ai.hasCode()) {
19912 reportStartInstrumentationFailureLocked(watcher, className,
19913 "Instrumentation target has no code: " + ii.targetPackage);
19917 int match = mContext.getPackageManager().checkSignatures(
19918 ii.targetPackage, ii.packageName);
19919 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19920 String msg = "Permission Denial: starting instrumentation "
19921 + className + " from pid="
19922 + Binder.getCallingPid()
19923 + ", uid=" + Binder.getCallingPid()
19924 + " not allowed because package " + ii.packageName
19925 + " does not have a signature matching the target "
19926 + ii.targetPackage;
19927 reportStartInstrumentationFailureLocked(watcher, className, msg);
19928 throw new SecurityException(msg);
19931 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19932 activeInstr.mClass = className;
19933 String defProcess = ai.processName;;
19934 if (ii.targetProcesses == null) {
19935 activeInstr.mTargetProcesses = new String[]{ai.processName};
19936 } else if (ii.targetProcesses.equals("*")) {
19937 activeInstr.mTargetProcesses = new String[0];
19939 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19940 defProcess = activeInstr.mTargetProcesses[0];
19942 activeInstr.mTargetInfo = ai;
19943 activeInstr.mProfileFile = profileFile;
19944 activeInstr.mArguments = arguments;
19945 activeInstr.mWatcher = watcher;
19946 activeInstr.mUiAutomationConnection = uiAutomationConnection;
19947 activeInstr.mResultClass = className;
19949 final long origId = Binder.clearCallingIdentity();
19950 // Instrumentation can kill and relaunch even persistent processes
19951 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19953 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19954 app.instr = activeInstr;
19955 activeInstr.mFinished = false;
19956 activeInstr.mRunningProcesses.add(app);
19957 if (!mActiveInstrumentation.contains(activeInstr)) {
19958 mActiveInstrumentation.add(activeInstr);
19960 Binder.restoreCallingIdentity(origId);
19967 * Report errors that occur while attempting to start Instrumentation. Always writes the
19968 * error to the logs, but if somebody is watching, send the report there too. This enables
19969 * the "am" command to report errors with more information.
19971 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
19972 * @param cn The component name of the instrumentation.
19973 * @param report The error report.
19975 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19976 ComponentName cn, String report) {
19977 Slog.w(TAG, report);
19978 if (watcher != null) {
19979 Bundle results = new Bundle();
19980 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19981 results.putString("Error", report);
19982 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19986 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19987 if (app.instr == null) {
19988 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19992 if (!app.instr.mFinished && results != null) {
19993 if (app.instr.mCurResults == null) {
19994 app.instr.mCurResults = new Bundle(results);
19996 app.instr.mCurResults.putAll(results);
20001 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20002 int userId = UserHandle.getCallingUserId();
20003 // Refuse possible leaked file descriptors
20004 if (results != null && results.hasFileDescriptors()) {
20005 throw new IllegalArgumentException("File descriptors passed in Intent");
20008 synchronized(this) {
20009 ProcessRecord app = getRecordForAppLocked(target);
20011 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20014 final long origId = Binder.clearCallingIdentity();
20015 addInstrumentationResultsLocked(app, results);
20016 Binder.restoreCallingIdentity(origId);
20020 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20021 if (app.instr == null) {
20022 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20026 if (!app.instr.mFinished) {
20027 if (app.instr.mWatcher != null) {
20028 Bundle finalResults = app.instr.mCurResults;
20029 if (finalResults != null) {
20030 if (app.instr.mCurResults != null && results != null) {
20031 finalResults.putAll(results);
20034 finalResults = results;
20036 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20037 app.instr.mClass, resultCode, finalResults);
20040 // Can't call out of the system process with a lock held, so post a message.
20041 if (app.instr.mUiAutomationConnection != null) {
20042 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20043 app.instr.mUiAutomationConnection).sendToTarget();
20045 app.instr.mFinished = true;
20048 app.instr.removeProcess(app);
20051 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20055 public void finishInstrumentation(IApplicationThread target,
20056 int resultCode, Bundle results) {
20057 int userId = UserHandle.getCallingUserId();
20058 // Refuse possible leaked file descriptors
20059 if (results != null && results.hasFileDescriptors()) {
20060 throw new IllegalArgumentException("File descriptors passed in Intent");
20063 synchronized(this) {
20064 ProcessRecord app = getRecordForAppLocked(target);
20066 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20069 final long origId = Binder.clearCallingIdentity();
20070 finishInstrumentationLocked(app, resultCode, results);
20071 Binder.restoreCallingIdentity(origId);
20075 // =========================================================
20077 // =========================================================
20079 public ConfigurationInfo getDeviceConfigurationInfo() {
20080 ConfigurationInfo config = new ConfigurationInfo();
20081 synchronized (this) {
20082 final Configuration globalConfig = getGlobalConfiguration();
20083 config.reqTouchScreen = globalConfig.touchscreen;
20084 config.reqKeyboardType = globalConfig.keyboard;
20085 config.reqNavigation = globalConfig.navigation;
20086 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20087 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20088 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20090 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20091 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20092 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20094 config.reqGlEsVersion = GL_ES_VERSION;
20099 ActivityStack getFocusedStack() {
20100 return mStackSupervisor.getFocusedStack();
20104 public int getFocusedStackId() throws RemoteException {
20105 ActivityStack focusedStack = getFocusedStack();
20106 if (focusedStack != null) {
20107 return focusedStack.getStackId();
20112 public Configuration getConfiguration() {
20114 synchronized(this) {
20115 ci = new Configuration(getGlobalConfiguration());
20116 ci.userSetLocale = false;
20122 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20123 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20124 synchronized (this) {
20125 mSuppressResizeConfigChanges = suppress;
20130 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20131 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20132 * activity and clearing the task at the same time.
20135 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20136 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20137 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20138 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20140 synchronized (this) {
20141 final long origId = Binder.clearCallingIdentity();
20143 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20145 Binder.restoreCallingIdentity(origId);
20151 public void updatePersistentConfiguration(Configuration values) {
20152 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20153 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20154 if (values == null) {
20155 throw new NullPointerException("Configuration must not be null");
20158 int userId = UserHandle.getCallingUserId();
20160 synchronized(this) {
20161 updatePersistentConfigurationLocked(values, userId);
20165 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20166 final long origId = Binder.clearCallingIdentity();
20168 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20170 Binder.restoreCallingIdentity(origId);
20174 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20175 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20176 FONT_SCALE, 1.0f, userId);
20178 synchronized (this) {
20179 if (getGlobalConfiguration().fontScale == scaleFactor) {
20183 final Configuration configuration
20184 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20185 configuration.fontScale = scaleFactor;
20186 updatePersistentConfigurationLocked(configuration, userId);
20190 private void enforceWriteSettingsPermission(String func) {
20191 int uid = Binder.getCallingUid();
20192 if (uid == ROOT_UID) {
20196 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20197 Settings.getPackageNameForUid(mContext, uid), false)) {
20201 String msg = "Permission Denial: " + func + " from pid="
20202 + Binder.getCallingPid()
20204 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20206 throw new SecurityException(msg);
20210 public boolean updateConfiguration(Configuration values) {
20211 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20213 synchronized(this) {
20214 if (values == null && mWindowManager != null) {
20215 // sentinel: fetch the current configuration from the window manager
20216 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20219 if (mWindowManager != null) {
20220 // Update OOM levels based on display size.
20221 mProcessList.applyDisplaySize(mWindowManager);
20224 final long origId = Binder.clearCallingIdentity();
20226 if (values != null) {
20227 Settings.System.clearConfiguration(values);
20229 updateConfigurationLocked(values, null, false, false /* persistent */,
20230 UserHandle.USER_NULL, false /* deferResume */,
20231 mTmpUpdateConfigurationResult);
20232 return mTmpUpdateConfigurationResult.changes != 0;
20234 Binder.restoreCallingIdentity(origId);
20239 void updateUserConfigurationLocked() {
20240 final Configuration configuration = new Configuration(getGlobalConfiguration());
20241 final int currentUserId = mUserController.getCurrentUserIdLocked();
20242 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20243 currentUserId, Settings.System.canWrite(mContext));
20244 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20245 false /* persistent */, currentUserId, false /* deferResume */);
20248 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20249 boolean initLocale) {
20250 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20253 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20254 boolean initLocale, boolean deferResume) {
20255 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20256 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20257 UserHandle.USER_NULL, deferResume);
20260 // To cache the list of supported system locales
20261 private String[] mSupportedSystemLocales = null;
20263 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20264 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20265 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20266 deferResume, null /* result */);
20270 * Do either or both things: (1) change the current configuration, and (2)
20271 * make sure the given activity is running with the (now) current
20272 * configuration. Returns true if the activity has been left running, or
20273 * false if <var>starting</var> is being destroyed to match the new
20276 * @param userId is only used when persistent parameter is set to true to persist configuration
20277 * for that particular user
20279 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20280 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20281 UpdateConfigurationResult result) {
20283 boolean kept = true;
20285 if (mWindowManager != null) {
20286 mWindowManager.deferSurfaceLayout();
20289 if (values != null) {
20290 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20294 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20296 if (mWindowManager != null) {
20297 mWindowManager.continueSurfaceLayout();
20301 if (result != null) {
20302 result.changes = changes;
20303 result.activityRelaunched = !kept;
20308 /** Update default (global) configuration and notify listeners about changes. */
20309 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20310 boolean persistent, int userId, boolean deferResume) {
20311 mTempConfig.setTo(getGlobalConfiguration());
20312 final int changes = mTempConfig.updateFrom(values);
20313 if (changes == 0) {
20314 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20315 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20316 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20317 // (even if there are no actual changes) to unfreeze the window.
20318 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20322 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20323 "Updating global configuration to: " + values);
20325 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20327 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20328 final LocaleList locales = values.getLocales();
20329 int bestLocaleIndex = 0;
20330 if (locales.size() > 1) {
20331 if (mSupportedSystemLocales == null) {
20332 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20334 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20336 SystemProperties.set("persist.sys.locale",
20337 locales.get(bestLocaleIndex).toLanguageTag());
20338 LocaleList.setDefault(locales, bestLocaleIndex);
20339 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20340 locales.get(bestLocaleIndex)));
20343 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20344 mTempConfig.seq = mConfigurationSeq;
20346 // Update stored global config and notify everyone about the change.
20347 mStackSupervisor.onConfigurationChanged(mTempConfig);
20349 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20350 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20351 mUsageStatsService.reportConfigurationChange(mTempConfig,
20352 mUserController.getCurrentUserIdLocked());
20354 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20355 mShowDialogs = shouldShowDialogs(mTempConfig);
20357 AttributeCache ac = AttributeCache.instance();
20359 ac.updateConfiguration(mTempConfig);
20362 // Make sure all resources in our process are updated right now, so that anyone who is going
20363 // to retrieve resource values after we return will be sure to get the new ones. This is
20364 // especially important during boot, where the first config change needs to guarantee all
20365 // resources have that config before following boot code is executed.
20366 mSystemThread.applyConfigurationToResources(mTempConfig);
20368 // We need another copy of global config because we're scheduling some calls instead of
20369 // running them in place. We need to be sure that object we send will be handled unchanged.
20370 final Configuration configCopy = new Configuration(mTempConfig);
20371 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20372 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20373 msg.obj = configCopy;
20375 mHandler.sendMessage(msg);
20378 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20379 ProcessRecord app = mLruProcesses.get(i);
20381 if (app.thread != null) {
20382 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20383 + app.processName + " new config " + configCopy);
20384 app.thread.scheduleConfigurationChanged(configCopy);
20386 } catch (Exception e) {
20390 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20391 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20392 | Intent.FLAG_RECEIVER_FOREGROUND
20393 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20394 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20395 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20396 UserHandle.USER_ALL);
20397 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20398 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20399 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20400 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20401 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20402 if (initLocale || !mProcessesReady) {
20403 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20405 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20406 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20407 UserHandle.USER_ALL);
20410 // Override configuration of the default display duplicates global config, so we need to
20411 // update it also. This will also notify WindowManager about changes.
20412 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20419 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20420 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20422 synchronized (this) {
20423 // Check if display is initialized in AM.
20424 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20425 // Call might come when display is not yet added or has already been removed.
20426 if (DEBUG_CONFIGURATION) {
20427 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20433 if (values == null && mWindowManager != null) {
20434 // sentinel: fetch the current configuration from the window manager
20435 values = mWindowManager.computeNewConfiguration(displayId);
20438 if (mWindowManager != null) {
20439 // Update OOM levels based on display size.
20440 mProcessList.applyDisplaySize(mWindowManager);
20443 final long origId = Binder.clearCallingIdentity();
20445 if (values != null) {
20446 Settings.System.clearConfiguration(values);
20448 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20449 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20450 return mTmpUpdateConfigurationResult.changes != 0;
20452 Binder.restoreCallingIdentity(origId);
20457 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20458 boolean deferResume, int displayId) {
20459 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20460 displayId, null /* result */);
20464 * Updates override configuration specific for the selected display. If no config is provided,
20465 * new one will be computed in WM based on current display info.
20467 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20468 ActivityRecord starting, boolean deferResume, int displayId,
20469 UpdateConfigurationResult result) {
20471 boolean kept = true;
20473 if (mWindowManager != null) {
20474 mWindowManager.deferSurfaceLayout();
20477 if (values != null) {
20478 if (displayId == DEFAULT_DISPLAY) {
20479 // Override configuration of the default display duplicates global config, so
20480 // we're calling global config update instead for default display. It will also
20481 // apply the correct override config.
20482 changes = updateGlobalConfiguration(values, false /* initLocale */,
20483 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20485 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20489 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20491 if (mWindowManager != null) {
20492 mWindowManager.continueSurfaceLayout();
20496 if (result != null) {
20497 result.changes = changes;
20498 result.activityRelaunched = !kept;
20503 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20505 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20506 final int changes = mTempConfig.updateFrom(values);
20507 if (changes != 0) {
20508 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20509 + mTempConfig + " for displayId=" + displayId);
20510 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20512 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20513 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20514 // Reset the unsupported display size dialog.
20515 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20517 killAllBackgroundProcessesExcept(N,
20518 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20522 // Update the configuration with WM first and check if any of the stacks need to be resized
20523 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20524 // necessary. This way we don't need to relaunch again afterwards in
20525 // ensureActivityConfigurationLocked().
20526 if (mWindowManager != null) {
20527 final int[] resizedStacks =
20528 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20529 if (resizedStacks != null) {
20530 for (int stackId : resizedStacks) {
20531 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20539 /** Applies latest configuration and/or visibility updates if needed. */
20540 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20541 boolean kept = true;
20542 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20543 // mainStack is null during startup.
20544 if (mainStack != null) {
20545 if (changes != 0 && starting == null) {
20546 // If the configuration changed, and the caller is not already
20547 // in the process of starting an activity, then find the top
20548 // activity to check if its configuration needs to change.
20549 starting = mainStack.topRunningActivityLocked();
20552 if (starting != null) {
20553 kept = starting.ensureActivityConfigurationLocked(changes,
20554 false /* preserveWindow */);
20555 // And we need to make sure at this point that all other activities
20556 // are made visible with the correct configuration.
20557 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20558 !PRESERVE_WINDOWS);
20565 /** Helper method that requests bounds from WM and applies them to stack. */
20566 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20567 final Rect newStackBounds = new Rect();
20568 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20569 mStackSupervisor.resizeStackLocked(
20570 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20571 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20572 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20576 * Decide based on the configuration whether we should show the ANR,
20577 * crash, etc dialogs. The idea is that if there is no affordance to
20578 * press the on-screen buttons, or the user experience would be more
20579 * greatly impacted than the crash itself, we shouldn't show the dialog.
20581 * A thought: SystemUI might also want to get told about this, the Power
20582 * dialog / global actions also might want different behaviors.
20584 private static boolean shouldShowDialogs(Configuration config) {
20585 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20586 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20587 && config.navigation == Configuration.NAVIGATION_NONAV);
20588 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20589 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20590 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20591 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20592 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20593 return inputMethodExists && uiModeSupportsDialogs;
20597 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20598 synchronized (this) {
20599 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20600 if (srec != null) {
20601 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20607 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20608 Intent resultData) {
20610 synchronized (this) {
20611 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20613 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20619 public int getLaunchedFromUid(IBinder activityToken) {
20620 ActivityRecord srec;
20621 synchronized (this) {
20622 srec = ActivityRecord.forTokenLocked(activityToken);
20624 if (srec == null) {
20627 return srec.launchedFromUid;
20630 public String getLaunchedFromPackage(IBinder activityToken) {
20631 ActivityRecord srec;
20632 synchronized (this) {
20633 srec = ActivityRecord.forTokenLocked(activityToken);
20635 if (srec == null) {
20638 return srec.launchedFromPackage;
20641 // =========================================================
20642 // LIFETIME MANAGEMENT
20643 // =========================================================
20645 // Returns whether the app is receiving broadcast.
20646 // If receiving, fetch all broadcast queues which the app is
20647 // the current [or imminent] receiver on.
20648 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20649 ArraySet<BroadcastQueue> receivingQueues) {
20650 if (!app.curReceivers.isEmpty()) {
20651 for (BroadcastRecord r : app.curReceivers) {
20652 receivingQueues.add(r.queue);
20657 // It's not the current receiver, but it might be starting up to become one
20658 for (BroadcastQueue queue : mBroadcastQueues) {
20659 final BroadcastRecord r = queue.mPendingBroadcast;
20660 if (r != null && r.curApp == app) {
20661 // found it; report which queue it's in
20662 receivingQueues.add(queue);
20666 return !receivingQueues.isEmpty();
20669 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20670 int targetUid, ComponentName targetComponent, String targetProcess) {
20671 if (!mTrackingAssociations) {
20674 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20675 = mAssociations.get(targetUid);
20676 if (components == null) {
20677 components = new ArrayMap<>();
20678 mAssociations.put(targetUid, components);
20680 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20681 if (sourceUids == null) {
20682 sourceUids = new SparseArray<>();
20683 components.put(targetComponent, sourceUids);
20685 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20686 if (sourceProcesses == null) {
20687 sourceProcesses = new ArrayMap<>();
20688 sourceUids.put(sourceUid, sourceProcesses);
20690 Association ass = sourceProcesses.get(sourceProcess);
20692 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20694 sourceProcesses.put(sourceProcess, ass);
20698 if (ass.mNesting == 1) {
20699 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20700 ass.mLastState = sourceState;
20705 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20706 ComponentName targetComponent) {
20707 if (!mTrackingAssociations) {
20710 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20711 = mAssociations.get(targetUid);
20712 if (components == null) {
20715 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20716 if (sourceUids == null) {
20719 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20720 if (sourceProcesses == null) {
20723 Association ass = sourceProcesses.get(sourceProcess);
20724 if (ass == null || ass.mNesting <= 0) {
20728 if (ass.mNesting == 0) {
20729 long uptime = SystemClock.uptimeMillis();
20730 ass.mTime += uptime - ass.mStartTime;
20731 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20732 += uptime - ass.mLastStateUptime;
20733 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20737 private void noteUidProcessState(final int uid, final int state) {
20738 mBatteryStatsService.noteUidProcessState(uid, state);
20739 if (mTrackingAssociations) {
20740 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20741 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20742 = mAssociations.valueAt(i1);
20743 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20744 SparseArray<ArrayMap<String, Association>> sourceUids
20745 = targetComponents.valueAt(i2);
20746 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20747 if (sourceProcesses != null) {
20748 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20749 Association ass = sourceProcesses.valueAt(i4);
20750 if (ass.mNesting >= 1) {
20751 // currently associated
20752 long uptime = SystemClock.uptimeMillis();
20753 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20754 += uptime - ass.mLastStateUptime;
20755 ass.mLastState = state;
20756 ass.mLastStateUptime = uptime;
20765 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20766 boolean doingAll, long now) {
20767 if (mAdjSeq == app.adjSeq) {
20768 // This adjustment has already been computed.
20769 return app.curRawAdj;
20772 if (app.thread == null) {
20773 app.adjSeq = mAdjSeq;
20774 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20775 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20776 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20779 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20780 app.adjSource = null;
20781 app.adjTarget = null;
20783 app.cached = false;
20785 final int activitiesSize = app.activities.size();
20787 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20788 // The max adjustment doesn't allow this app to be anything
20789 // below foreground, so it is not worth doing work for it.
20790 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20791 app.adjType = "fixed";
20792 app.adjSeq = mAdjSeq;
20793 app.curRawAdj = app.maxAdj;
20794 app.foregroundActivities = false;
20795 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20796 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20797 // System processes can do UI, and when they do we want to have
20798 // them trim their memory after the user leaves the UI. To
20799 // facilitate this, here we need to determine whether or not it
20800 // is currently showing UI.
20801 app.systemNoUi = true;
20802 if (app == TOP_APP) {
20803 app.systemNoUi = false;
20804 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20805 app.adjType = "pers-top-activity";
20806 } else if (app.hasTopUi) {
20807 app.systemNoUi = false;
20808 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20809 app.adjType = "pers-top-ui";
20810 } else if (activitiesSize > 0) {
20811 for (int j = 0; j < activitiesSize; j++) {
20812 final ActivityRecord r = app.activities.get(j);
20814 app.systemNoUi = false;
20818 if (!app.systemNoUi) {
20819 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20821 return (app.curAdj=app.maxAdj);
20824 app.systemNoUi = false;
20826 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20828 // Determine the importance of the process, starting with most
20829 // important to least, and assign an appropriate OOM adjustment.
20833 boolean foregroundActivities = false;
20834 mTmpBroadcastQueue.clear();
20835 if (app == TOP_APP) {
20836 // The last app on the list is the foreground app.
20837 adj = ProcessList.FOREGROUND_APP_ADJ;
20838 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20839 app.adjType = "top-activity";
20840 foregroundActivities = true;
20841 procState = PROCESS_STATE_CUR_TOP;
20842 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20843 } else if (app.instr != null) {
20844 // Don't want to kill running instrumentation.
20845 adj = ProcessList.FOREGROUND_APP_ADJ;
20846 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20847 app.adjType = "instrumentation";
20848 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20849 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20850 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20851 // An app that is currently receiving a broadcast also
20852 // counts as being in the foreground for OOM killer purposes.
20853 // It's placed in a sched group based on the nature of the
20854 // broadcast as reflected by which queue it's active in.
20855 adj = ProcessList.FOREGROUND_APP_ADJ;
20856 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20857 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20858 app.adjType = "broadcast";
20859 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20860 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20861 } else if (app.executingServices.size() > 0) {
20862 // An app that is currently executing a service callback also
20863 // counts as being in the foreground.
20864 adj = ProcessList.FOREGROUND_APP_ADJ;
20865 schedGroup = app.execServicesFg ?
20866 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20867 app.adjType = "exec-service";
20868 procState = ActivityManager.PROCESS_STATE_SERVICE;
20869 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20870 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20872 // As far as we know the process is empty. We may change our mind later.
20873 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20874 // At this point we don't actually know the adjustment. Use the cached adj
20875 // value that the caller wants us to.
20877 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20880 app.adjType = "cch-empty";
20881 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20884 // Examine all activities if not already foreground.
20885 if (!foregroundActivities && activitiesSize > 0) {
20886 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20887 for (int j = 0; j < activitiesSize; j++) {
20888 final ActivityRecord r = app.activities.get(j);
20889 if (r.app != app) {
20890 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20891 + " instead of expected " + app);
20892 if (r.app == null || (r.app.uid == app.uid)) {
20893 // Only fix things up when they look sane
20900 // App has a visible activity; only upgrade adjustment.
20901 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20902 adj = ProcessList.VISIBLE_APP_ADJ;
20903 app.adjType = "vis-activity";
20904 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20906 if (procState > PROCESS_STATE_CUR_TOP) {
20907 procState = PROCESS_STATE_CUR_TOP;
20908 app.adjType = "vis-activity";
20909 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20911 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20912 app.cached = false;
20914 foregroundActivities = true;
20915 final TaskRecord task = r.getTask();
20916 if (task != null && minLayer > 0) {
20917 final int layer = task.mLayerRank;
20918 if (layer >= 0 && minLayer > layer) {
20923 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20924 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20925 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20926 app.adjType = "pause-activity";
20927 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20929 if (procState > PROCESS_STATE_CUR_TOP) {
20930 procState = PROCESS_STATE_CUR_TOP;
20931 app.adjType = "pause-activity";
20932 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20934 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20935 app.cached = false;
20937 foregroundActivities = true;
20938 } else if (r.state == ActivityState.STOPPING) {
20939 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20940 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20941 app.adjType = "stop-activity";
20942 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20944 // For the process state, we will at this point consider the
20945 // process to be cached. It will be cached either as an activity
20946 // or empty depending on whether the activity is finishing. We do
20947 // this so that we can treat the process as cached for purposes of
20948 // memory trimming (determing current memory level, trim command to
20949 // send to process) since there can be an arbitrary number of stopping
20950 // processes and they should soon all go into the cached state.
20951 if (!r.finishing) {
20952 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20953 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20954 app.adjType = "stop-activity";
20955 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20958 app.cached = false;
20960 foregroundActivities = true;
20962 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20963 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20964 app.adjType = "cch-act";
20965 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20969 if (adj == ProcessList.VISIBLE_APP_ADJ) {
20974 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20975 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20976 if (app.foregroundServices) {
20977 // The user is aware of this app, so make it visible.
20978 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20979 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20980 app.cached = false;
20981 app.adjType = "fg-service";
20982 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20983 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
20984 } else if (app.hasOverlayUi) {
20985 // The process is display an overlay UI.
20986 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20987 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20988 app.cached = false;
20989 app.adjType = "has-overlay-ui";
20990 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20991 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
20995 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20996 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
20997 if (app.forcingToImportant != null) {
20998 // This is currently used for toasts... they are not interactive, and
20999 // we don't want them to cause the app to become fully foreground (and
21000 // thus out of background check), so we yes the best background level we can.
21001 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21002 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21003 app.cached = false;
21004 app.adjType = "force-imp";
21005 app.adjSource = app.forcingToImportant;
21006 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21007 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21011 if (app == mHeavyWeightProcess) {
21012 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21013 // We don't want to kill the current heavy-weight process.
21014 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21015 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21016 app.cached = false;
21017 app.adjType = "heavy";
21018 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21020 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21021 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21022 app.adjType = "heavy";
21023 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21027 if (app == mHomeProcess) {
21028 if (adj > ProcessList.HOME_APP_ADJ) {
21029 // This process is hosting what we currently consider to be the
21030 // home app, so we don't want to let it go into the background.
21031 adj = ProcessList.HOME_APP_ADJ;
21032 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21033 app.cached = false;
21034 app.adjType = "home";
21035 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21037 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21038 procState = ActivityManager.PROCESS_STATE_HOME;
21039 app.adjType = "home";
21040 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21044 if (app == mPreviousProcess && app.activities.size() > 0) {
21045 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21046 // This was the previous process that showed UI to the user.
21047 // We want to try to keep it around more aggressively, to give
21048 // a good experience around switching between two apps.
21049 adj = ProcessList.PREVIOUS_APP_ADJ;
21050 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21051 app.cached = false;
21052 app.adjType = "previous";
21053 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21055 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21056 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21057 app.adjType = "previous";
21058 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21062 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21063 + " reason=" + app.adjType);
21065 // By default, we use the computed adjustment. It may be changed if
21066 // there are applications dependent on our services or providers, but
21067 // this gives us a baseline and makes sure we don't get into an
21068 // infinite recursion.
21069 app.adjSeq = mAdjSeq;
21070 app.curRawAdj = adj;
21071 app.hasStartedServices = false;
21073 if (mBackupTarget != null && app == mBackupTarget.app) {
21074 // If possible we want to avoid killing apps while they're being backed up
21075 if (adj > ProcessList.BACKUP_APP_ADJ) {
21076 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21077 adj = ProcessList.BACKUP_APP_ADJ;
21078 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21079 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21081 app.adjType = "backup";
21082 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21083 app.cached = false;
21085 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21086 procState = ActivityManager.PROCESS_STATE_BACKUP;
21087 app.adjType = "backup";
21088 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21092 boolean mayBeTop = false;
21093 String mayBeTopType = null;
21094 Object mayBeTopSource = null;
21095 Object mayBeTopTarget = null;
21097 for (int is = app.services.size()-1;
21098 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21099 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21100 || procState > ActivityManager.PROCESS_STATE_TOP);
21102 ServiceRecord s = app.services.valueAt(is);
21103 if (s.startRequested) {
21104 app.hasStartedServices = true;
21105 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21106 procState = ActivityManager.PROCESS_STATE_SERVICE;
21107 app.adjType = "started-services";
21108 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21110 if (app.hasShownUi && app != mHomeProcess) {
21111 // If this process has shown some UI, let it immediately
21112 // go to the LRU list because it may be pretty heavy with
21113 // UI stuff. We'll tag it with a label just to help
21114 // debug and understand what is going on.
21115 if (adj > ProcessList.SERVICE_ADJ) {
21116 app.adjType = "cch-started-ui-services";
21119 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21120 // This service has seen some activity within
21121 // recent memory, so we will keep its process ahead
21122 // of the background processes.
21123 if (adj > ProcessList.SERVICE_ADJ) {
21124 adj = ProcessList.SERVICE_ADJ;
21125 app.adjType = "started-services";
21126 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21127 app.cached = false;
21130 // If we have let the service slide into the background
21131 // state, still have some text describing what it is doing
21132 // even though the service no longer has an impact.
21133 if (adj > ProcessList.SERVICE_ADJ) {
21134 app.adjType = "cch-started-services";
21139 for (int conni = s.connections.size()-1;
21140 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21141 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21142 || procState > ActivityManager.PROCESS_STATE_TOP);
21144 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21146 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21147 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21148 || procState > ActivityManager.PROCESS_STATE_TOP);
21150 // XXX should compute this based on the max of
21151 // all connected clients.
21152 ConnectionRecord cr = clist.get(i);
21153 if (cr.binding.client == app) {
21154 // Binding to ourself is not interesting.
21158 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21159 ProcessRecord client = cr.binding.client;
21160 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21161 TOP_APP, doingAll, now);
21162 int clientProcState = client.curProcState;
21163 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21164 // If the other app is cached for any reason, for purposes here
21165 // we are going to consider it empty. The specific cached state
21166 // doesn't propagate except under certain conditions.
21167 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21169 String adjType = null;
21170 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21171 // Not doing bind OOM management, so treat
21172 // this guy more like a started service.
21173 if (app.hasShownUi && app != mHomeProcess) {
21174 // If this process has shown some UI, let it immediately
21175 // go to the LRU list because it may be pretty heavy with
21176 // UI stuff. We'll tag it with a label just to help
21177 // debug and understand what is going on.
21178 if (adj > clientAdj) {
21179 adjType = "cch-bound-ui-services";
21181 app.cached = false;
21183 clientProcState = procState;
21185 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21186 // This service has not seen activity within
21187 // recent memory, so allow it to drop to the
21188 // LRU list if there is no other reason to keep
21189 // it around. We'll also tag it with a label just
21190 // to help debug and undertand what is going on.
21191 if (adj > clientAdj) {
21192 adjType = "cch-bound-services";
21198 if (adj > clientAdj) {
21199 // If this process has recently shown UI, and
21200 // the process that is binding to it is less
21201 // important than being visible, then we don't
21202 // care about the binding as much as we care
21203 // about letting this process get into the LRU
21204 // list to be killed and restarted if needed for
21206 if (app.hasShownUi && app != mHomeProcess
21207 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21208 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21209 adjType = "cch-bound-ui-services";
21213 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21214 |Context.BIND_IMPORTANT)) != 0) {
21215 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21216 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21217 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21218 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21219 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21220 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21221 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21222 newAdj = clientAdj;
21224 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21225 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21230 if (!client.cached) {
21231 app.cached = false;
21233 if (adj > newAdj) {
21235 adjType = "service";
21239 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21240 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21241 // This will treat important bound services identically to
21242 // the top app, which may behave differently than generic
21243 // foreground work.
21244 if (client.curSchedGroup > schedGroup) {
21245 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21246 schedGroup = client.curSchedGroup;
21248 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21251 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21252 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21253 // Special handling of clients who are in the top state.
21254 // We *may* want to consider this process to be in the
21255 // top state as well, but only if there is not another
21256 // reason for it to be running. Being on the top is a
21257 // special state, meaning you are specifically running
21258 // for the current top app. If the process is already
21259 // running in the background for some other reason, it
21260 // is more important to continue considering it to be
21261 // in the background state.
21263 mayBeTopType = "service";
21264 mayBeTopSource = cr.binding.client;
21265 mayBeTopTarget = s.name;
21266 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21268 // Special handling for above-top states (persistent
21269 // processes). These should not bring the current process
21270 // into the top state, since they are not on top. Instead
21271 // give them the best state after that.
21272 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21274 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21275 } else if (mWakefulness
21276 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21277 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21280 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21283 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21287 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21288 if (clientProcState <
21289 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21291 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21294 if (clientProcState <
21295 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21297 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21300 if (procState > clientProcState) {
21301 procState = clientProcState;
21302 if (adjType == null) {
21303 adjType = "service";
21306 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21307 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21308 app.pendingUiClean = true;
21310 if (adjType != null) {
21311 app.adjType = adjType;
21312 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21313 .REASON_SERVICE_IN_USE;
21314 app.adjSource = cr.binding.client;
21315 app.adjSourceProcState = clientProcState;
21316 app.adjTarget = s.name;
21317 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21318 + ": " + app + ", due to " + cr.binding.client
21319 + " adj=" + adj + " procState=" + procState);
21322 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21323 app.treatLikeActivity = true;
21325 final ActivityRecord a = cr.activity;
21326 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21327 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21328 (a.visible || a.state == ActivityState.RESUMED ||
21329 a.state == ActivityState.PAUSING)) {
21330 adj = ProcessList.FOREGROUND_APP_ADJ;
21331 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21332 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21333 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21335 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21338 app.cached = false;
21339 app.adjType = "service";
21340 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21341 .REASON_SERVICE_IN_USE;
21343 app.adjSourceProcState = procState;
21344 app.adjTarget = s.name;
21345 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21353 for (int provi = app.pubProviders.size()-1;
21354 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21355 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21356 || procState > ActivityManager.PROCESS_STATE_TOP);
21358 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21359 for (int i = cpr.connections.size()-1;
21360 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21361 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21362 || procState > ActivityManager.PROCESS_STATE_TOP);
21364 ContentProviderConnection conn = cpr.connections.get(i);
21365 ProcessRecord client = conn.client;
21366 if (client == app) {
21367 // Being our own client is not interesting.
21370 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21371 int clientProcState = client.curProcState;
21372 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21373 // If the other app is cached for any reason, for purposes here
21374 // we are going to consider it empty.
21375 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21377 String adjType = null;
21378 if (adj > clientAdj) {
21379 if (app.hasShownUi && app != mHomeProcess
21380 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21381 adjType = "cch-ui-provider";
21383 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21384 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21385 adjType = "provider";
21387 app.cached &= client.cached;
21389 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21390 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21391 // Special handling of clients who are in the top state.
21392 // We *may* want to consider this process to be in the
21393 // top state as well, but only if there is not another
21394 // reason for it to be running. Being on the top is a
21395 // special state, meaning you are specifically running
21396 // for the current top app. If the process is already
21397 // running in the background for some other reason, it
21398 // is more important to continue considering it to be
21399 // in the background state.
21401 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21402 mayBeTopType = adjType = "provider-top";
21403 mayBeTopSource = client;
21404 mayBeTopTarget = cpr.name;
21406 // Special handling for above-top states (persistent
21407 // processes). These should not bring the current process
21408 // into the top state, since they are not on top. Instead
21409 // give them the best state after that.
21411 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21412 if (adjType == null) {
21413 adjType = "provider";
21417 if (procState > clientProcState) {
21418 procState = clientProcState;
21420 if (client.curSchedGroup > schedGroup) {
21421 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21423 if (adjType != null) {
21424 app.adjType = adjType;
21425 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21426 .REASON_PROVIDER_IN_USE;
21427 app.adjSource = client;
21428 app.adjSourceProcState = clientProcState;
21429 app.adjTarget = cpr.name;
21430 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21431 + ": " + app + ", due to " + client
21432 + " adj=" + adj + " procState=" + procState);
21435 // If the provider has external (non-framework) process
21436 // dependencies, ensure that its adjustment is at least
21437 // FOREGROUND_APP_ADJ.
21438 if (cpr.hasExternalProcessHandles()) {
21439 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21440 adj = ProcessList.FOREGROUND_APP_ADJ;
21441 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21442 app.cached = false;
21443 app.adjType = "ext-provider";
21444 app.adjTarget = cpr.name;
21445 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21447 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21448 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21453 if (app.lastProviderTime > 0 &&
21454 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21455 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21456 adj = ProcessList.PREVIOUS_APP_ADJ;
21457 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21458 app.cached = false;
21459 app.adjType = "recent-provider";
21460 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21462 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21463 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21464 app.adjType = "recent-provider";
21465 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21469 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21470 // A client of one of our services or providers is in the top state. We
21471 // *may* want to be in the top state, but not if we are already running in
21472 // the background for some other reason. For the decision here, we are going
21473 // to pick out a few specific states that we want to remain in when a client
21474 // is top (states that tend to be longer-term) and otherwise allow it to go
21475 // to the top state.
21476 switch (procState) {
21477 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21478 // Something else is keeping it at this level, just leave it.
21480 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21481 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21482 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21483 case ActivityManager.PROCESS_STATE_SERVICE:
21484 // These all are longer-term states, so pull them up to the top
21485 // of the background states, but not all the way to the top state.
21486 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21487 app.adjType = mayBeTopType;
21488 app.adjSource = mayBeTopSource;
21489 app.adjTarget = mayBeTopTarget;
21490 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21491 + ": " + app + ", due to " + mayBeTopSource
21492 + " adj=" + adj + " procState=" + procState);
21495 // Otherwise, top is a better choice, so take it.
21496 procState = ActivityManager.PROCESS_STATE_TOP;
21497 app.adjType = mayBeTopType;
21498 app.adjSource = mayBeTopSource;
21499 app.adjTarget = mayBeTopTarget;
21500 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21501 + ": " + app + ", due to " + mayBeTopSource
21502 + " adj=" + adj + " procState=" + procState);
21507 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21508 if (app.hasClientActivities) {
21509 // This is a cached process, but with client activities. Mark it so.
21510 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21511 app.adjType = "cch-client-act";
21512 } else if (app.treatLikeActivity) {
21513 // This is a cached process, but somebody wants us to treat it like it has
21514 // an activity, okay!
21515 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21516 app.adjType = "cch-as-act";
21520 if (adj == ProcessList.SERVICE_ADJ) {
21522 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21523 mNewNumServiceProcs++;
21524 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21525 if (!app.serviceb) {
21526 // This service isn't far enough down on the LRU list to
21527 // normally be a B service, but if we are low on RAM and it
21528 // is large we want to force it down since we would prefer to
21529 // keep launcher over it.
21530 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21531 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21532 app.serviceHighRam = true;
21533 app.serviceb = true;
21534 //Slog.i(TAG, "ADJ " + app + " high ram!");
21536 mNewNumAServiceProcs++;
21537 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21540 app.serviceHighRam = false;
21543 if (app.serviceb) {
21544 adj = ProcessList.SERVICE_B_ADJ;
21548 app.curRawAdj = adj;
21550 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21551 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21552 if (adj > app.maxAdj) {
21554 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21555 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21559 // Do final modification to adj. Everything we do between here and applying
21560 // the final setAdj must be done in this function, because we will also use
21561 // it when computing the final cached adj later. Note that we don't need to
21562 // worry about this for max adj above, since max adj will always be used to
21563 // keep it out of the cached vaues.
21564 app.curAdj = app.modifyRawOomAdj(adj);
21565 app.curSchedGroup = schedGroup;
21566 app.curProcState = procState;
21567 app.foregroundActivities = foregroundActivities;
21569 return app.curRawAdj;
21573 * Record new PSS sample for a process.
21575 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21577 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21579 proc.lastPssTime = now;
21580 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21581 if (DEBUG_PSS) Slog.d(TAG_PSS,
21582 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21583 + " state=" + ProcessList.makeProcStateString(procState));
21584 if (proc.initialIdlePss == 0) {
21585 proc.initialIdlePss = pss;
21587 proc.lastPss = pss;
21588 proc.lastSwapPss = swapPss;
21589 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21590 proc.lastCachedPss = pss;
21591 proc.lastCachedSwapPss = swapPss;
21594 final SparseArray<Pair<Long, String>> watchUids
21595 = mMemWatchProcesses.getMap().get(proc.processName);
21597 if (watchUids != null) {
21598 Pair<Long, String> val = watchUids.get(proc.uid);
21600 val = watchUids.get(0);
21606 if (check != null) {
21607 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21608 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21609 if (!isDebuggable) {
21610 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21611 isDebuggable = true;
21614 if (isDebuggable) {
21615 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21616 final ProcessRecord myProc = proc;
21617 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21618 mMemWatchDumpProcName = proc.processName;
21619 mMemWatchDumpFile = heapdumpFile.toString();
21620 mMemWatchDumpPid = proc.pid;
21621 mMemWatchDumpUid = proc.uid;
21622 BackgroundThread.getHandler().post(new Runnable() {
21624 public void run() {
21625 revokeUriPermission(ActivityThread.currentActivityThread()
21626 .getApplicationThread(),
21627 null, DumpHeapActivity.JAVA_URI,
21628 Intent.FLAG_GRANT_READ_URI_PERMISSION
21629 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21630 UserHandle.myUserId());
21631 ParcelFileDescriptor fd = null;
21633 heapdumpFile.delete();
21634 fd = ParcelFileDescriptor.open(heapdumpFile,
21635 ParcelFileDescriptor.MODE_CREATE |
21636 ParcelFileDescriptor.MODE_TRUNCATE |
21637 ParcelFileDescriptor.MODE_WRITE_ONLY |
21638 ParcelFileDescriptor.MODE_APPEND);
21639 IApplicationThread thread = myProc.thread;
21640 if (thread != null) {
21642 if (DEBUG_PSS) Slog.d(TAG_PSS,
21643 "Requesting dump heap from "
21644 + myProc + " to " + heapdumpFile);
21645 thread.dumpHeap(true, heapdumpFile.toString(), fd);
21646 } catch (RemoteException e) {
21649 } catch (FileNotFoundException e) {
21650 e.printStackTrace();
21655 } catch (IOException e) {
21662 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21663 + ", but debugging not enabled");
21670 * Schedule PSS collection of a process.
21672 void requestPssLocked(ProcessRecord proc, int procState) {
21673 if (mPendingPssProcesses.contains(proc)) {
21676 if (mPendingPssProcesses.size() == 0) {
21677 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21679 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21680 proc.pssProcState = procState;
21681 mPendingPssProcesses.add(proc);
21685 * Schedule PSS collection of all processes.
21687 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21689 if (now < (mLastFullPssTime +
21690 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21691 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21695 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21696 mLastFullPssTime = now;
21697 mFullPssPending = true;
21698 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21699 mPendingPssProcesses.clear();
21700 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21701 ProcessRecord app = mLruProcesses.get(i);
21702 if (app.thread == null
21703 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21706 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21707 app.pssProcState = app.setProcState;
21708 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21709 mTestPssMode, isSleepingLocked(), now);
21710 mPendingPssProcesses.add(app);
21713 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21716 public void setTestPssMode(boolean enabled) {
21717 synchronized (this) {
21718 mTestPssMode = enabled;
21720 // Whenever we enable the mode, we want to take a snapshot all of current
21721 // process mem use.
21722 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21728 * Ask a given process to GC right now.
21730 final void performAppGcLocked(ProcessRecord app) {
21732 app.lastRequestedGc = SystemClock.uptimeMillis();
21733 if (app.thread != null) {
21734 if (app.reportLowMemory) {
21735 app.reportLowMemory = false;
21736 app.thread.scheduleLowMemory();
21738 app.thread.processInBackground();
21741 } catch (Exception e) {
21747 * Returns true if things are idle enough to perform GCs.
21749 private final boolean canGcNowLocked() {
21750 boolean processingBroadcasts = false;
21751 for (BroadcastQueue q : mBroadcastQueues) {
21752 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21753 processingBroadcasts = true;
21756 return !processingBroadcasts
21757 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21761 * Perform GCs on all processes that are waiting for it, but only
21762 * if things are idle.
21764 final void performAppGcsLocked() {
21765 final int N = mProcessesToGc.size();
21769 if (canGcNowLocked()) {
21770 while (mProcessesToGc.size() > 0) {
21771 ProcessRecord proc = mProcessesToGc.remove(0);
21772 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21773 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21774 <= SystemClock.uptimeMillis()) {
21775 // To avoid spamming the system, we will GC processes one
21776 // at a time, waiting a few seconds between each.
21777 performAppGcLocked(proc);
21778 scheduleAppGcsLocked();
21781 // It hasn't been long enough since we last GCed this
21782 // process... put it in the list to wait for its time.
21783 addProcessToGcListLocked(proc);
21789 scheduleAppGcsLocked();
21794 * If all looks good, perform GCs on all processes waiting for them.
21796 final void performAppGcsIfAppropriateLocked() {
21797 if (canGcNowLocked()) {
21798 performAppGcsLocked();
21801 // Still not idle, wait some more.
21802 scheduleAppGcsLocked();
21806 * Schedule the execution of all pending app GCs.
21808 final void scheduleAppGcsLocked() {
21809 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21811 if (mProcessesToGc.size() > 0) {
21812 // Schedule a GC for the time to the next process.
21813 ProcessRecord proc = mProcessesToGc.get(0);
21814 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21816 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21817 long now = SystemClock.uptimeMillis();
21818 if (when < (now+mConstants.GC_TIMEOUT)) {
21819 when = now + mConstants.GC_TIMEOUT;
21821 mHandler.sendMessageAtTime(msg, when);
21826 * Add a process to the array of processes waiting to be GCed. Keeps the
21827 * list in sorted order by the last GC time. The process can't already be
21830 final void addProcessToGcListLocked(ProcessRecord proc) {
21831 boolean added = false;
21832 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21833 if (mProcessesToGc.get(i).lastRequestedGc <
21834 proc.lastRequestedGc) {
21836 mProcessesToGc.add(i+1, proc);
21841 mProcessesToGc.add(0, proc);
21846 * Set up to ask a process to GC itself. This will either do it
21847 * immediately, or put it on the list of processes to gc the next
21848 * time things are idle.
21850 final void scheduleAppGcLocked(ProcessRecord app) {
21851 long now = SystemClock.uptimeMillis();
21852 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21855 if (!mProcessesToGc.contains(app)) {
21856 addProcessToGcListLocked(app);
21857 scheduleAppGcsLocked();
21861 final void checkExcessivePowerUsageLocked(boolean doKills) {
21862 updateCpuStatsNow();
21864 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21865 boolean doWakeKills = doKills;
21866 boolean doCpuKills = doKills;
21867 if (mLastPowerCheckRealtime == 0) {
21868 doWakeKills = false;
21870 if (mLastPowerCheckUptime == 0) {
21871 doCpuKills = false;
21873 if (stats.isScreenOn()) {
21874 doWakeKills = false;
21876 final long curRealtime = SystemClock.elapsedRealtime();
21877 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21878 final long curUptime = SystemClock.uptimeMillis();
21879 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21880 mLastPowerCheckRealtime = curRealtime;
21881 mLastPowerCheckUptime = curUptime;
21882 if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21883 doWakeKills = false;
21885 if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21886 doCpuKills = false;
21888 int i = mLruProcesses.size();
21891 ProcessRecord app = mLruProcesses.get(i);
21892 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21894 synchronized (stats) {
21895 wtime = stats.getProcessWakeTime(app.info.uid,
21896 app.pid, curRealtime);
21898 long wtimeUsed = wtime - app.lastWakeTime;
21899 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21901 StringBuilder sb = new StringBuilder(128);
21902 sb.append("Wake for ");
21903 app.toShortString(sb);
21904 sb.append(": over ");
21905 TimeUtils.formatDuration(realtimeSince, sb);
21906 sb.append(" used ");
21907 TimeUtils.formatDuration(wtimeUsed, sb);
21909 sb.append((wtimeUsed*100)/realtimeSince);
21911 Slog.i(TAG_POWER, sb.toString());
21913 sb.append("CPU for ");
21914 app.toShortString(sb);
21915 sb.append(": over ");
21916 TimeUtils.formatDuration(uptimeSince, sb);
21917 sb.append(" used ");
21918 TimeUtils.formatDuration(cputimeUsed, sb);
21920 sb.append((cputimeUsed*100)/uptimeSince);
21922 Slog.i(TAG_POWER, sb.toString());
21924 // If a process has held a wake lock for more
21925 // than 50% of the time during this period,
21926 // that sounds bad. Kill!
21927 if (doWakeKills && realtimeSince > 0
21928 && ((wtimeUsed*100)/realtimeSince) >= 50) {
21929 synchronized (stats) {
21930 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21931 realtimeSince, wtimeUsed);
21933 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21934 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21935 } else if (doCpuKills && uptimeSince > 0
21936 && ((cputimeUsed*100)/uptimeSince) >= 25) {
21937 synchronized (stats) {
21938 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21939 uptimeSince, cputimeUsed);
21941 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21942 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21944 app.lastWakeTime = wtime;
21945 app.lastCpuTime = app.curCpuTime;
21951 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21953 boolean success = true;
21955 if (app.curRawAdj != app.setRawAdj) {
21956 app.setRawAdj = app.curRawAdj;
21961 if (app.curAdj != app.setAdj) {
21962 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21963 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21964 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21966 app.setAdj = app.curAdj;
21967 app.verifiedAdj = ProcessList.INVALID_ADJ;
21970 if (app.setSchedGroup != app.curSchedGroup) {
21971 int oldSchedGroup = app.setSchedGroup;
21972 app.setSchedGroup = app.curSchedGroup;
21973 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21974 "Setting sched group of " + app.processName
21975 + " to " + app.curSchedGroup);
21976 if (app.waitingToKill != null && app.curReceivers.isEmpty()
21977 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21978 app.kill(app.waitingToKill, true);
21982 switch (app.curSchedGroup) {
21983 case ProcessList.SCHED_GROUP_BACKGROUND:
21984 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21986 case ProcessList.SCHED_GROUP_TOP_APP:
21987 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21988 processGroup = THREAD_GROUP_TOP_APP;
21991 processGroup = THREAD_GROUP_DEFAULT;
21994 long oldId = Binder.clearCallingIdentity();
21996 setProcessGroup(app.pid, processGroup);
21997 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21998 // do nothing if we already switched to RT
21999 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22000 mVrController.onTopProcChangedLocked(app);
22001 if (mUseFifoUiScheduling) {
22002 // Switch UI pipeline for app to SCHED_FIFO
22003 app.savedPriority = Process.getThreadPriority(app.pid);
22004 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22005 if (app.renderThreadTid != 0) {
22006 scheduleAsFifoPriority(app.renderThreadTid,
22007 /* suppressLogs */true);
22008 if (DEBUG_OOM_ADJ) {
22009 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22010 app.renderThreadTid + ") to FIFO");
22013 if (DEBUG_OOM_ADJ) {
22014 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22018 // Boost priority for top app UI and render threads
22019 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22020 if (app.renderThreadTid != 0) {
22022 setThreadPriority(app.renderThreadTid,
22023 TOP_APP_PRIORITY_BOOST);
22024 } catch (IllegalArgumentException e) {
22025 // thread died, ignore
22030 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22031 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22032 mVrController.onTopProcChangedLocked(app);
22033 if (mUseFifoUiScheduling) {
22034 // Reset UI pipeline to SCHED_OTHER
22035 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22036 setThreadPriority(app.pid, app.savedPriority);
22037 if (app.renderThreadTid != 0) {
22038 setThreadScheduler(app.renderThreadTid,
22040 setThreadPriority(app.renderThreadTid, -4);
22043 // Reset priority for top app UI and render threads
22044 setThreadPriority(app.pid, 0);
22045 if (app.renderThreadTid != 0) {
22046 setThreadPriority(app.renderThreadTid, 0);
22050 } catch (Exception e) {
22052 Slog.w(TAG, "Failed setting process group of " + app.pid
22053 + " to " + app.curSchedGroup);
22054 Slog.w(TAG, "at location", e);
22057 Binder.restoreCallingIdentity(oldId);
22061 if (app.repForegroundActivities != app.foregroundActivities) {
22062 app.repForegroundActivities = app.foregroundActivities;
22063 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22065 if (app.repProcState != app.curProcState) {
22066 app.repProcState = app.curProcState;
22067 if (app.thread != null) {
22070 //RuntimeException h = new RuntimeException("here");
22071 Slog.i(TAG, "Sending new process state " + app.repProcState
22072 + " to " + app /*, h*/);
22074 app.thread.setProcessState(app.repProcState);
22075 } catch (RemoteException e) {
22079 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22080 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22081 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22082 // Experimental code to more aggressively collect pss while
22083 // running test... the problem is that this tends to collect
22084 // the data right when a process is transitioning between process
22085 // states, which well tend to give noisy data.
22086 long start = SystemClock.uptimeMillis();
22087 long pss = Debug.getPss(app.pid, mTmpLong, null);
22088 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22089 mPendingPssProcesses.remove(app);
22090 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22091 + " to " + app.curProcState + ": "
22092 + (SystemClock.uptimeMillis()-start) + "ms");
22094 app.lastStateTime = now;
22095 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22096 mTestPssMode, isSleepingLocked(), now);
22097 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22098 + ProcessList.makeProcStateString(app.setProcState) + " to "
22099 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22100 + (app.nextPssTime-now) + ": " + app);
22102 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22103 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22105 requestPssLocked(app, app.setProcState);
22106 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22107 mTestPssMode, isSleepingLocked(), now);
22108 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22109 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22111 if (app.setProcState != app.curProcState) {
22112 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22113 "Proc state change of " + app.processName
22114 + " to " + app.curProcState);
22115 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22116 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22117 if (setImportant && !curImportant) {
22118 // This app is no longer something we consider important enough to allow to
22119 // use arbitrary amounts of battery power. Note
22120 // its current wake lock time to later know to kill it if
22121 // it is not behaving well.
22122 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22123 synchronized (stats) {
22124 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
22125 app.pid, nowElapsed);
22127 app.lastCpuTime = app.curCpuTime;
22130 // Inform UsageStats of important process state change
22131 // Must be called before updating setProcState
22132 maybeUpdateUsageStatsLocked(app, nowElapsed);
22134 app.setProcState = app.curProcState;
22135 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22136 app.notCachedSinceIdle = false;
22139 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22141 app.procStateChanged = true;
22143 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22144 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22145 // For apps that sit around for a long time in the interactive state, we need
22146 // to report this at least once a day so they don't go idle.
22147 maybeUpdateUsageStatsLocked(app, nowElapsed);
22150 if (changes != 0) {
22151 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22152 "Changes in " + app + ": " + changes);
22153 int i = mPendingProcessChanges.size()-1;
22154 ProcessChangeItem item = null;
22156 item = mPendingProcessChanges.get(i);
22157 if (item.pid == app.pid) {
22158 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22159 "Re-using existing item: " + item);
22165 // No existing item in pending changes; need a new one.
22166 final int NA = mAvailProcessChanges.size();
22168 item = mAvailProcessChanges.remove(NA-1);
22169 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22170 "Retrieving available item: " + item);
22172 item = new ProcessChangeItem();
22173 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22174 "Allocating new item: " + item);
22177 item.pid = app.pid;
22178 item.uid = app.info.uid;
22179 if (mPendingProcessChanges.size() == 0) {
22180 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22181 "*** Enqueueing dispatch processes changed!");
22182 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22184 mPendingProcessChanges.add(item);
22186 item.changes |= changes;
22187 item.foregroundActivities = app.repForegroundActivities;
22188 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22189 "Item " + Integer.toHexString(System.identityHashCode(item))
22190 + " " + app.toShortString() + ": changes=" + item.changes
22191 + " foreground=" + item.foregroundActivities
22192 + " type=" + app.adjType + " source=" + app.adjSource
22193 + " target=" + app.adjTarget);
22199 private boolean isEphemeralLocked(int uid) {
22200 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22201 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22204 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22209 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22210 final UidRecord.ChangeItem pendingChange;
22211 if (uidRec == null || uidRec.pendingChange == null) {
22212 if (mPendingUidChanges.size() == 0) {
22213 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22214 "*** Enqueueing dispatch uid changed!");
22215 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22217 final int NA = mAvailUidChanges.size();
22219 pendingChange = mAvailUidChanges.remove(NA-1);
22220 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22221 "Retrieving available item: " + pendingChange);
22223 pendingChange = new UidRecord.ChangeItem();
22224 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22225 "Allocating new item: " + pendingChange);
22227 if (uidRec != null) {
22228 uidRec.pendingChange = pendingChange;
22229 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
22230 // If this uid is going away, and we haven't yet reported it is gone,
22232 change = UidRecord.CHANGE_GONE_IDLE;
22234 } else if (uid < 0) {
22235 throw new IllegalArgumentException("No UidRecord or uid");
22237 pendingChange.uidRecord = uidRec;
22238 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22239 mPendingUidChanges.add(pendingChange);
22241 pendingChange = uidRec.pendingChange;
22242 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
22243 change = UidRecord.CHANGE_GONE_IDLE;
22246 pendingChange.change = change;
22247 pendingChange.processState = uidRec != null
22248 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22249 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22250 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22251 if (uidRec != null) {
22252 uidRec.updateLastDispatchedProcStateSeq(change);
22255 // Directly update the power manager, since we sit on top of it and it is critical
22256 // it be kept in sync (so wake locks will be held as soon as appropriate).
22257 if (mLocalPowerManager != null) {
22259 case UidRecord.CHANGE_GONE:
22260 case UidRecord.CHANGE_GONE_IDLE:
22261 mLocalPowerManager.uidGone(pendingChange.uid);
22263 case UidRecord.CHANGE_IDLE:
22264 mLocalPowerManager.uidIdle(pendingChange.uid);
22266 case UidRecord.CHANGE_ACTIVE:
22267 mLocalPowerManager.uidActive(pendingChange.uid);
22270 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22271 pendingChange.processState);
22277 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22278 String authority) {
22279 if (app == null) return;
22280 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22281 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22282 if (userState == null) return;
22283 final long now = SystemClock.elapsedRealtime();
22284 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22285 if (lastReported == null || lastReported < now - 60 * 1000L) {
22286 if (mSystemReady) {
22287 // Cannot touch the user stats if not system ready
22288 mUsageStatsService.reportContentProviderUsage(
22289 authority, providerPkgName, app.userId);
22291 userState.mProviderLastReportedFg.put(authority, now);
22296 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22297 if (DEBUG_USAGE_STATS) {
22298 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22299 + "] state changes: old = " + app.setProcState + ", new = "
22300 + app.curProcState);
22302 if (mUsageStatsService == null) {
22305 boolean isInteraction;
22306 // To avoid some abuse patterns, we are going to be careful about what we consider
22307 // to be an app interaction. Being the top activity doesn't count while the display
22308 // is sleeping, nor do short foreground services.
22309 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22310 isInteraction = true;
22311 app.fgInteractionTime = 0;
22312 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22313 if (app.fgInteractionTime == 0) {
22314 app.fgInteractionTime = nowElapsed;
22315 isInteraction = false;
22317 isInteraction = nowElapsed > app.fgInteractionTime
22318 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22321 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22322 app.fgInteractionTime = 0;
22324 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22325 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22326 app.interactionEventTime = nowElapsed;
22327 String[] packages = app.getPackageList();
22328 if (packages != null) {
22329 for (int i = 0; i < packages.length; i++) {
22330 mUsageStatsService.reportEvent(packages[i], app.userId,
22331 UsageEvents.Event.SYSTEM_INTERACTION);
22335 app.reportedInteraction = isInteraction;
22336 if (!isInteraction) {
22337 app.interactionEventTime = 0;
22341 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22342 if (proc.thread != null) {
22343 if (proc.baseProcessTracker != null) {
22344 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22349 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22350 ProcessRecord TOP_APP, boolean doingAll, long now) {
22351 if (app.thread == null) {
22355 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22357 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22360 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22362 if (isForeground != proc.foregroundServices) {
22363 proc.foregroundServices = isForeground;
22364 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22366 if (isForeground) {
22367 if (curProcs == null) {
22368 curProcs = new ArrayList<ProcessRecord>();
22369 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22371 if (!curProcs.contains(proc)) {
22372 curProcs.add(proc);
22373 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22374 proc.info.packageName, proc.info.uid);
22377 if (curProcs != null) {
22378 if (curProcs.remove(proc)) {
22379 mBatteryStatsService.noteEvent(
22380 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22381 proc.info.packageName, proc.info.uid);
22382 if (curProcs.size() <= 0) {
22383 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22389 updateOomAdjLocked();
22394 private final ActivityRecord resumedAppLocked() {
22395 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22399 pkg = act.packageName;
22400 uid = act.info.applicationInfo.uid;
22405 // Has the UID or resumed package name changed?
22406 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22407 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22408 if (mCurResumedPackage != null) {
22409 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22410 mCurResumedPackage, mCurResumedUid);
22412 mCurResumedPackage = pkg;
22413 mCurResumedUid = uid;
22414 if (mCurResumedPackage != null) {
22415 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22416 mCurResumedPackage, mCurResumedUid);
22423 * Update OomAdj for a specific process.
22424 * @param app The process to update
22425 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22426 * if necessary, or skip.
22427 * @return whether updateOomAdjLocked(app) was successful.
22429 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22430 final ActivityRecord TOP_ACT = resumedAppLocked();
22431 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22432 final boolean wasCached = app.cached;
22436 // This is the desired cached adjusment we want to tell it to use.
22437 // If our app is currently cached, we know it, and that is it. Otherwise,
22438 // we don't know it yet, and it needs to now be cached we will then
22439 // need to do a complete oom adj.
22440 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22441 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22442 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22443 SystemClock.uptimeMillis());
22445 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22446 // Changed to/from cached state, so apps after it in the LRU
22447 // list may also be changed.
22448 updateOomAdjLocked();
22453 final void updateOomAdjLocked() {
22454 final ActivityRecord TOP_ACT = resumedAppLocked();
22455 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22456 final long now = SystemClock.uptimeMillis();
22457 final long nowElapsed = SystemClock.elapsedRealtime();
22458 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22459 final int N = mLruProcesses.size();
22462 RuntimeException e = new RuntimeException();
22463 e.fillInStackTrace();
22464 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22467 // Reset state in all uid records.
22468 for (int i=mActiveUids.size()-1; i>=0; i--) {
22469 final UidRecord uidRec = mActiveUids.valueAt(i);
22470 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22471 "Starting update of " + uidRec);
22475 mStackSupervisor.rankTaskLayersIfNeeded();
22478 mNewNumServiceProcs = 0;
22479 mNewNumAServiceProcs = 0;
22481 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22482 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22484 // Let's determine how many processes we have running vs.
22485 // how many slots we have for background processes; we may want
22486 // to put multiple processes in a slot of there are enough of
22488 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22489 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22490 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22491 if (numEmptyProcs > cachedProcessLimit) {
22492 // If there are more empty processes than our limit on cached
22493 // processes, then use the cached process limit for the factor.
22494 // This ensures that the really old empty processes get pushed
22495 // down to the bottom, so if we are running low on memory we will
22496 // have a better chance at keeping around more cached processes
22497 // instead of a gazillion empty processes.
22498 numEmptyProcs = cachedProcessLimit;
22500 int emptyFactor = numEmptyProcs/numSlots;
22501 if (emptyFactor < 1) emptyFactor = 1;
22502 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22503 if (cachedFactor < 1) cachedFactor = 1;
22504 int stepCached = 0;
22508 int numTrimming = 0;
22510 mNumNonCachedProcs = 0;
22511 mNumCachedHiddenProcs = 0;
22513 // First update the OOM adjustment for each of the
22514 // application processes based on their current state.
22515 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22516 int nextCachedAdj = curCachedAdj+1;
22517 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22518 int nextEmptyAdj = curEmptyAdj+2;
22519 for (int i=N-1; i>=0; i--) {
22520 ProcessRecord app = mLruProcesses.get(i);
22521 if (!app.killedByAm && app.thread != null) {
22522 app.procStateChanged = false;
22523 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22525 // If we haven't yet assigned the final cached adj
22526 // to the process, do that now.
22527 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22528 switch (app.curProcState) {
22529 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22530 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22531 // This process is a cached process holding activities...
22532 // assign it the next cached value for that type, and then
22533 // step that cached level.
22534 app.curRawAdj = curCachedAdj;
22535 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22536 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22537 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22539 if (curCachedAdj != nextCachedAdj) {
22541 if (stepCached >= cachedFactor) {
22543 curCachedAdj = nextCachedAdj;
22544 nextCachedAdj += 2;
22545 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22546 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22552 // For everything else, assign next empty cached process
22553 // level and bump that up. Note that this means that
22554 // long-running services that have dropped down to the
22555 // cached level will be treated as empty (since their process
22556 // state is still as a service), which is what we want.
22557 app.curRawAdj = curEmptyAdj;
22558 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22559 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22560 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22562 if (curEmptyAdj != nextEmptyAdj) {
22564 if (stepEmpty >= emptyFactor) {
22566 curEmptyAdj = nextEmptyAdj;
22568 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22569 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22577 applyOomAdjLocked(app, true, now, nowElapsed);
22579 // Count the number of process types.
22580 switch (app.curProcState) {
22581 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22582 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22583 mNumCachedHiddenProcs++;
22585 if (numCached > cachedProcessLimit) {
22586 app.kill("cached #" + numCached, true);
22589 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22590 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22591 && app.lastActivityTime < oldTime) {
22592 app.kill("empty for "
22593 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22594 / 1000) + "s", true);
22597 if (numEmpty > emptyProcessLimit) {
22598 app.kill("empty #" + numEmpty, true);
22603 mNumNonCachedProcs++;
22607 if (app.isolated && app.services.size() <= 0) {
22608 // If this is an isolated process, and there are no
22609 // services running in it, then the process is no longer
22610 // needed. We agressively kill these because we can by
22611 // definition not re-use the same process again, and it is
22612 // good to avoid having whatever code was running in them
22613 // left sitting around after no longer needed.
22614 app.kill("isolated not needed", true);
22616 // Keeping this process, update its uid.
22617 final UidRecord uidRec = app.uidRecord;
22618 if (uidRec != null) {
22619 uidRec.ephemeral = app.info.isInstantApp();
22620 if (uidRec.curProcState > app.curProcState) {
22621 uidRec.curProcState = app.curProcState;
22623 if (app.foregroundServices) {
22624 uidRec.foregroundServices = true;
22629 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22630 && !app.killedByAm) {
22636 incrementProcStateSeqAndNotifyAppsLocked();
22638 mNumServiceProcs = mNewNumServiceProcs;
22640 // Now determine the memory trimming level of background processes.
22641 // Unfortunately we need to start at the back of the list to do this
22642 // properly. We only do this if the number of background apps we
22643 // are managing to keep around is less than half the maximum we desire;
22644 // if we are keeping a good number around, we'll let them use whatever
22645 // memory they want.
22646 final int numCachedAndEmpty = numCached + numEmpty;
22648 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22649 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22650 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22651 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22652 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22653 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22655 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22658 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22660 // We always allow the memory level to go up (better). We only allow it to go
22661 // down if we are in a state where that is allowed, *and* the total number of processes
22662 // has gone down since last time.
22663 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22664 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22665 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22666 if (memFactor > mLastMemoryLevel) {
22667 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22668 memFactor = mLastMemoryLevel;
22669 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22672 if (memFactor != mLastMemoryLevel) {
22673 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22675 mLastMemoryLevel = memFactor;
22676 mLastNumProcesses = mLruProcesses.size();
22677 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22678 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22679 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22680 if (mLowRamStartTime == 0) {
22681 mLowRamStartTime = now;
22685 switch (memFactor) {
22686 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22687 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22689 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22690 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22693 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22696 int factor = numTrimming/3;
22698 if (mHomeProcess != null) minFactor++;
22699 if (mPreviousProcess != null) minFactor++;
22700 if (factor < minFactor) factor = minFactor;
22701 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22702 for (int i=N-1; i>=0; i--) {
22703 ProcessRecord app = mLruProcesses.get(i);
22704 if (allChanged || app.procStateChanged) {
22705 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22706 app.procStateChanged = false;
22708 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22709 && !app.killedByAm) {
22710 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22712 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22713 "Trimming memory of " + app.processName + " to " + curLevel);
22714 app.thread.scheduleTrimMemory(curLevel);
22715 } catch (RemoteException e) {
22718 // For now we won't do this; our memory trimming seems
22719 // to be good enough at this point that destroying
22720 // activities causes more harm than good.
22721 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22722 && app != mHomeProcess && app != mPreviousProcess) {
22723 // Need to do this on its own message because the stack may not
22724 // be in a consistent state at this point.
22725 // For these apps we will also finish their activities
22726 // to help them free memory.
22727 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22731 app.trimMemoryLevel = curLevel;
22733 if (step >= factor) {
22735 switch (curLevel) {
22736 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22737 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22739 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22740 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22744 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22745 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22746 && app.thread != null) {
22748 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22749 "Trimming memory of heavy-weight " + app.processName
22750 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22751 app.thread.scheduleTrimMemory(
22752 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22753 } catch (RemoteException e) {
22756 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22758 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22759 || app.systemNoUi) && app.pendingUiClean) {
22760 // If this application is now in the background and it
22761 // had done UI, then give it the special trim level to
22762 // have it free UI resources.
22763 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22764 if (app.trimMemoryLevel < level && app.thread != null) {
22766 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22767 "Trimming memory of bg-ui " + app.processName
22769 app.thread.scheduleTrimMemory(level);
22770 } catch (RemoteException e) {
22773 app.pendingUiClean = false;
22775 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22777 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22778 "Trimming memory of fg " + app.processName
22779 + " to " + fgTrimLevel);
22780 app.thread.scheduleTrimMemory(fgTrimLevel);
22781 } catch (RemoteException e) {
22784 app.trimMemoryLevel = fgTrimLevel;
22788 if (mLowRamStartTime != 0) {
22789 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22790 mLowRamStartTime = 0;
22792 for (int i=N-1; i>=0; i--) {
22793 ProcessRecord app = mLruProcesses.get(i);
22794 if (allChanged || app.procStateChanged) {
22795 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22796 app.procStateChanged = false;
22798 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22799 || app.systemNoUi) && app.pendingUiClean) {
22800 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22801 && app.thread != null) {
22803 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22804 "Trimming memory of ui hidden " + app.processName
22805 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22806 app.thread.scheduleTrimMemory(
22807 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22808 } catch (RemoteException e) {
22811 app.pendingUiClean = false;
22813 app.trimMemoryLevel = 0;
22817 if (mAlwaysFinishActivities) {
22818 // Need to do this on its own message because the stack may not
22819 // be in a consistent state at this point.
22820 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22824 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22827 // Update from any uid changes.
22828 if (mLocalPowerManager != null) {
22829 mLocalPowerManager.startUidChanges();
22831 for (int i=mActiveUids.size()-1; i>=0; i--) {
22832 final UidRecord uidRec = mActiveUids.valueAt(i);
22833 int uidChange = UidRecord.CHANGE_PROCSTATE;
22834 if (uidRec.setProcState != uidRec.curProcState
22835 || uidRec.setWhitelist != uidRec.curWhitelist) {
22836 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22837 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22838 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22839 + " to " + uidRec.curWhitelist);
22840 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22841 && !uidRec.curWhitelist) {
22842 // UID is now in the background (and not on the temp whitelist). Was it
22843 // previously in the foreground (or on the temp whitelist)?
22844 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22845 || uidRec.setWhitelist) {
22846 uidRec.lastBackgroundTime = nowElapsed;
22847 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22848 // Note: the background settle time is in elapsed realtime, while
22849 // the handler time base is uptime. All this means is that we may
22850 // stop background uids later than we had intended, but that only
22851 // happens because the device was sleeping so we are okay anyway.
22852 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22853 mConstants.BACKGROUND_SETTLE_TIME);
22858 uidChange = UidRecord.CHANGE_ACTIVE;
22859 EventLogTags.writeAmUidActive(uidRec.uid);
22860 uidRec.idle = false;
22862 uidRec.lastBackgroundTime = 0;
22864 uidRec.setProcState = uidRec.curProcState;
22865 uidRec.setWhitelist = uidRec.curWhitelist;
22866 enqueueUidChangeLocked(uidRec, -1, uidChange);
22867 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22868 if (uidRec.foregroundServices) {
22869 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22873 if (mLocalPowerManager != null) {
22874 mLocalPowerManager.finishUidChanges();
22877 if (mProcessStats.shouldWriteNowLocked(now)) {
22878 mHandler.post(new Runnable() {
22879 @Override public void run() {
22880 synchronized (ActivityManagerService.this) {
22881 mProcessStats.writeStateAsyncLocked();
22887 if (DEBUG_OOM_ADJ) {
22888 final long duration = SystemClock.uptimeMillis() - now;
22890 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22891 new RuntimeException("here").fillInStackTrace());
22893 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22899 public void makePackageIdle(String packageName, int userId) {
22900 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22901 != PackageManager.PERMISSION_GRANTED) {
22902 String msg = "Permission Denial: makePackageIdle() from pid="
22903 + Binder.getCallingPid()
22904 + ", uid=" + Binder.getCallingUid()
22905 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22907 throw new SecurityException(msg);
22909 final int callingPid = Binder.getCallingPid();
22910 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22911 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22912 long callingId = Binder.clearCallingIdentity();
22913 synchronized(this) {
22915 IPackageManager pm = AppGlobals.getPackageManager();
22918 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22919 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22920 } catch (RemoteException e) {
22922 if (pkgUid == -1) {
22923 throw new IllegalArgumentException("Unknown package name " + packageName);
22926 if (mLocalPowerManager != null) {
22927 mLocalPowerManager.startUidChanges();
22929 final int appId = UserHandle.getAppId(pkgUid);
22930 final int N = mActiveUids.size();
22931 for (int i=N-1; i>=0; i--) {
22932 final UidRecord uidRec = mActiveUids.valueAt(i);
22933 final long bgTime = uidRec.lastBackgroundTime;
22934 if (bgTime > 0 && !uidRec.idle) {
22935 if (UserHandle.getAppId(uidRec.uid) == appId) {
22936 if (userId == UserHandle.USER_ALL ||
22937 userId == UserHandle.getUserId(uidRec.uid)) {
22938 EventLogTags.writeAmUidIdle(uidRec.uid);
22939 uidRec.idle = true;
22940 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22941 + " from package " + packageName + " user " + userId);
22942 doStopUidLocked(uidRec.uid, uidRec);
22948 if (mLocalPowerManager != null) {
22949 mLocalPowerManager.finishUidChanges();
22951 Binder.restoreCallingIdentity(callingId);
22956 final void idleUids() {
22957 synchronized (this) {
22958 final int N = mActiveUids.size();
22962 final long nowElapsed = SystemClock.elapsedRealtime();
22963 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22965 if (mLocalPowerManager != null) {
22966 mLocalPowerManager.startUidChanges();
22968 for (int i=N-1; i>=0; i--) {
22969 final UidRecord uidRec = mActiveUids.valueAt(i);
22970 final long bgTime = uidRec.lastBackgroundTime;
22971 if (bgTime > 0 && !uidRec.idle) {
22972 if (bgTime <= maxBgTime) {
22973 EventLogTags.writeAmUidIdle(uidRec.uid);
22974 uidRec.idle = true;
22975 doStopUidLocked(uidRec.uid, uidRec);
22977 if (nextTime == 0 || nextTime > bgTime) {
22983 if (mLocalPowerManager != null) {
22984 mLocalPowerManager.finishUidChanges();
22986 if (nextTime > 0) {
22987 mHandler.removeMessages(IDLE_UIDS_MSG);
22988 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22989 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
22995 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22996 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22997 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23001 void incrementProcStateSeqAndNotifyAppsLocked() {
23002 if (mWaitForNetworkTimeoutMs <= 0) {
23005 // Used for identifying which uids need to block for network.
23006 ArrayList<Integer> blockingUids = null;
23007 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23008 final UidRecord uidRec = mActiveUids.valueAt(i);
23009 // If the network is not restricted for uid, then nothing to do here.
23010 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23013 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23016 // If process state is not changed, then there's nothing to do.
23017 if (uidRec.setProcState == uidRec.curProcState) {
23020 final int blockState = getBlockStateForUid(uidRec);
23021 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23022 // there's nothing the app needs to do in this scenario.
23023 if (blockState == NETWORK_STATE_NO_CHANGE) {
23026 synchronized (uidRec.networkStateLock) {
23027 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23028 if (blockState == NETWORK_STATE_BLOCK) {
23029 if (blockingUids == null) {
23030 blockingUids = new ArrayList<>();
23032 blockingUids.add(uidRec.uid);
23034 if (DEBUG_NETWORK) {
23035 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23036 + " threads for uid: " + uidRec);
23038 if (uidRec.waitingForNetwork) {
23039 uidRec.networkStateLock.notifyAll();
23045 // There are no uids that need to block, so nothing more to do.
23046 if (blockingUids == null) {
23050 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23051 final ProcessRecord app = mLruProcesses.get(i);
23052 if (!blockingUids.contains(app.uid)) {
23055 if (!app.killedByAm && app.thread != null) {
23056 final UidRecord uidRec = mActiveUids.get(app.uid);
23058 if (DEBUG_NETWORK) {
23059 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23062 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23063 } catch (RemoteException ignored) {
23070 * Checks if the uid is coming from background to foreground or vice versa and returns
23071 * appropriate block state based on this.
23073 * @return blockState based on whether the uid is coming from background to foreground or
23074 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23075 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23076 * {@link #NETWORK_STATE_NO_CHANGE}.
23079 int getBlockStateForUid(UidRecord uidRec) {
23080 // Denotes whether uid's process state is currently allowed network access.
23081 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23082 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23083 // Denotes whether uid's process state was previously allowed network access.
23084 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23085 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23087 // When the uid is coming to foreground, AMS should inform the app thread that it should
23088 // block for the network rules to get updated before launching an activity.
23089 if (!wasAllowed && isAllowed) {
23090 return NETWORK_STATE_BLOCK;
23092 // When the uid is going to background, AMS should inform the app thread that if an
23093 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23094 if (wasAllowed && !isAllowed) {
23095 return NETWORK_STATE_UNBLOCK;
23097 return NETWORK_STATE_NO_CHANGE;
23100 final void runInBackgroundDisabled(int uid) {
23101 synchronized (this) {
23102 UidRecord uidRec = mActiveUids.get(uid);
23103 if (uidRec != null) {
23104 // This uid is actually running... should it be considered background now?
23106 doStopUidLocked(uidRec.uid, uidRec);
23109 // This uid isn't actually running... still send a report about it being "stopped".
23110 doStopUidLocked(uid, null);
23115 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23116 mServices.stopInBackgroundLocked(uid);
23117 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23121 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23123 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23124 long duration, String tag) {
23125 if (DEBUG_WHITELISTS) {
23126 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23127 + targetUid + ", " + duration + ")");
23130 synchronized (mPidsSelfLocked) {
23131 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23133 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23137 if (!pr.whitelistManager) {
23138 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23139 != PackageManager.PERMISSION_GRANTED) {
23140 if (DEBUG_WHITELISTS) {
23141 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23142 + ": pid " + callerPid + " is not allowed");
23149 tempWhitelistUidLocked(targetUid, duration, tag);
23153 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23155 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23156 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23157 setUidTempWhitelistStateLocked(targetUid, true);
23158 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23161 void pushTempWhitelist() {
23163 final PendingTempWhitelist[] list;
23165 // First copy out the pending changes... we need to leave them in the map for now,
23166 // in case someone needs to check what is coming up while we don't have the lock held.
23167 synchronized(this) {
23168 N = mPendingTempWhitelist.size();
23169 list = new PendingTempWhitelist[N];
23170 for (int i = 0; i < N; i++) {
23171 list[i] = mPendingTempWhitelist.valueAt(i);
23175 // Now safely dispatch changes to device idle controller.
23176 for (int i = 0; i < N; i++) {
23177 PendingTempWhitelist ptw = list[i];
23178 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23179 ptw.duration, true, ptw.tag);
23182 // And now we can safely remove them from the map.
23183 synchronized(this) {
23184 for (int i = 0; i < N; i++) {
23185 PendingTempWhitelist ptw = list[i];
23186 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23187 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23188 mPendingTempWhitelist.removeAt(index);
23194 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23195 boolean changed = false;
23196 for (int i=mActiveUids.size()-1; i>=0; i--) {
23197 final UidRecord uidRec = mActiveUids.valueAt(i);
23198 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23199 uidRec.curWhitelist = onWhitelist;
23204 updateOomAdjLocked();
23208 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23209 boolean changed = false;
23210 final UidRecord uidRec = mActiveUids.get(uid);
23211 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23212 uidRec.curWhitelist = onWhitelist;
23213 updateOomAdjLocked();
23217 final void trimApplications() {
23218 synchronized (this) {
23221 // First remove any unused application processes whose package
23222 // has been removed.
23223 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23224 final ProcessRecord app = mRemovedProcesses.get(i);
23225 if (app.activities.size() == 0
23226 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23228 TAG, "Exiting empty application process "
23229 + app.toShortString() + " ("
23230 + (app.thread != null ? app.thread.asBinder() : null)
23232 if (app.pid > 0 && app.pid != MY_PID) {
23233 app.kill("empty", false);
23236 app.thread.scheduleExit();
23237 } catch (Exception e) {
23238 // Ignore exceptions.
23241 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23242 mRemovedProcesses.remove(i);
23244 if (app.persistent) {
23245 addAppLocked(app.info, null, false, null /* ABI override */);
23250 // Now update the oom adj for all processes.
23251 updateOomAdjLocked();
23255 /** This method sends the specified signal to each of the persistent apps */
23256 public void signalPersistentProcesses(int sig) throws RemoteException {
23257 if (sig != SIGNAL_USR1) {
23258 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23261 synchronized (this) {
23262 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23263 != PackageManager.PERMISSION_GRANTED) {
23264 throw new SecurityException("Requires permission "
23265 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23268 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23269 ProcessRecord r = mLruProcesses.get(i);
23270 if (r.thread != null && r.persistent) {
23271 sendSignal(r.pid, sig);
23277 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23278 if (proc == null || proc == mProfileProc) {
23279 proc = mProfileProc;
23280 profileType = mProfileType;
23281 clearProfilerLocked();
23283 if (proc == null) {
23287 proc.thread.profilerControl(false, null, profileType);
23288 } catch (RemoteException e) {
23289 throw new IllegalStateException("Process disappeared");
23293 private void clearProfilerLocked() {
23294 if (mProfileFd != null) {
23296 mProfileFd.close();
23297 } catch (IOException e) {
23300 mProfileApp = null;
23301 mProfileProc = null;
23302 mProfileFile = null;
23304 mAutoStopProfiler = false;
23305 mStreamingOutput = false;
23306 mSamplingInterval = 0;
23309 public boolean profileControl(String process, int userId, boolean start,
23310 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23313 synchronized (this) {
23314 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23315 // its own permission.
23316 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23317 != PackageManager.PERMISSION_GRANTED) {
23318 throw new SecurityException("Requires permission "
23319 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23322 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23323 throw new IllegalArgumentException("null profile info or fd");
23326 ProcessRecord proc = null;
23327 if (process != null) {
23328 proc = findProcessLocked(process, userId, "profileControl");
23331 if (start && (proc == null || proc.thread == null)) {
23332 throw new IllegalArgumentException("Unknown process: " + process);
23336 stopProfilerLocked(null, 0);
23337 setProfileApp(proc.info, proc.processName, profilerInfo);
23338 mProfileProc = proc;
23339 mProfileType = profileType;
23340 ParcelFileDescriptor fd = profilerInfo.profileFd;
23343 } catch (IOException e) {
23346 profilerInfo.profileFd = fd;
23347 proc.thread.profilerControl(start, profilerInfo, profileType);
23350 mProfileFd.close();
23351 } catch (IOException e) {
23355 stopProfilerLocked(proc, profileType);
23356 if (profilerInfo != null && profilerInfo.profileFd != null) {
23358 profilerInfo.profileFd.close();
23359 } catch (IOException e) {
23366 } catch (RemoteException e) {
23367 throw new IllegalStateException("Process disappeared");
23369 if (profilerInfo != null && profilerInfo.profileFd != null) {
23371 profilerInfo.profileFd.close();
23372 } catch (IOException e) {
23378 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23379 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23380 userId, true, ALLOW_FULL_ONLY, callName, null);
23381 ProcessRecord proc = null;
23383 int pid = Integer.parseInt(process);
23384 synchronized (mPidsSelfLocked) {
23385 proc = mPidsSelfLocked.get(pid);
23387 } catch (NumberFormatException e) {
23390 if (proc == null) {
23391 ArrayMap<String, SparseArray<ProcessRecord>> all
23392 = mProcessNames.getMap();
23393 SparseArray<ProcessRecord> procs = all.get(process);
23394 if (procs != null && procs.size() > 0) {
23395 proc = procs.valueAt(0);
23396 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23397 for (int i=1; i<procs.size(); i++) {
23398 ProcessRecord thisProc = procs.valueAt(i);
23399 if (thisProc.userId == userId) {
23411 public boolean dumpHeap(String process, int userId, boolean managed,
23412 String path, ParcelFileDescriptor fd) throws RemoteException {
23415 synchronized (this) {
23416 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23417 // its own permission (same as profileControl).
23418 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23419 != PackageManager.PERMISSION_GRANTED) {
23420 throw new SecurityException("Requires permission "
23421 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23425 throw new IllegalArgumentException("null fd");
23428 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23429 if (proc == null || proc.thread == null) {
23430 throw new IllegalArgumentException("Unknown process: " + process);
23433 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23434 if (!isDebuggable) {
23435 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23436 throw new SecurityException("Process not debuggable: " + proc);
23440 proc.thread.dumpHeap(managed, path, fd);
23444 } catch (RemoteException e) {
23445 throw new IllegalStateException("Process disappeared");
23450 } catch (IOException e) {
23457 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23458 String reportPackage) {
23459 if (processName != null) {
23460 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23461 "setDumpHeapDebugLimit()");
23463 synchronized (mPidsSelfLocked) {
23464 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23465 if (proc == null) {
23466 throw new SecurityException("No process found for calling pid "
23467 + Binder.getCallingPid());
23469 if (!Build.IS_DEBUGGABLE
23470 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23471 throw new SecurityException("Not running a debuggable build");
23473 processName = proc.processName;
23475 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23476 throw new SecurityException("Package " + reportPackage + " is not running in "
23481 synchronized (this) {
23482 if (maxMemSize > 0) {
23483 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23486 mMemWatchProcesses.remove(processName, uid);
23488 mMemWatchProcesses.getMap().remove(processName);
23495 public void dumpHeapFinished(String path) {
23496 synchronized (this) {
23497 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23498 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23499 + " does not match last pid " + mMemWatchDumpPid);
23502 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23503 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23504 + " does not match last path " + mMemWatchDumpFile);
23507 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23508 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23512 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23513 public void monitor() {
23514 synchronized (this) { }
23517 void onCoreSettingsChange(Bundle settings) {
23518 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23519 ProcessRecord processRecord = mLruProcesses.get(i);
23521 if (processRecord.thread != null) {
23522 processRecord.thread.setCoreSettings(settings);
23524 } catch (RemoteException re) {
23530 // Multi-user methods
23533 * Start user, if its not already running, but don't bring it to foreground.
23536 public boolean startUserInBackground(final int userId) {
23537 return mUserController.startUser(userId, /* foreground */ false);
23541 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23542 return mUserController.unlockUser(userId, token, secret, listener);
23546 public boolean switchUser(final int targetUserId) {
23547 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23549 UserInfo targetUserInfo;
23550 synchronized (this) {
23551 currentUserId = mUserController.getCurrentUserIdLocked();
23552 targetUserInfo = mUserController.getUserInfo(targetUserId);
23553 if (targetUserId == currentUserId) {
23554 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23557 if (targetUserInfo == null) {
23558 Slog.w(TAG, "No user info for user #" + targetUserId);
23561 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23562 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23563 + " when device is in demo mode");
23566 if (!targetUserInfo.supportsSwitchTo()) {
23567 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23570 if (targetUserInfo.isManagedProfile()) {
23571 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23574 mUserController.setTargetUserIdLocked(targetUserId);
23576 if (mUserController.mUserSwitchUiEnabled) {
23577 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23578 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23579 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23580 mUiHandler.sendMessage(mHandler.obtainMessage(
23581 START_USER_SWITCH_UI_MSG, userNames));
23583 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23584 mHandler.sendMessage(mHandler.obtainMessage(
23585 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23590 void scheduleStartProfilesLocked() {
23591 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23592 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23593 DateUtils.SECOND_IN_MILLIS);
23598 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23599 return mUserController.stopUser(userId, force, callback);
23603 public UserInfo getCurrentUser() {
23604 return mUserController.getCurrentUser();
23607 String getStartedUserState(int userId) {
23608 synchronized (this) {
23609 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23610 return UserState.stateToString(userState.state);
23615 public boolean isUserRunning(int userId, int flags) {
23616 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23617 && checkCallingPermission(INTERACT_ACROSS_USERS)
23618 != PackageManager.PERMISSION_GRANTED) {
23619 String msg = "Permission Denial: isUserRunning() from pid="
23620 + Binder.getCallingPid()
23621 + ", uid=" + Binder.getCallingUid()
23622 + " requires " + INTERACT_ACROSS_USERS;
23624 throw new SecurityException(msg);
23626 synchronized (this) {
23627 return mUserController.isUserRunningLocked(userId, flags);
23632 public int[] getRunningUserIds() {
23633 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23634 != PackageManager.PERMISSION_GRANTED) {
23635 String msg = "Permission Denial: isUserRunning() from pid="
23636 + Binder.getCallingPid()
23637 + ", uid=" + Binder.getCallingUid()
23638 + " requires " + INTERACT_ACROSS_USERS;
23640 throw new SecurityException(msg);
23642 synchronized (this) {
23643 return mUserController.getStartedUserArrayLocked();
23648 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23649 mUserController.registerUserSwitchObserver(observer, name);
23653 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23654 mUserController.unregisterUserSwitchObserver(observer);
23657 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23658 if (info == null) return null;
23659 ApplicationInfo newInfo = new ApplicationInfo(info);
23660 newInfo.initForUser(userId);
23664 public boolean isUserStopped(int userId) {
23665 synchronized (this) {
23666 return mUserController.getStartedUserStateLocked(userId) == null;
23670 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23672 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23676 ActivityInfo info = new ActivityInfo(aInfo);
23677 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23681 private boolean processSanityChecksLocked(ProcessRecord process) {
23682 if (process == null || process.thread == null) {
23686 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23687 if (!isDebuggable) {
23688 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23696 public boolean startBinderTracking() throws RemoteException {
23697 synchronized (this) {
23698 mBinderTransactionTrackingEnabled = true;
23699 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23700 // permission (same as profileControl).
23701 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23702 != PackageManager.PERMISSION_GRANTED) {
23703 throw new SecurityException("Requires permission "
23704 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23707 for (int i = 0; i < mLruProcesses.size(); i++) {
23708 ProcessRecord process = mLruProcesses.get(i);
23709 if (!processSanityChecksLocked(process)) {
23713 process.thread.startBinderTracking();
23714 } catch (RemoteException e) {
23715 Log.v(TAG, "Process disappared");
23722 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23724 synchronized (this) {
23725 mBinderTransactionTrackingEnabled = false;
23726 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23727 // permission (same as profileControl).
23728 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23729 != PackageManager.PERMISSION_GRANTED) {
23730 throw new SecurityException("Requires permission "
23731 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23735 throw new IllegalArgumentException("null fd");
23738 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23739 pw.println("Binder transaction traces for all processes.\n");
23740 for (ProcessRecord process : mLruProcesses) {
23741 if (!processSanityChecksLocked(process)) {
23745 pw.println("Traces for process: " + process.processName);
23748 TransferPipe tp = new TransferPipe();
23750 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23751 tp.go(fd.getFileDescriptor());
23755 } catch (IOException e) {
23756 pw.println("Failure while dumping IPC traces from " + process +
23757 ". Exception: " + e);
23759 } catch (RemoteException e) {
23760 pw.println("Got a RemoteException while dumping IPC traces from " +
23761 process + ". Exception: " + e);
23772 } catch (IOException e) {
23779 final class LocalService extends ActivityManagerInternal {
23781 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23782 int targetUserId) {
23783 synchronized (ActivityManagerService.this) {
23784 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23785 targetPkg, intent, null, targetUserId);
23790 public String checkContentProviderAccess(String authority, int userId) {
23791 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23795 public void onWakefulnessChanged(int wakefulness) {
23796 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23800 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23801 String processName, String abiOverride, int uid, Runnable crashHandler) {
23802 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23803 processName, abiOverride, uid, crashHandler);
23807 public SleepToken acquireSleepToken(String tag) {
23808 Preconditions.checkNotNull(tag);
23810 synchronized (ActivityManagerService.this) {
23811 SleepTokenImpl token = new SleepTokenImpl(tag);
23812 mSleepTokens.add(token);
23813 updateSleepIfNeededLocked();
23819 public ComponentName getHomeActivityForUser(int userId) {
23820 synchronized (ActivityManagerService.this) {
23821 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23822 return homeActivity == null ? null : homeActivity.realActivity;
23827 public void onUserRemoved(int userId) {
23828 synchronized (ActivityManagerService.this) {
23829 ActivityManagerService.this.onUserStoppedLocked(userId);
23834 public void onLocalVoiceInteractionStarted(IBinder activity,
23835 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23836 synchronized (ActivityManagerService.this) {
23837 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23838 voiceSession, voiceInteractor);
23843 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23844 synchronized (ActivityManagerService.this) {
23845 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23846 reasons, timestamp);
23851 public void notifyAppTransitionFinished() {
23852 synchronized (ActivityManagerService.this) {
23853 mStackSupervisor.notifyAppTransitionDone();
23858 public void notifyAppTransitionCancelled() {
23859 synchronized (ActivityManagerService.this) {
23860 mStackSupervisor.notifyAppTransitionDone();
23865 public List<IBinder> getTopVisibleActivities() {
23866 synchronized (ActivityManagerService.this) {
23867 return mStackSupervisor.getTopVisibleActivities();
23872 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23873 synchronized (ActivityManagerService.this) {
23874 mStackSupervisor.setDockedStackMinimized(minimized);
23879 public void killForegroundAppsForUser(int userHandle) {
23880 synchronized (ActivityManagerService.this) {
23881 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23882 final int NP = mProcessNames.getMap().size();
23883 for (int ip = 0; ip < NP; ip++) {
23884 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23885 final int NA = apps.size();
23886 for (int ia = 0; ia < NA; ia++) {
23887 final ProcessRecord app = apps.valueAt(ia);
23888 if (app.persistent) {
23889 // We don't kill persistent processes.
23894 } else if (app.userId == userHandle && app.foregroundActivities) {
23895 app.removed = true;
23901 final int N = procs.size();
23902 for (int i = 0; i < N; i++) {
23903 removeProcessLocked(procs.get(i), false, true, "kill all fg");
23909 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23911 if (!(target instanceof PendingIntentRecord)) {
23912 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23915 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23919 public void setDeviceIdleWhitelist(int[] appids) {
23920 synchronized (ActivityManagerService.this) {
23921 mDeviceIdleWhitelist = appids;
23926 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23927 synchronized (ActivityManagerService.this) {
23928 mDeviceIdleTempWhitelist = appids;
23929 setAppIdTempWhitelistStateLocked(changingAppId, adding);
23934 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23936 Preconditions.checkNotNull(values, "Configuration must not be null");
23937 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23938 synchronized (ActivityManagerService.this) {
23939 updateConfigurationLocked(values, null, false, true, userId,
23940 false /* deferResume */);
23945 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23947 Preconditions.checkNotNull(intents, "intents");
23948 final String[] resolvedTypes = new String[intents.length];
23949 for (int i = 0; i < intents.length; i++) {
23950 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23953 // UID of the package on user userId.
23954 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23955 // packageUid may not be initialized.
23956 int packageUid = 0;
23958 packageUid = AppGlobals.getPackageManager().getPackageUid(
23959 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23960 } catch (RemoteException e) {
23961 // Shouldn't happen.
23964 synchronized (ActivityManagerService.this) {
23965 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23966 /*resultTo*/ null, bOptions, userId);
23971 public int getUidProcessState(int uid) {
23972 return getUidState(uid);
23976 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23977 synchronized (ActivityManagerService.this) {
23979 // We might change the visibilities here, so prepare an empty app transition which
23980 // might be overridden later if we actually change visibilities.
23981 mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23982 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23983 mWindowManager.executeAppTransition();
23985 if (callback != null) {
23991 public boolean isSystemReady() {
23992 // no need to synchronize(this) just to read & return the value
23993 return mSystemReady;
23997 public void notifyKeyguardTrustedChanged() {
23998 synchronized (ActivityManagerService.this) {
23999 if (mKeyguardController.isKeyguardShowing()) {
24000 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24006 * Sets if the given pid has an overlay UI or not.
24008 * @param pid The pid we are setting overlay UI for.
24009 * @param hasOverlayUi True if the process has overlay UI.
24010 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24013 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24014 synchronized (ActivityManagerService.this) {
24015 final ProcessRecord pr;
24016 synchronized (mPidsSelfLocked) {
24017 pr = mPidsSelfLocked.get(pid);
24019 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24023 if (pr.hasOverlayUi == hasOverlayUi) {
24026 pr.hasOverlayUi = hasOverlayUi;
24027 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24028 updateOomAdjLocked(pr, true);
24033 * Called after the network policy rules are updated by
24034 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24035 * and {@param procStateSeq}.
24038 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24039 if (DEBUG_NETWORK) {
24040 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24041 + uid + " seq: " + procStateSeq);
24044 synchronized (ActivityManagerService.this) {
24045 record = mActiveUids.get(uid);
24046 if (record == null) {
24047 if (DEBUG_NETWORK) {
24048 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24049 + " procStateSeq: " + procStateSeq);
24054 synchronized (record.networkStateLock) {
24055 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24056 if (DEBUG_NETWORK) {
24057 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24058 + " been handled for uid: " + uid);
24062 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24063 if (record.curProcStateSeq > procStateSeq) {
24064 if (DEBUG_NETWORK) {
24065 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24066 + ", curProcstateSeq: " + record.curProcStateSeq
24067 + ", procStateSeq: " + procStateSeq);
24071 if (record.waitingForNetwork) {
24072 if (DEBUG_NETWORK) {
24073 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24074 + ", procStateSeq: " + procStateSeq);
24076 record.networkStateLock.notifyAll();
24082 * Called after virtual display Id is updated by
24083 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24084 * {@param vrVr2dDisplayId}.
24087 public void setVr2dDisplayId(int vr2dDisplayId) {
24089 Slog.d(TAG, "setVr2dDisplayId called for: " +
24092 synchronized (ActivityManagerService.this) {
24093 mVr2dDisplayId = vr2dDisplayId;
24098 public void saveANRState(String reason) {
24099 synchronized (ActivityManagerService.this) {
24100 final StringWriter sw = new StringWriter();
24101 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24102 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24103 if (reason != null) {
24104 pw.println(" Reason: " + reason);
24107 mActivityStarter.dump(pw, " ");
24109 pw.println("-------------------------------------------------------------------------------");
24110 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24111 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24116 mLastANRState = sw.toString();
24121 public void clearSavedANRState() {
24122 synchronized (ActivityManagerService.this) {
24123 mLastANRState = null;
24129 * Called by app main thread to wait for the network policy rules to get updated.
24131 * @param procStateSeq The sequence number indicating the process state change that the main
24132 * thread is interested in.
24135 public void waitForNetworkStateUpdate(long procStateSeq) {
24136 final int callingUid = Binder.getCallingUid();
24137 if (DEBUG_NETWORK) {
24138 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24141 synchronized (this) {
24142 record = mActiveUids.get(callingUid);
24143 if (record == null) {
24147 synchronized (record.networkStateLock) {
24148 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24149 if (DEBUG_NETWORK) {
24150 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24151 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24152 + " lastProcStateSeqDispatchedToObservers: "
24153 + record.lastDispatchedProcStateSeq);
24157 if (record.curProcStateSeq > procStateSeq) {
24158 if (DEBUG_NETWORK) {
24159 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24160 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24161 + ", procStateSeq: " + procStateSeq);
24165 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24166 if (DEBUG_NETWORK) {
24167 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24168 + procStateSeq + ", so no need to wait. Uid: "
24169 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24170 + record.lastNetworkUpdatedProcStateSeq);
24175 if (DEBUG_NETWORK) {
24176 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24177 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24179 final long startTime = SystemClock.uptimeMillis();
24180 record.waitingForNetwork = true;
24181 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24182 record.waitingForNetwork = false;
24183 final long totalTime = SystemClock.uptimeMillis() - startTime;
24184 if (totalTime >= mWaitForNetworkTimeoutMs) {
24185 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24186 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24187 + procStateSeq + " UidRec: " + record
24188 + " validateUidRec: " + mValidateUids.get(callingUid));
24190 } catch (InterruptedException e) {
24191 Thread.currentThread().interrupt();
24196 public void waitForBroadcastIdle(PrintWriter pw) {
24197 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24199 boolean idle = true;
24200 synchronized (this) {
24201 for (BroadcastQueue queue : mBroadcastQueues) {
24202 if (!queue.isIdle()) {
24203 final String msg = "Waiting for queue " + queue + " to become idle...";
24213 final String msg = "All broadcast queues are idle!";
24219 SystemClock.sleep(1000);
24225 * Return the user id of the last resumed activity.
24228 public @UserIdInt int getLastResumedActivityUserId() {
24229 enforceCallingPermission(
24230 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24231 synchronized (this) {
24232 if (mLastResumedActivity == null) {
24233 return mUserController.getCurrentUserIdLocked();
24235 return mLastResumedActivity.userId;
24239 private final class SleepTokenImpl extends SleepToken {
24240 private final String mTag;
24241 private final long mAcquireTime;
24243 public SleepTokenImpl(String tag) {
24245 mAcquireTime = SystemClock.uptimeMillis();
24249 public void release() {
24250 synchronized (ActivityManagerService.this) {
24251 if (mSleepTokens.remove(this)) {
24252 updateSleepIfNeededLocked();
24258 public String toString() {
24259 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
24264 * An implementation of IAppTask, that allows an app to manage its own tasks via
24265 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24266 * only the process that calls getAppTasks() can call the AppTask methods.
24268 class AppTaskImpl extends IAppTask.Stub {
24269 private int mTaskId;
24270 private int mCallingUid;
24272 public AppTaskImpl(int taskId, int callingUid) {
24274 mCallingUid = callingUid;
24277 private void checkCaller() {
24278 if (mCallingUid != Binder.getCallingUid()) {
24279 throw new SecurityException("Caller " + mCallingUid
24280 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24285 public void finishAndRemoveTask() {
24288 synchronized (ActivityManagerService.this) {
24289 long origId = Binder.clearCallingIdentity();
24291 // We remove the task from recents to preserve backwards
24292 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24293 REMOVE_FROM_RECENTS)) {
24294 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24297 Binder.restoreCallingIdentity(origId);
24303 public ActivityManager.RecentTaskInfo getTaskInfo() {
24306 synchronized (ActivityManagerService.this) {
24307 long origId = Binder.clearCallingIdentity();
24309 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24311 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24313 return createRecentTaskInfoFromTaskRecord(tr);
24315 Binder.restoreCallingIdentity(origId);
24321 public void moveToFront() {
24323 // Will bring task to front if it already has a root activity.
24324 final long origId = Binder.clearCallingIdentity();
24326 synchronized (this) {
24327 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24330 Binder.restoreCallingIdentity(origId);
24335 public int startActivity(IBinder whoThread, String callingPackage,
24336 Intent intent, String resolvedType, Bundle bOptions) {
24339 int callingUser = UserHandle.getCallingUserId();
24341 IApplicationThread appThread;
24342 synchronized (ActivityManagerService.this) {
24343 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24345 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24347 appThread = IApplicationThread.Stub.asInterface(whoThread);
24348 if (appThread == null) {
24349 throw new IllegalArgumentException("Bad app thread " + appThread);
24352 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24353 resolvedType, null, null, null, null, 0, 0, null, null,
24354 null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
24358 public void setExcludeFromRecents(boolean exclude) {
24361 synchronized (ActivityManagerService.this) {
24362 long origId = Binder.clearCallingIdentity();
24364 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24366 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24368 Intent intent = tr.getBaseIntent();
24370 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24372 intent.setFlags(intent.getFlags()
24373 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24376 Binder.restoreCallingIdentity(origId);
24383 * Kill processes for the user with id userId and that depend on the package named packageName
24386 public void killPackageDependents(String packageName, int userId) {
24387 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24388 if (packageName == null) {
24389 throw new NullPointerException(
24390 "Cannot kill the dependents of a package without its name.");
24393 long callingId = Binder.clearCallingIdentity();
24394 IPackageManager pm = AppGlobals.getPackageManager();
24397 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24398 } catch (RemoteException e) {
24400 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24401 throw new IllegalArgumentException(
24402 "Cannot kill dependents of non-existing package " + packageName);
24405 synchronized(this) {
24406 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24407 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24408 "dep: " + packageName);
24411 Binder.restoreCallingIdentity(callingId);
24416 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24417 throws RemoteException {
24418 final long callingId = Binder.clearCallingIdentity();
24420 mKeyguardController.dismissKeyguard(token, callback);
24422 Binder.restoreCallingIdentity(callingId);
24427 public int restartUserInBackground(final int userId) {
24428 return mUserController.restartUser(userId, /* foreground */ false);
24432 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24433 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24434 "scheduleApplicationInfoChanged()");
24436 synchronized (this) {
24437 final long origId = Binder.clearCallingIdentity();
24439 updateApplicationInfoLocked(packageNames, userId);
24441 Binder.restoreCallingIdentity(origId);
24446 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24447 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24448 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24449 final ProcessRecord app = mLruProcesses.get(i);
24450 if (app.thread == null) {
24454 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24458 final int packageCount = app.pkgList.size();
24459 for (int j = 0; j < packageCount; j++) {
24460 final String packageName = app.pkgList.keyAt(j);
24461 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24463 final ApplicationInfo ai = AppGlobals.getPackageManager()
24464 .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24466 app.thread.scheduleApplicationInfoChanged(ai);
24468 } catch (RemoteException e) {
24469 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24470 packageName, app));
24478 * Attach an agent to the specified process (proces name or PID)
24480 public void attachAgent(String process, String path) {
24482 synchronized (this) {
24483 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24484 if (proc == null || proc.thread == null) {
24485 throw new IllegalArgumentException("Unknown process: " + process);
24488 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24489 if (!isDebuggable) {
24490 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24491 throw new SecurityException("Process not debuggable: " + proc);
24495 proc.thread.attachAgent(path);
24497 } catch (RemoteException e) {
24498 throw new IllegalStateException("Process disappeared");
24503 public static class Injector {
24504 private NetworkManagementInternal mNmi;
24506 public Context getContext() {
24510 public AppOpsService getAppOpsService(File file, Handler handler) {
24511 return new AppOpsService(file, handler);
24514 public Handler getUiHandler(ActivityManagerService service) {
24515 return service.new UiHandler();
24518 public boolean isNetworkRestrictedForUid(int uid) {
24519 if (ensureHasNetworkManagementInternal()) {
24520 return mNmi.isNetworkRestrictedForUid(uid);
24525 private boolean ensureHasNetworkManagementInternal() {
24526 if (mNmi == null) {
24527 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24529 return mNmi != null;