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.INTERNAL_SYSTEM_WINDOW;
24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25 import static android.Manifest.permission.READ_FRAME_BUFFER;
26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
32 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
33 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
34 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
35 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
36 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
37 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
38 import static android.content.pm.PackageManager.GET_PROVIDERS;
39 import static android.content.pm.PackageManager.MATCH_ANY_USER;
40 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
41 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
43 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
44 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
45 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
46 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
47 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
49 import static android.os.Build.VERSION_CODES.N;
50 import static android.os.Process.BLUETOOTH_UID;
51 import static android.os.Process.FIRST_APPLICATION_UID;
52 import static android.os.Process.FIRST_ISOLATED_UID;
53 import static android.os.Process.LAST_ISOLATED_UID;
54 import static android.os.Process.NFC_UID;
55 import static android.os.Process.PHONE_UID;
56 import static android.os.Process.PROC_CHAR;
57 import static android.os.Process.PROC_OUT_LONG;
58 import static android.os.Process.PROC_PARENS;
59 import static android.os.Process.PROC_SPACE_TERM;
60 import static android.os.Process.ProcessStartResult;
61 import static android.os.Process.ROOT_UID;
62 import static android.os.Process.SCHED_FIFO;
63 import static android.os.Process.SCHED_OTHER;
64 import static android.os.Process.SCHED_RESET_ON_FORK;
65 import static android.os.Process.SHELL_UID;
66 import static android.os.Process.SIGNAL_QUIT;
67 import static android.os.Process.SIGNAL_USR1;
68 import static android.os.Process.SYSTEM_UID;
69 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
70 import static android.os.Process.THREAD_GROUP_DEFAULT;
71 import static android.os.Process.THREAD_GROUP_TOP_APP;
72 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
73 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
74 import static android.os.Process.getFreeMemory;
75 import static android.os.Process.getTotalMemory;
76 import static android.os.Process.isThreadInProcess;
77 import static android.os.Process.killProcess;
78 import static android.os.Process.killProcessQuiet;
79 import static android.os.Process.myPid;
80 import static android.os.Process.myUid;
81 import static android.os.Process.readProcFile;
82 import static android.os.Process.removeAllProcessGroups;
83 import static android.os.Process.sendSignal;
84 import static android.os.Process.setProcessGroup;
85 import static android.os.Process.setThreadPriority;
86 import static android.os.Process.setThreadScheduler;
87 import static android.os.Process.startWebView;
88 import static android.os.Process.zygoteProcess;
89 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
90 import static android.provider.Settings.Global.DEBUG_APP;
91 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
92 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
94 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
95 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
96 import static android.provider.Settings.System.FONT_SCALE;
97 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
98 import static android.view.Display.DEFAULT_DISPLAY;
99 import static android.view.Display.INVALID_DISPLAY;
100 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
101 import static com.android.internal.util.XmlUtils.readIntAttribute;
102 import static com.android.internal.util.XmlUtils.readLongAttribute;
103 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
104 import static com.android.internal.util.XmlUtils.writeIntAttribute;
105 import static com.android.internal.util.XmlUtils.writeLongAttribute;
106 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
107 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
140 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
165 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
167 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188 import static org.xmlpull.v1.XmlPullParser.START_TAG;
190 import android.Manifest;
191 import android.Manifest.permission;
192 import android.annotation.NonNull;
193 import android.annotation.Nullable;
194 import android.annotation.UserIdInt;
195 import android.app.Activity;
196 import android.app.ActivityManager;
197 import android.app.ActivityManager.RunningTaskInfo;
198 import android.app.ActivityManager.StackId;
199 import android.app.ActivityManager.StackInfo;
200 import android.app.ActivityManager.TaskSnapshot;
201 import android.app.ActivityManager.TaskThumbnailInfo;
202 import android.app.ActivityManagerInternal;
203 import android.app.ActivityManagerInternal.SleepToken;
204 import android.app.ActivityOptions;
205 import android.app.ActivityThread;
206 import android.app.AlertDialog;
207 import android.app.AppGlobals;
208 import android.app.AppOpsManager;
209 import android.app.ApplicationErrorReport;
210 import android.app.ApplicationThreadConstants;
211 import android.app.BroadcastOptions;
212 import android.app.ContentProviderHolder;
213 import android.app.Dialog;
214 import android.app.IActivityContainer;
215 import android.app.IActivityContainerCallback;
216 import android.app.IActivityController;
217 import android.app.IActivityManager;
218 import android.app.IAppTask;
219 import android.app.IApplicationThread;
220 import android.app.IInstrumentationWatcher;
221 import android.app.INotificationManager;
222 import android.app.IProcessObserver;
223 import android.app.IServiceConnection;
224 import android.app.IStopUserCallback;
225 import android.app.ITaskStackListener;
226 import android.app.IUiAutomationConnection;
227 import android.app.IUidObserver;
228 import android.app.IUserSwitchObserver;
229 import android.app.Instrumentation;
230 import android.app.Notification;
231 import android.app.NotificationManager;
232 import android.app.PendingIntent;
233 import android.app.PictureInPictureParams;
234 import android.app.ProfilerInfo;
235 import android.app.RemoteAction;
236 import android.app.WaitResult;
237 import android.app.admin.DevicePolicyManager;
238 import android.app.assist.AssistContent;
239 import android.app.assist.AssistStructure;
240 import android.app.backup.IBackupManager;
241 import android.app.usage.UsageEvents;
242 import android.app.usage.UsageStatsManagerInternal;
243 import android.appwidget.AppWidgetManager;
244 import android.content.ActivityNotFoundException;
245 import android.content.BroadcastReceiver;
246 import android.content.ClipData;
247 import android.content.ComponentCallbacks2;
248 import android.content.ComponentName;
249 import android.content.ContentProvider;
250 import android.content.ContentResolver;
251 import android.content.Context;
252 import android.content.DialogInterface;
253 import android.content.IContentProvider;
254 import android.content.IIntentReceiver;
255 import android.content.IIntentSender;
256 import android.content.Intent;
257 import android.content.IntentFilter;
258 import android.content.IntentSender;
259 import android.content.pm.ActivityInfo;
260 import android.content.pm.ApplicationInfo;
261 import android.content.pm.ConfigurationInfo;
262 import android.content.pm.IPackageDataObserver;
263 import android.content.pm.IPackageManager;
264 import android.content.pm.InstrumentationInfo;
265 import android.content.pm.PackageInfo;
266 import android.content.pm.PackageManager;
267 import android.content.pm.PackageManager.NameNotFoundException;
268 import android.content.pm.PackageManagerInternal;
269 import android.content.pm.ParceledListSlice;
270 import android.content.pm.PathPermission;
271 import android.content.pm.PermissionInfo;
272 import android.content.pm.ProviderInfo;
273 import android.content.pm.ResolveInfo;
274 import android.content.pm.SELinuxUtil;
275 import android.content.pm.ServiceInfo;
276 import android.content.pm.UserInfo;
277 import android.content.res.CompatibilityInfo;
278 import android.content.res.Configuration;
279 import android.content.res.Resources;
280 import android.database.ContentObserver;
281 import android.graphics.Bitmap;
282 import android.graphics.Point;
283 import android.graphics.Rect;
284 import android.location.LocationManager;
285 import android.media.audiofx.AudioEffect;
286 import android.metrics.LogMaker;
287 import android.net.Proxy;
288 import android.net.ProxyInfo;
289 import android.net.Uri;
290 import android.os.BatteryStats;
291 import android.os.Binder;
292 import android.os.Build;
293 import android.os.Bundle;
294 import android.os.Debug;
295 import android.os.DropBoxManager;
296 import android.os.Environment;
297 import android.os.FactoryTest;
298 import android.os.FileObserver;
299 import android.os.FileUtils;
300 import android.os.Handler;
301 import android.os.IBinder;
302 import android.os.IDeviceIdentifiersPolicyService;
303 import android.os.IPermissionController;
304 import android.os.IProcessInfoService;
305 import android.os.IProgressListener;
306 import android.os.LocaleList;
307 import android.os.Looper;
308 import android.os.Message;
309 import android.os.Parcel;
310 import android.os.ParcelFileDescriptor;
311 import android.os.PersistableBundle;
312 import android.os.PowerManager;
313 import android.os.PowerManagerInternal;
314 import android.os.Process;
315 import android.os.RemoteCallbackList;
316 import android.os.RemoteException;
317 import android.os.ResultReceiver;
318 import android.os.ServiceManager;
319 import android.os.ShellCallback;
320 import android.os.StrictMode;
321 import android.os.SystemClock;
322 import android.os.SystemProperties;
323 import android.os.Trace;
324 import android.os.TransactionTooLargeException;
325 import android.os.UpdateLock;
326 import android.os.UserHandle;
327 import android.os.UserManager;
328 import android.os.WorkSource;
329 import android.os.storage.IStorageManager;
330 import android.os.storage.StorageManager;
331 import android.os.storage.StorageManagerInternal;
332 import android.provider.Downloads;
333 import android.provider.Settings;
334 import android.service.voice.IVoiceInteractionSession;
335 import android.service.voice.VoiceInteractionManagerInternal;
336 import android.service.voice.VoiceInteractionSession;
337 import android.telecom.TelecomManager;
338 import android.text.TextUtils;
339 import android.text.format.DateUtils;
340 import android.text.format.Time;
341 import android.text.style.SuggestionSpan;
342 import android.util.ArrayMap;
343 import android.util.ArraySet;
344 import android.util.AtomicFile;
345 import android.util.BootTimingsTraceLog;
346 import android.util.DebugUtils;
347 import android.util.DisplayMetrics;
348 import android.util.EventLog;
349 import android.util.Log;
350 import android.util.Pair;
351 import android.util.PrintWriterPrinter;
352 import android.util.Slog;
353 import android.util.SparseArray;
354 import android.util.SparseIntArray;
355 import android.util.TimeUtils;
356 import android.util.Xml;
357 import android.view.Gravity;
358 import android.view.LayoutInflater;
359 import android.view.View;
360 import android.view.WindowManager;
362 import com.android.server.job.JobSchedulerInternal;
363 import com.google.android.collect.Lists;
364 import com.google.android.collect.Maps;
366 import com.android.internal.R;
367 import com.android.internal.annotations.GuardedBy;
368 import com.android.internal.annotations.VisibleForTesting;
369 import com.android.internal.app.AssistUtils;
370 import com.android.internal.app.DumpHeapActivity;
371 import com.android.internal.app.IAppOpsCallback;
372 import com.android.internal.app.IAppOpsService;
373 import com.android.internal.app.IVoiceInteractor;
374 import com.android.internal.app.ProcessMap;
375 import com.android.internal.app.SystemUserHomeActivity;
376 import com.android.internal.app.procstats.ProcessStats;
377 import com.android.internal.logging.MetricsLogger;
378 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
379 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
380 import com.android.internal.notification.SystemNotificationChannels;
381 import com.android.internal.os.BackgroundThread;
382 import com.android.internal.os.BatteryStatsImpl;
383 import com.android.internal.os.IResultReceiver;
384 import com.android.internal.os.ProcessCpuTracker;
385 import com.android.internal.os.TransferPipe;
386 import com.android.internal.os.Zygote;
387 import com.android.internal.policy.IKeyguardDismissCallback;
388 import com.android.internal.telephony.TelephonyIntents;
389 import com.android.internal.util.ArrayUtils;
390 import com.android.internal.util.DumpUtils;
391 import com.android.internal.util.FastPrintWriter;
392 import com.android.internal.util.FastXmlSerializer;
393 import com.android.internal.util.MemInfoReader;
394 import com.android.internal.util.Preconditions;
395 import com.android.server.AppOpsService;
396 import com.android.server.AttributeCache;
397 import com.android.server.DeviceIdleController;
398 import com.android.server.IntentResolver;
399 import com.android.server.LocalServices;
400 import com.android.server.LockGuard;
401 import com.android.server.NetworkManagementInternal;
402 import com.android.server.RescueParty;
403 import com.android.server.ServiceThread;
404 import com.android.server.SystemConfig;
405 import com.android.server.SystemService;
406 import com.android.server.SystemServiceManager;
407 import com.android.server.ThreadPriorityBooster;
408 import com.android.server.Watchdog;
409 import com.android.server.am.ActivityStack.ActivityState;
410 import com.android.server.firewall.IntentFirewall;
411 import com.android.server.pm.Installer;
412 import com.android.server.pm.Installer.InstallerException;
413 import com.android.server.statusbar.StatusBarManagerInternal;
414 import com.android.server.vr.VrManagerInternal;
415 import com.android.server.wm.PinnedStackWindowController;
416 import com.android.server.wm.WindowManagerService;
418 import org.xmlpull.v1.XmlPullParser;
419 import org.xmlpull.v1.XmlPullParserException;
420 import org.xmlpull.v1.XmlSerializer;
423 import java.io.FileDescriptor;
424 import java.io.FileInputStream;
425 import java.io.FileNotFoundException;
426 import java.io.FileOutputStream;
427 import java.io.IOException;
428 import java.io.InputStreamReader;
429 import java.io.PrintWriter;
430 import java.io.StringWriter;
431 import java.io.UnsupportedEncodingException;
432 import java.lang.ref.WeakReference;
433 import java.nio.charset.StandardCharsets;
434 import java.text.DateFormat;
435 import java.util.ArrayList;
436 import java.util.Arrays;
437 import java.util.Collections;
438 import java.util.Comparator;
439 import java.util.Date;
440 import java.util.HashMap;
441 import java.util.HashSet;
442 import java.util.Iterator;
443 import java.util.List;
444 import java.util.Locale;
445 import java.util.Map;
446 import java.util.Objects;
447 import java.util.Set;
448 import java.util.concurrent.CountDownLatch;
449 import java.util.concurrent.atomic.AtomicBoolean;
450 import java.util.concurrent.atomic.AtomicLong;
452 import dalvik.system.VMRuntime;
453 import libcore.io.IoUtils;
454 import libcore.util.EmptyArray;
456 public class ActivityManagerService extends IActivityManager.Stub
457 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
460 * Priority we boost main thread and RT of top app to.
462 public static final int TOP_APP_PRIORITY_BOOST = -10;
464 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
465 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
466 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
467 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
468 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
469 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
470 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
471 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
472 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
473 private static final String TAG_LRU = TAG + POSTFIX_LRU;
474 private static final String TAG_MU = TAG + POSTFIX_MU;
475 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
476 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
477 private static final String TAG_POWER = TAG + POSTFIX_POWER;
478 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
479 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
480 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
481 private static final String TAG_PSS = TAG + POSTFIX_PSS;
482 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
483 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
484 private static final String TAG_STACK = TAG + POSTFIX_STACK;
485 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
486 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
487 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
488 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
489 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
491 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
492 // here so that while the job scheduler can depend on AMS, the other way around
493 // need not be the case.
494 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
496 /** Control over CPU and battery monitoring */
497 // write battery stats every 30 minutes.
498 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
499 static final boolean MONITOR_CPU_USAGE = true;
500 // don't sample cpu less than every 5 seconds.
501 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
502 // wait possibly forever for next cpu sample.
503 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
504 static final boolean MONITOR_THREAD_CPU_USAGE = false;
506 // The flags that are set for all calls we make to the package manager.
507 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
509 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
511 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
513 // Amount of time after a call to stopAppSwitches() during which we will
514 // prevent further untrusted switches from happening.
515 static final long APP_SWITCH_DELAY_TIME = 5*1000;
517 // How long we wait for a launched process to attach to the activity manager
518 // before we decide it's never going to come up for real.
519 static final int PROC_START_TIMEOUT = 10*1000;
520 // How long we wait for an attached process to publish its content providers
521 // before we decide it must be hung.
522 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
524 // How long we wait for a launched process to attach to the activity manager
525 // before we decide it's never going to come up for real, when the process was
526 // started with a wrapper for instrumentation (such as Valgrind) because it
527 // could take much longer than usual.
528 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
530 // How long we allow a receiver to run before giving up on it.
531 static final int BROADCAST_FG_TIMEOUT = 10*1000;
532 static final int BROADCAST_BG_TIMEOUT = 60*1000;
534 // How long we wait until we timeout on key dispatching.
535 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
537 // How long we wait until we timeout on key dispatching during instrumentation.
538 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
540 // How long to wait in getAssistContextExtras for the activity and foreground services
541 // to respond with the result.
542 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
544 // How long top wait when going through the modern assist (which doesn't need to block
545 // on getting this result before starting to launch its UI).
546 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
548 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
549 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
551 // Maximum number of persisted Uri grants a package is allowed
552 static final int MAX_PERSISTED_URI_GRANTS = 128;
554 static final int MY_PID = myPid();
556 static final String[] EMPTY_STRING_ARRAY = new String[0];
558 // How many bytes to write into the dropbox log before truncating
559 static final int DROPBOX_MAX_SIZE = 192 * 1024;
560 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
561 // as one line, but close enough for now.
562 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
564 // Access modes for handleIncomingUser.
565 static final int ALLOW_NON_FULL = 0;
566 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
567 static final int ALLOW_FULL_ONLY = 2;
569 // Necessary ApplicationInfo flags to mark an app as persistent
570 private static final int PERSISTENT_MASK =
571 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
573 // Intent sent when remote bugreport collection has been completed
574 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
575 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
577 // Used to indicate that an app transition should be animated.
578 static final boolean ANIMATE = true;
580 // Determines whether to take full screen screenshots
581 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
584 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
586 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
589 * State indicating that there is no need for any blocking for network.
592 static final int NETWORK_STATE_NO_CHANGE = 0;
595 * State indicating that the main thread needs to be informed about the network wait.
598 static final int NETWORK_STATE_BLOCK = 1;
601 * State indicating that any threads waiting for network state to get updated can be unblocked.
604 static final int NETWORK_STATE_UNBLOCK = 2;
606 // Max character limit for a notification title. If the notification title is larger than this
607 // the notification will not be legible to the user.
608 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
610 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
612 /** All system services */
613 SystemServiceManager mSystemServiceManager;
614 AssistUtils mAssistUtils;
616 private Installer mInstaller;
618 /** Run all ActivityStacks through this */
619 final ActivityStackSupervisor mStackSupervisor;
620 private final KeyguardController mKeyguardController;
622 final ActivityStarter mActivityStarter;
624 final TaskChangeNotificationController mTaskChangeNotificationController;
626 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
628 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
630 public final IntentFirewall mIntentFirewall;
632 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
633 // default action automatically. Important for devices without direct input
635 private boolean mShowDialogs = true;
637 private final VrController mVrController;
639 // VR Vr2d Display Id.
640 int mVr2dDisplayId = INVALID_DISPLAY;
642 // Whether we should use SCHED_FIFO for UI and RenderThreads.
643 private boolean mUseFifoUiScheduling = false;
645 BroadcastQueue mFgBroadcastQueue;
646 BroadcastQueue mBgBroadcastQueue;
647 // Convenient for easy iteration over the queues. Foreground is first
648 // so that dispatch of foreground broadcasts gets precedence.
649 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
651 BroadcastStats mLastBroadcastStats;
652 BroadcastStats mCurBroadcastStats;
654 BroadcastQueue broadcastQueueForIntent(Intent intent) {
655 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
656 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
657 "Broadcast intent " + intent + " on "
658 + (isFg ? "foreground" : "background") + " queue");
659 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
663 * The last resumed activity. This is identical to the current resumed activity most
664 * of the time but could be different when we're pausing one activity before we resume
667 private ActivityRecord mLastResumedActivity;
670 * If non-null, we are tracking the time the user spends in the currently focused app.
672 private AppTimeTracker mCurAppTimeTracker;
675 * List of intents that were used to start the most recent tasks.
677 final RecentTasks mRecentTasks;
680 * For addAppTask: cached of the last activity component that was added.
682 ComponentName mLastAddedTaskComponent;
685 * For addAppTask: cached of the last activity uid that was added.
687 int mLastAddedTaskUid;
690 * For addAppTask: cached of the last ActivityInfo that was added.
692 ActivityInfo mLastAddedTaskActivity;
695 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
697 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
700 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
702 String mDeviceOwnerName;
704 final UserController mUserController;
706 final AppErrors mAppErrors;
709 * Dump of the activity state at the time of the last ANR. Cleared after
710 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
712 String mLastANRState;
715 * Indicates the maximum time spent waiting for the network rules to get updated.
718 long mWaitForNetworkTimeoutMs;
720 public boolean canShowErrorDialogs() {
721 return mShowDialogs && !mSleeping && !mShuttingDown
722 && !mKeyguardController.isKeyguardShowing()
723 && !(UserManager.isDeviceInDemoMode(mContext)
724 && mUserController.getCurrentUser().isDemo());
727 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
728 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
730 static void boostPriorityForLockedSection() {
731 sThreadPriorityBooster.boost();
734 static void resetPriorityAfterLockedSection() {
735 sThreadPriorityBooster.reset();
738 public class PendingAssistExtras extends Binder implements Runnable {
739 public final ActivityRecord activity;
740 public boolean isHome;
741 public final Bundle extras;
742 public final Intent intent;
743 public final String hint;
744 public final IResultReceiver receiver;
745 public final int userHandle;
746 public boolean haveResult = false;
747 public Bundle result = null;
748 public AssistStructure structure = null;
749 public AssistContent content = null;
750 public Bundle receiverExtras;
752 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
753 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
754 activity = _activity;
758 receiver = _receiver;
759 receiverExtras = _receiverExtras;
760 userHandle = _userHandle;
765 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
766 synchronized (this) {
770 pendingAssistExtrasTimedOut(this);
774 final ArrayList<PendingAssistExtras> mPendingAssistExtras
775 = new ArrayList<PendingAssistExtras>();
778 * Process management.
780 final ProcessList mProcessList = new ProcessList();
783 * All of the applications we currently have running organized by name.
784 * The keys are strings of the application package name (as
785 * returned by the package manager), and the keys are ApplicationRecord
788 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
791 * Tracking long-term execution of processes to look for abuse and other
794 final ProcessStatsService mProcessStats;
797 * The currently running isolated processes.
799 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
802 * Counter for assigning isolated process uids, to avoid frequently reusing the
805 int mNextIsolatedProcessUid = 0;
808 * The currently running heavy-weight process, if any.
810 ProcessRecord mHeavyWeightProcess = null;
813 * Non-persistent appId whitelist for background restrictions
815 int[] mBackgroundAppIdWhitelist = new int[] {
820 * Broadcast actions that will always be deliverable to unlaunched/background apps
822 ArraySet<String> mBackgroundLaunchBroadcasts;
825 * All of the processes we currently have running organized by pid.
826 * The keys are the pid running the application.
828 * <p>NOTE: This object is protected by its own lock, NOT the global
829 * activity manager lock!
831 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
834 * All of the processes that have been forced to be important. The key
835 * is the pid of the caller who requested it (we hold a death
838 abstract class ImportanceToken implements IBinder.DeathRecipient {
843 ImportanceToken(int _pid, IBinder _token, String _reason) {
850 public String toString() {
851 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
852 + " " + reason + " " + pid + " " + token + " }";
855 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
858 * List of records for processes that someone had tried to start before the
859 * system was ready. We don't start them at that point, but ensure they
860 * are started by the time booting is complete.
862 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
865 * List of persistent applications that are in the process
868 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
871 * Processes that are being forcibly torn down.
873 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
876 * List of running applications, sorted by recent usage.
877 * The first entry in the list is the least recently used.
879 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
882 * Where in mLruProcesses that the processes hosting activities start.
884 int mLruProcessActivityStart = 0;
887 * Where in mLruProcesses that the processes hosting services start.
888 * This is after (lower index) than mLruProcessesActivityStart.
890 int mLruProcessServiceStart = 0;
893 * List of processes that should gc as soon as things are idle.
895 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
898 * Processes we want to collect PSS data from.
900 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
902 private boolean mBinderTransactionTrackingEnabled = false;
905 * Last time we requested PSS data of all processes.
907 long mLastFullPssTime = SystemClock.uptimeMillis();
910 * If set, the next time we collect PSS data we should do a full collection
911 * with data from native processes and the kernel.
913 boolean mFullPssPending = false;
916 * This is the process holding what we currently consider to be
917 * the "home" activity.
919 ProcessRecord mHomeProcess;
922 * This is the process holding the activity the user last visited that
923 * is in a different process from the one they are currently in.
925 ProcessRecord mPreviousProcess;
928 * The time at which the previous process was last visible.
930 long mPreviousProcessVisibleTime;
933 * Track all uids that have actively running processes.
935 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
938 * This is for verifying the UID report flow.
940 static final boolean VALIDATE_UID_STATES = true;
941 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
944 * Packages that the user has asked to have run in screen size
945 * compatibility mode instead of filling the screen.
947 final CompatModePackages mCompatModePackages;
950 * Set of IntentSenderRecord objects that are currently active.
952 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
953 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
956 * Fingerprints (hashCode()) of stack traces that we've
957 * already logged DropBox entries for. Guarded by itself. If
958 * something (rogue user app) forces this over
959 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
961 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
962 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
965 * Strict Mode background batched logging state.
967 * The string buffer is guarded by itself, and its lock is also
968 * used to determine if another batched write is already
971 private final StringBuilder mStrictModeBuffer = new StringBuilder();
974 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
975 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
977 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
980 * Resolver for broadcast intents to registered receivers.
981 * Holds BroadcastFilter (subclass of IntentFilter).
983 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
984 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
986 protected boolean allowFilterResult(
987 BroadcastFilter filter, List<BroadcastFilter> dest) {
988 IBinder target = filter.receiverList.receiver.asBinder();
989 for (int i = dest.size() - 1; i >= 0; i--) {
990 if (dest.get(i).receiverList.receiver.asBinder() == target) {
998 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
999 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1000 || userId == filter.owningUserId) {
1001 return super.newResult(filter, match, userId);
1007 protected BroadcastFilter[] newArray(int size) {
1008 return new BroadcastFilter[size];
1012 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1013 return packageName.equals(filter.packageName);
1018 * State of all active sticky broadcasts per user. Keys are the action of the
1019 * sticky Intent, values are an ArrayList of all broadcasted intents with
1020 * that action (which should usually be one). The SparseArray is keyed
1021 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1022 * for stickies that are sent to all users.
1024 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1025 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1027 final ActiveServices mServices;
1029 final static class Association {
1030 final int mSourceUid;
1031 final String mSourceProcess;
1032 final int mTargetUid;
1033 final ComponentName mTargetComponent;
1034 final String mTargetProcess;
1042 // states of the source process when the bind occurred.
1043 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1044 long mLastStateUptime;
1045 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1046 - ActivityManager.MIN_PROCESS_STATE+1];
1048 Association(int sourceUid, String sourceProcess, int targetUid,
1049 ComponentName targetComponent, String targetProcess) {
1050 mSourceUid = sourceUid;
1051 mSourceProcess = sourceProcess;
1052 mTargetUid = targetUid;
1053 mTargetComponent = targetComponent;
1054 mTargetProcess = targetProcess;
1059 * When service association tracking is enabled, this is all of the associations we
1060 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1061 * -> association data.
1063 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1064 mAssociations = new SparseArray<>();
1065 boolean mTrackingAssociations;
1068 * Backup/restore process management
1070 String mBackupAppName = null;
1071 BackupRecord mBackupTarget = null;
1073 final ProviderMap mProviderMap;
1076 * List of content providers who have clients waiting for them. The
1077 * application is currently being launched and the provider will be
1078 * removed from this list once it is published.
1080 final ArrayList<ContentProviderRecord> mLaunchingProviders
1081 = new ArrayList<ContentProviderRecord>();
1084 * File storing persisted {@link #mGrantedUriPermissions}.
1086 private final AtomicFile mGrantFile;
1088 /** XML constants used in {@link #mGrantFile} */
1089 private static final String TAG_URI_GRANTS = "uri-grants";
1090 private static final String TAG_URI_GRANT = "uri-grant";
1091 private static final String ATTR_USER_HANDLE = "userHandle";
1092 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1093 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1094 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1095 private static final String ATTR_TARGET_PKG = "targetPkg";
1096 private static final String ATTR_URI = "uri";
1097 private static final String ATTR_MODE_FLAGS = "modeFlags";
1098 private static final String ATTR_CREATED_TIME = "createdTime";
1099 private static final String ATTR_PREFIX = "prefix";
1102 * Global set of specific {@link Uri} permissions that have been granted.
1103 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1104 * to {@link UriPermission#uri} to {@link UriPermission}.
1107 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1108 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1110 public static class GrantUri {
1111 public final int sourceUserId;
1112 public final Uri uri;
1113 public boolean prefix;
1115 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1116 this.sourceUserId = sourceUserId;
1118 this.prefix = prefix;
1122 public int hashCode() {
1124 hashCode = 31 * hashCode + sourceUserId;
1125 hashCode = 31 * hashCode + uri.hashCode();
1126 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1131 public boolean equals(Object o) {
1132 if (o instanceof GrantUri) {
1133 GrantUri other = (GrantUri) o;
1134 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1135 && prefix == other.prefix;
1141 public String toString() {
1142 String result = uri.toString() + " [user " + sourceUserId + "]";
1143 if (prefix) result += " [prefix]";
1147 public String toSafeString() {
1148 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1149 if (prefix) result += " [prefix]";
1153 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1154 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1155 ContentProvider.getUriWithoutUserId(uri), false);
1159 CoreSettingsObserver mCoreSettingsObserver;
1161 FontScaleSettingObserver mFontScaleSettingObserver;
1163 private final class FontScaleSettingObserver extends ContentObserver {
1164 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1166 public FontScaleSettingObserver() {
1168 ContentResolver resolver = mContext.getContentResolver();
1169 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1173 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1174 if (mFontScaleUri.equals(uri)) {
1175 updateFontScaleIfNeeded(userId);
1181 * Thread-local storage used to carry caller permissions over through
1182 * indirect content-provider access.
1184 private class Identity {
1185 public final IBinder token;
1186 public final int pid;
1187 public final int uid;
1189 Identity(IBinder _token, int _pid, int _uid) {
1196 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1199 * All information we have collected about the runtime performance of
1200 * any user id that can impact battery performance.
1202 final BatteryStatsService mBatteryStatsService;
1205 * Information about component usage
1207 UsageStatsManagerInternal mUsageStatsService;
1210 * Access to DeviceIdleController service.
1212 DeviceIdleController.LocalService mLocalDeviceIdleController;
1215 * Set of app ids that are whitelisted for device idle and thus background check.
1217 int[] mDeviceIdleWhitelist = new int[0];
1220 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1222 int[] mDeviceIdleTempWhitelist = new int[0];
1224 static final class PendingTempWhitelist {
1225 final int targetUid;
1226 final long duration;
1229 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1230 targetUid = _targetUid;
1231 duration = _duration;
1236 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1239 * Information about and control over application operations
1241 final AppOpsService mAppOpsService;
1243 /** Current sequencing integer of the configuration, for skipping old configurations. */
1244 private int mConfigurationSeq;
1247 * Temp object used when global and/or display override configuration is updated. It is also
1248 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1251 private Configuration mTempConfig = new Configuration();
1253 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1254 new UpdateConfigurationResult();
1255 private static final class UpdateConfigurationResult {
1256 // Configuration changes that were updated.
1258 // If the activity was relaunched to match the new configuration.
1259 boolean activityRelaunched;
1263 activityRelaunched = false;
1267 boolean mSuppressResizeConfigChanges;
1270 * Hardware-reported OpenGLES version.
1272 final int GL_ES_VERSION;
1275 * List of initialization arguments to pass to all processes when binding applications to them.
1276 * For example, references to the commonly used services.
1278 HashMap<String, IBinder> mAppBindArgs;
1279 HashMap<String, IBinder> mIsolatedAppBindArgs;
1282 * Temporary to avoid allocations. Protected by main lock.
1284 final StringBuilder mStringBuilder = new StringBuilder(256);
1287 * Used to control how we initialize the service.
1289 ComponentName mTopComponent;
1290 String mTopAction = Intent.ACTION_MAIN;
1293 volatile boolean mProcessesReady = false;
1294 volatile boolean mSystemReady = false;
1295 volatile boolean mOnBattery = false;
1296 volatile int mFactoryTest;
1298 @GuardedBy("this") boolean mBooting = false;
1299 @GuardedBy("this") boolean mCallFinishBooting = false;
1300 @GuardedBy("this") boolean mBootAnimationComplete = false;
1301 @GuardedBy("this") boolean mLaunchWarningShown = false;
1302 @GuardedBy("this") boolean mCheckedForSetup = false;
1304 final Context mContext;
1307 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1308 * change at runtime. Use mContext for non-UI purposes.
1310 final Context mUiContext;
1313 * The time at which we will allow normal application switches again,
1314 * after a call to {@link #stopAppSwitches()}.
1316 long mAppSwitchesAllowedTime;
1319 * This is set to true after the first switch after mAppSwitchesAllowedTime
1320 * is set; any switches after that will clear the time.
1322 boolean mDidAppSwitch;
1325 * Last time (in realtime) at which we checked for power usage.
1327 long mLastPowerCheckRealtime;
1330 * Last time (in uptime) at which we checked for power usage.
1332 long mLastPowerCheckUptime;
1335 * Set while we are wanting to sleep, to prevent any
1336 * activities from being started/resumed.
1338 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1340 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1341 * while in the sleep state until there is a pending transition out of sleep, in which case
1342 * mSleeping is set to false, and remains false while awake.
1344 * Whether mSleeping can quickly toggled between true/false without the device actually
1345 * display changing states is undefined.
1347 private boolean mSleeping = false;
1350 * The process state used for processes that are running the top activities.
1351 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1353 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1356 * Set while we are running a voice interaction. This overrides
1357 * sleeping while it is active.
1359 private IVoiceInteractionSession mRunningVoice;
1362 * For some direct access we need to power manager.
1364 PowerManagerInternal mLocalPowerManager;
1367 * We want to hold a wake lock while running a voice interaction session, since
1368 * this may happen with the screen off and we need to keep the CPU running to
1369 * be able to continue to interact with the user.
1371 PowerManager.WakeLock mVoiceWakeLock;
1374 * State of external calls telling us if the device is awake or asleep.
1376 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1379 * A list of tokens that cause the top activity to be put to sleep.
1380 * They are used by components that may hide and block interaction with underlying
1383 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1386 * Set if we are shutting down the system, similar to sleeping.
1388 boolean mShuttingDown = false;
1391 * Current sequence id for oom_adj computation traversal.
1396 * Current sequence id for process LRU updating.
1401 * Keep track of the non-cached/empty process we last found, to help
1402 * determine how to distribute cached/empty processes next time.
1404 int mNumNonCachedProcs = 0;
1407 * Keep track of the number of cached hidden procs, to balance oom adj
1408 * distribution between those and empty procs.
1410 int mNumCachedHiddenProcs = 0;
1413 * Keep track of the number of service processes we last found, to
1414 * determine on the next iteration which should be B services.
1416 int mNumServiceProcs = 0;
1417 int mNewNumAServiceProcs = 0;
1418 int mNewNumServiceProcs = 0;
1421 * Allow the current computed overall memory level of the system to go down?
1422 * This is set to false when we are killing processes for reasons other than
1423 * memory management, so that the now smaller process list will not be taken as
1424 * an indication that memory is tighter.
1426 boolean mAllowLowerMemLevel = false;
1429 * The last computed memory level, for holding when we are in a state that
1430 * processes are going away for other reasons.
1432 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1435 * The last total number of process we have, to determine if changes actually look
1436 * like a shrinking number of process due to lower RAM.
1438 int mLastNumProcesses;
1441 * The uptime of the last time we performed idle maintenance.
1443 long mLastIdleTime = SystemClock.uptimeMillis();
1446 * Total time spent with RAM that has been added in the past since the last idle time.
1448 long mLowRamTimeSinceLastIdle = 0;
1451 * If RAM is currently low, when that horrible situation started.
1453 long mLowRamStartTime = 0;
1456 * For reporting to battery stats the current top application.
1458 private String mCurResumedPackage = null;
1459 private int mCurResumedUid = -1;
1462 * For reporting to battery stats the apps currently running foreground
1463 * service. The ProcessMap is package/uid tuples; each of these contain
1464 * an array of the currently foreground processes.
1466 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1467 = new ProcessMap<ArrayList<ProcessRecord>>();
1470 * Set if the systemServer made a call to enterSafeMode.
1475 * If true, we are running under a test environment so will sample PSS from processes
1476 * much more rapidly to try to collect better data when the tests are rapidly
1477 * running through apps.
1479 boolean mTestPssMode = false;
1481 String mDebugApp = null;
1482 boolean mWaitForDebugger = false;
1483 boolean mDebugTransient = false;
1484 String mOrigDebugApp = null;
1485 boolean mOrigWaitForDebugger = false;
1486 boolean mAlwaysFinishActivities = false;
1487 boolean mForceResizableActivities;
1489 * Flag that indicates if multi-window is enabled.
1491 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1492 * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
1493 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1494 * At least one of the forms of multi-window must be enabled in order for this flag to be
1495 * initialized to 'true'.
1497 * @see #mSupportsSplitScreenMultiWindow
1498 * @see #mSupportsFreeformWindowManagement
1499 * @see #mSupportsPictureInPicture
1500 * @see #mSupportsMultiDisplay
1502 boolean mSupportsMultiWindow;
1503 boolean mSupportsSplitScreenMultiWindow;
1504 boolean mSupportsFreeformWindowManagement;
1505 boolean mSupportsPictureInPicture;
1506 boolean mSupportsMultiDisplay;
1507 boolean mSupportsLeanbackOnly;
1508 IActivityController mController = null;
1509 boolean mControllerIsAMonkey = false;
1510 String mProfileApp = null;
1511 ProcessRecord mProfileProc = null;
1512 String mProfileFile;
1513 ParcelFileDescriptor mProfileFd;
1514 int mSamplingInterval = 0;
1515 boolean mAutoStopProfiler = false;
1516 boolean mStreamingOutput = false;
1517 int mProfileType = 0;
1518 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1519 String mMemWatchDumpProcName;
1520 String mMemWatchDumpFile;
1521 int mMemWatchDumpPid;
1522 int mMemWatchDumpUid;
1523 String mTrackAllocationApp = null;
1524 String mNativeDebuggingApp = null;
1526 final long[] mTmpLong = new long[2];
1528 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1531 * A global counter for generating sequence numbers.
1532 * This value will be used when incrementing sequence numbers in individual uidRecords.
1534 * Having a global counter ensures that seq numbers are monotonically increasing for a
1535 * particular uid even when the uidRecord is re-created.
1539 long mProcStateSeqCounter = 0;
1541 private final Injector mInjector;
1543 static final class ProcessChangeItem {
1544 static final int CHANGE_ACTIVITIES = 1<<0;
1549 boolean foregroundActivities;
1552 static final class UidObserverRegistration {
1558 final SparseIntArray lastProcStates;
1560 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1564 cutpoint = _cutpoint;
1565 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1566 lastProcStates = new SparseIntArray();
1568 lastProcStates = null;
1573 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1574 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1576 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1577 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1579 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1580 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1582 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1583 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1586 * Runtime CPU use collection thread. This object's lock is used to
1587 * perform synchronization with the thread (notifying it to run).
1589 final Thread mProcessCpuThread;
1592 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1593 * Must acquire this object's lock when accessing it.
1594 * NOTE: this lock will be held while doing long operations (trawling
1595 * through all processes in /proc), so it should never be acquired by
1596 * any critical paths such as when holding the main activity manager lock.
1598 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1599 MONITOR_THREAD_CPU_USAGE);
1600 final AtomicLong mLastCpuTime = new AtomicLong(0);
1601 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1602 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1604 long mLastWriteTime = 0;
1607 * Used to retain an update lock when the foreground activity is in
1610 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1613 * Set to true after the system has finished booting.
1615 boolean mBooted = false;
1617 WindowManagerService mWindowManager;
1618 final ActivityThread mSystemThread;
1620 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1621 final ProcessRecord mApp;
1623 final IApplicationThread mAppThread;
1625 AppDeathRecipient(ProcessRecord app, int pid,
1626 IApplicationThread thread) {
1627 if (DEBUG_ALL) Slog.v(
1628 TAG, "New death recipient " + this
1629 + " for thread " + thread.asBinder());
1632 mAppThread = thread;
1636 public void binderDied() {
1637 if (DEBUG_ALL) Slog.v(
1638 TAG, "Death received in " + this
1639 + " for thread " + mAppThread.asBinder());
1640 synchronized(ActivityManagerService.this) {
1641 appDiedLocked(mApp, mPid, mAppThread, true);
1646 static final int SHOW_ERROR_UI_MSG = 1;
1647 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1648 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1649 static final int UPDATE_CONFIGURATION_MSG = 4;
1650 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1651 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1652 static final int SERVICE_TIMEOUT_MSG = 12;
1653 static final int UPDATE_TIME_ZONE = 13;
1654 static final int SHOW_UID_ERROR_UI_MSG = 14;
1655 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1656 static final int PROC_START_TIMEOUT_MSG = 20;
1657 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1658 static final int KILL_APPLICATION_MSG = 22;
1659 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1660 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1661 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1662 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1663 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1664 static final int CLEAR_DNS_CACHE_MSG = 28;
1665 static final int UPDATE_HTTP_PROXY_MSG = 29;
1666 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1667 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1668 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1669 static final int REPORT_MEM_USAGE_MSG = 33;
1670 static final int REPORT_USER_SWITCH_MSG = 34;
1671 static final int CONTINUE_USER_SWITCH_MSG = 35;
1672 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1673 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1674 static final int PERSIST_URI_GRANTS_MSG = 38;
1675 static final int REQUEST_ALL_PSS_MSG = 39;
1676 static final int START_PROFILES_MSG = 40;
1677 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1678 static final int SYSTEM_USER_START_MSG = 42;
1679 static final int SYSTEM_USER_CURRENT_MSG = 43;
1680 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1681 static final int FINISH_BOOTING_MSG = 45;
1682 static final int START_USER_SWITCH_UI_MSG = 46;
1683 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1684 static final int DISMISS_DIALOG_UI_MSG = 48;
1685 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1686 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1687 static final int DELETE_DUMPHEAP_MSG = 51;
1688 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1689 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1690 static final int REPORT_TIME_TRACKER_MSG = 54;
1691 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1692 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1693 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1694 static final int IDLE_UIDS_MSG = 58;
1695 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1696 static final int LOG_STACK_STATE = 60;
1697 static final int VR_MODE_CHANGE_MSG = 61;
1698 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1699 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1700 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1701 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1702 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1703 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1704 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1705 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1706 static final int START_USER_SWITCH_FG_MSG = 712;
1708 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1709 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1710 static final int FIRST_COMPAT_MODE_MSG = 300;
1711 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1713 static ServiceThread sKillThread = null;
1714 static KillHandler sKillHandler = null;
1716 CompatModeDialog mCompatModeDialog;
1717 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1718 long mLastMemUsageReportTime = 0;
1721 * Flag whether the current user is a "monkey", i.e. whether
1722 * the UI is driven by a UI automation tool.
1724 private boolean mUserIsMonkey;
1726 /** Flag whether the device has a Recents UI */
1727 boolean mHasRecents;
1729 /** The dimensions of the thumbnails in the Recents UI. */
1730 int mThumbnailWidth;
1731 int mThumbnailHeight;
1732 float mFullscreenThumbnailScale;
1734 final ServiceThread mHandlerThread;
1735 final MainHandler mHandler;
1736 final Handler mUiHandler;
1738 final ActivityManagerConstants mConstants;
1740 PackageManagerInternal mPackageManagerInt;
1742 // VoiceInteraction session ID that changes for each new request except when
1743 // being called for multiwindow assist in a single session.
1744 private int mViSessionId = 1000;
1746 final boolean mPermissionReviewRequired;
1749 * Current global configuration information. Contains general settings for the entire system,
1750 * also corresponds to the merged configuration of the default display.
1752 Configuration getGlobalConfiguration() {
1753 return mStackSupervisor.getConfiguration();
1756 final class KillHandler extends Handler {
1757 static final int KILL_PROCESS_GROUP_MSG = 4000;
1759 public KillHandler(Looper looper) {
1760 super(looper, null, true);
1764 public void handleMessage(Message msg) {
1766 case KILL_PROCESS_GROUP_MSG:
1768 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1769 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1770 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1775 super.handleMessage(msg);
1780 final class UiHandler extends Handler {
1781 public UiHandler() {
1782 super(com.android.server.UiThread.get().getLooper(), null, true);
1786 public void handleMessage(Message msg) {
1788 case SHOW_ERROR_UI_MSG: {
1789 mAppErrors.handleShowAppErrorUi(msg);
1790 ensureBootCompleted();
1792 case SHOW_NOT_RESPONDING_UI_MSG: {
1793 mAppErrors.handleShowAnrUi(msg);
1794 ensureBootCompleted();
1796 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1797 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1798 synchronized (ActivityManagerService.this) {
1799 ProcessRecord proc = (ProcessRecord) data.get("app");
1801 Slog.e(TAG, "App not found when showing strict mode dialog.");
1804 if (proc.crashDialog != null) {
1805 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1808 AppErrorResult res = (AppErrorResult) data.get("result");
1809 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1810 Dialog d = new StrictModeViolationDialog(mUiContext,
1811 ActivityManagerService.this, res, proc);
1813 proc.crashDialog = d;
1815 // The device is asleep, so just pretend that the user
1816 // saw a crash dialog and hit "force quit".
1820 ensureBootCompleted();
1822 case SHOW_FACTORY_ERROR_UI_MSG: {
1823 Dialog d = new FactoryErrorDialog(
1824 mUiContext, msg.getData().getCharSequence("msg"));
1826 ensureBootCompleted();
1828 case WAIT_FOR_DEBUGGER_UI_MSG: {
1829 synchronized (ActivityManagerService.this) {
1830 ProcessRecord app = (ProcessRecord)msg.obj;
1831 if (msg.arg1 != 0) {
1832 if (!app.waitedForDebugger) {
1833 Dialog d = new AppWaitingForDebuggerDialog(
1834 ActivityManagerService.this,
1837 app.waitedForDebugger = true;
1841 if (app.waitDialog != null) {
1842 app.waitDialog.dismiss();
1843 app.waitDialog = null;
1848 case SHOW_UID_ERROR_UI_MSG: {
1850 AlertDialog d = new BaseErrorDialog(mUiContext);
1851 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1852 d.setCancelable(false);
1853 d.setTitle(mUiContext.getText(R.string.android_system_label));
1854 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1855 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1856 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1860 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1862 AlertDialog d = new BaseErrorDialog(mUiContext);
1863 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1864 d.setCancelable(false);
1865 d.setTitle(mUiContext.getText(R.string.android_system_label));
1866 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1867 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1868 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1872 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1873 synchronized (ActivityManagerService.this) {
1874 ActivityRecord ar = (ActivityRecord) msg.obj;
1875 if (mCompatModeDialog != null) {
1876 if (mCompatModeDialog.mAppInfo.packageName.equals(
1877 ar.info.applicationInfo.packageName)) {
1880 mCompatModeDialog.dismiss();
1881 mCompatModeDialog = null;
1883 if (ar != null && false) {
1884 if (mCompatModePackages.getPackageAskCompatModeLocked(
1886 int mode = mCompatModePackages.computeCompatModeLocked(
1887 ar.info.applicationInfo);
1888 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1889 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1890 mCompatModeDialog = new CompatModeDialog(
1891 ActivityManagerService.this, mUiContext,
1892 ar.info.applicationInfo);
1893 mCompatModeDialog.show();
1900 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1901 synchronized (ActivityManagerService.this) {
1902 final ActivityRecord ar = (ActivityRecord) msg.obj;
1903 if (mUnsupportedDisplaySizeDialog != null) {
1904 mUnsupportedDisplaySizeDialog.dismiss();
1905 mUnsupportedDisplaySizeDialog = null;
1907 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1909 // TODO(multi-display): Show dialog on appropriate display.
1910 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1911 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1912 mUnsupportedDisplaySizeDialog.show();
1917 case START_USER_SWITCH_UI_MSG: {
1918 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1921 case DISMISS_DIALOG_UI_MSG: {
1922 final Dialog d = (Dialog) msg.obj;
1926 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1927 dispatchProcessesChanged();
1930 case DISPATCH_PROCESS_DIED_UI_MSG: {
1931 final int pid = msg.arg1;
1932 final int uid = msg.arg2;
1933 dispatchProcessDied(pid, uid);
1936 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1937 dispatchUidsChanged();
1939 case PUSH_TEMP_WHITELIST_UI_MSG: {
1940 pushTempWhitelist();
1946 final class MainHandler extends Handler {
1947 public MainHandler(Looper looper) {
1948 super(looper, null, true);
1952 public void handleMessage(Message msg) {
1954 case UPDATE_CONFIGURATION_MSG: {
1955 final ContentResolver resolver = mContext.getContentResolver();
1956 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1959 case GC_BACKGROUND_PROCESSES_MSG: {
1960 synchronized (ActivityManagerService.this) {
1961 performAppGcsIfAppropriateLocked();
1964 case SERVICE_TIMEOUT_MSG: {
1965 mServices.serviceTimeout((ProcessRecord)msg.obj);
1967 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1968 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1970 case SERVICE_FOREGROUND_CRASH_MSG: {
1971 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1973 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1974 RemoteCallbackList<IResultReceiver> callbacks
1975 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1976 int N = callbacks.beginBroadcast();
1977 for (int i = 0; i < N; i++) {
1979 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1980 } catch (RemoteException e) {
1983 callbacks.finishBroadcast();
1985 case UPDATE_TIME_ZONE: {
1986 synchronized (ActivityManagerService.this) {
1987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1988 ProcessRecord r = mLruProcesses.get(i);
1989 if (r.thread != null) {
1991 r.thread.updateTimeZone();
1992 } catch (RemoteException ex) {
1993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1999 case CLEAR_DNS_CACHE_MSG: {
2000 synchronized (ActivityManagerService.this) {
2001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2002 ProcessRecord r = mLruProcesses.get(i);
2003 if (r.thread != null) {
2005 r.thread.clearDnsCache();
2006 } catch (RemoteException ex) {
2007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2013 case UPDATE_HTTP_PROXY_MSG: {
2014 ProxyInfo proxy = (ProxyInfo)msg.obj;
2017 String exclList = "";
2018 Uri pacFileUrl = Uri.EMPTY;
2019 if (proxy != null) {
2020 host = proxy.getHost();
2021 port = Integer.toString(proxy.getPort());
2022 exclList = proxy.getExclusionListAsString();
2023 pacFileUrl = proxy.getPacFileUrl();
2025 synchronized (ActivityManagerService.this) {
2026 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2027 ProcessRecord r = mLruProcesses.get(i);
2028 if (r.thread != null) {
2030 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2031 } catch (RemoteException ex) {
2032 Slog.w(TAG, "Failed to update http proxy for: " +
2033 r.info.processName);
2039 case PROC_START_TIMEOUT_MSG: {
2040 ProcessRecord app = (ProcessRecord)msg.obj;
2041 synchronized (ActivityManagerService.this) {
2042 processStartTimedOutLocked(app);
2045 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2046 ProcessRecord app = (ProcessRecord)msg.obj;
2047 synchronized (ActivityManagerService.this) {
2048 processContentProviderPublishTimedOutLocked(app);
2051 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2052 synchronized (ActivityManagerService.this) {
2053 mActivityStarter.doPendingActivityLaunchesLocked(true);
2056 case KILL_APPLICATION_MSG: {
2057 synchronized (ActivityManagerService.this) {
2058 final int appId = msg.arg1;
2059 final int userId = msg.arg2;
2060 Bundle bundle = (Bundle)msg.obj;
2061 String pkg = bundle.getString("pkg");
2062 String reason = bundle.getString("reason");
2063 forceStopPackageLocked(pkg, appId, false, false, true, false,
2064 false, userId, reason);
2067 case FINALIZE_PENDING_INTENT_MSG: {
2068 ((PendingIntentRecord)msg.obj).completeFinalize();
2070 case POST_HEAVY_NOTIFICATION_MSG: {
2071 INotificationManager inm = NotificationManager.getService();
2076 ActivityRecord root = (ActivityRecord)msg.obj;
2077 ProcessRecord process = root.app;
2078 if (process == null) {
2083 Context context = mContext.createPackageContext(process.info.packageName, 0);
2084 String text = mContext.getString(R.string.heavy_weight_notification,
2085 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2086 Notification notification =
2087 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2088 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2092 .setColor(mContext.getColor(
2093 com.android.internal.R.color.system_notification_accent_color))
2094 .setContentTitle(text)
2096 mContext.getText(R.string.heavy_weight_notification_detail))
2097 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2098 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2099 new UserHandle(root.userId)))
2102 inm.enqueueNotificationWithTag("android", "android", null,
2103 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2104 notification, root.userId);
2105 } catch (RuntimeException e) {
2106 Slog.w(ActivityManagerService.TAG,
2107 "Error showing notification for heavy-weight app", e);
2108 } catch (RemoteException e) {
2110 } catch (NameNotFoundException e) {
2111 Slog.w(TAG, "Unable to create context for heavy notification", e);
2114 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2115 INotificationManager inm = NotificationManager.getService();
2120 inm.cancelNotificationWithTag("android", null,
2121 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2122 } catch (RuntimeException e) {
2123 Slog.w(ActivityManagerService.TAG,
2124 "Error canceling notification for service", e);
2125 } catch (RemoteException e) {
2128 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2129 synchronized (ActivityManagerService.this) {
2130 checkExcessivePowerUsageLocked(true);
2131 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2132 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2133 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2136 case REPORT_MEM_USAGE_MSG: {
2137 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2138 Thread thread = new Thread() {
2139 @Override public void run() {
2140 reportMemUsage(memInfos);
2146 case START_USER_SWITCH_FG_MSG: {
2147 mUserController.startUserInForeground(msg.arg1);
2150 case REPORT_USER_SWITCH_MSG: {
2151 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2154 case CONTINUE_USER_SWITCH_MSG: {
2155 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2158 case USER_SWITCH_TIMEOUT_MSG: {
2159 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2162 case IMMERSIVE_MODE_LOCK_MSG: {
2163 final boolean nextState = (msg.arg1 != 0);
2164 if (mUpdateLock.isHeld() != nextState) {
2165 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2166 "Applying new update lock state '" + nextState
2167 + "' for " + (ActivityRecord)msg.obj);
2169 mUpdateLock.acquire();
2171 mUpdateLock.release();
2176 case PERSIST_URI_GRANTS_MSG: {
2177 writeGrantedUriPermissions();
2180 case REQUEST_ALL_PSS_MSG: {
2181 synchronized (ActivityManagerService.this) {
2182 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2186 case START_PROFILES_MSG: {
2187 synchronized (ActivityManagerService.this) {
2188 mUserController.startProfilesLocked();
2192 case UPDATE_TIME_PREFERENCE_MSG: {
2193 // The user's time format preference might have changed.
2194 // For convenience we re-use the Intent extra values.
2195 synchronized (ActivityManagerService.this) {
2196 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2197 ProcessRecord r = mLruProcesses.get(i);
2198 if (r.thread != null) {
2200 r.thread.updateTimePrefs(msg.arg1);
2201 } catch (RemoteException ex) {
2202 Slog.w(TAG, "Failed to update preferences for: "
2203 + r.info.processName);
2210 case SYSTEM_USER_START_MSG: {
2211 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2212 Integer.toString(msg.arg1), msg.arg1);
2213 mSystemServiceManager.startUser(msg.arg1);
2216 case SYSTEM_USER_UNLOCK_MSG: {
2217 final int userId = msg.arg1;
2218 mSystemServiceManager.unlockUser(userId);
2219 synchronized (ActivityManagerService.this) {
2220 mRecentTasks.loadUserRecentsLocked(userId);
2222 if (userId == UserHandle.USER_SYSTEM) {
2223 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2225 installEncryptionUnawareProviders(userId);
2226 mUserController.finishUserUnlocked((UserState) msg.obj);
2229 case SYSTEM_USER_CURRENT_MSG: {
2230 mBatteryStatsService.noteEvent(
2231 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2232 Integer.toString(msg.arg2), msg.arg2);
2233 mBatteryStatsService.noteEvent(
2234 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2235 Integer.toString(msg.arg1), msg.arg1);
2236 mSystemServiceManager.switchUser(msg.arg1);
2239 case ENTER_ANIMATION_COMPLETE_MSG: {
2240 synchronized (ActivityManagerService.this) {
2241 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2242 if (r != null && r.app != null && r.app.thread != null) {
2244 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2245 } catch (RemoteException e) {
2251 case FINISH_BOOTING_MSG: {
2252 if (msg.arg1 != 0) {
2253 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2255 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2257 if (msg.arg2 != 0) {
2258 enableScreenAfterBoot();
2262 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2264 Locale l = (Locale) msg.obj;
2265 IBinder service = ServiceManager.getService("mount");
2266 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2267 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2268 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2269 } catch (RemoteException e) {
2270 Log.e(TAG, "Error storing locale for decryption UI", e);
2274 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2275 final int uid = msg.arg1;
2276 final byte[] firstPacket = (byte[]) msg.obj;
2278 synchronized (mPidsSelfLocked) {
2279 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2280 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2283 p.thread.notifyCleartextNetwork(firstPacket);
2284 } catch (RemoteException ignored) {
2291 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2292 final String procName;
2294 final long memLimit;
2295 final String reportPackage;
2296 synchronized (ActivityManagerService.this) {
2297 procName = mMemWatchDumpProcName;
2298 uid = mMemWatchDumpUid;
2299 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2301 val = mMemWatchProcesses.get(procName, 0);
2304 memLimit = val.first;
2305 reportPackage = val.second;
2308 reportPackage = null;
2311 if (procName == null) {
2315 if (DEBUG_PSS) Slog.d(TAG_PSS,
2316 "Showing dump heap notification from " + procName + "/" + uid);
2318 INotificationManager inm = NotificationManager.getService();
2323 String text = mContext.getString(R.string.dump_heap_notification, procName);
2326 Intent deleteIntent = new Intent();
2327 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2328 Intent intent = new Intent();
2329 intent.setClassName("android", DumpHeapActivity.class.getName());
2330 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2331 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2332 if (reportPackage != null) {
2333 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2335 int userId = UserHandle.getUserId(uid);
2336 Notification notification =
2337 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2338 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2341 .setAutoCancel(true)
2343 .setColor(mContext.getColor(
2344 com.android.internal.R.color.system_notification_accent_color))
2345 .setContentTitle(text)
2347 mContext.getText(R.string.dump_heap_notification_detail))
2348 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2349 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2350 new UserHandle(userId)))
2351 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2352 deleteIntent, 0, UserHandle.SYSTEM))
2356 inm.enqueueNotificationWithTag("android", "android", null,
2357 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2358 notification, userId);
2359 } catch (RuntimeException e) {
2360 Slog.w(ActivityManagerService.TAG,
2361 "Error showing notification for dump heap", e);
2362 } catch (RemoteException e) {
2365 case DELETE_DUMPHEAP_MSG: {
2366 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2367 null, DumpHeapActivity.JAVA_URI,
2368 Intent.FLAG_GRANT_READ_URI_PERMISSION
2369 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2370 UserHandle.myUserId());
2371 synchronized (ActivityManagerService.this) {
2372 mMemWatchDumpFile = null;
2373 mMemWatchDumpProcName = null;
2374 mMemWatchDumpPid = -1;
2375 mMemWatchDumpUid = -1;
2378 case FOREGROUND_PROFILE_CHANGED_MSG: {
2379 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2381 case REPORT_TIME_TRACKER_MSG: {
2382 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2383 tracker.deliverResult(mContext);
2385 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2386 mUserController.dispatchUserSwitchComplete(msg.arg1);
2388 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2389 mUserController.dispatchLockedBootComplete(msg.arg1);
2391 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2392 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2394 connection.shutdown();
2395 } catch (RemoteException e) {
2396 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2398 // Only a UiAutomation can set this flag and now that
2399 // it is finished we make sure it is reset to its default.
2400 mUserIsMonkey = false;
2402 case IDLE_UIDS_MSG: {
2405 case VR_MODE_CHANGE_MSG: {
2406 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2409 synchronized (ActivityManagerService.this) {
2410 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2411 mWindowManager.disableNonVrUi(disableNonVrUi);
2412 if (disableNonVrUi) {
2413 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2414 // then remove the pinned stack.
2415 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2417 if (pinnedStack != null) {
2418 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2423 case NOTIFY_VR_SLEEPING_MSG: {
2424 notifyVrManagerOfSleepState(msg.arg1 != 0);
2426 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2427 synchronized (ActivityManagerService.this) {
2428 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2429 ProcessRecord r = mLruProcesses.get(i);
2430 if (r.thread != null) {
2432 r.thread.handleTrustStorageUpdate();
2433 } catch (RemoteException ex) {
2434 Slog.w(TAG, "Failed to handle trust storage update for: " +
2435 r.info.processName);
2445 static final int COLLECT_PSS_BG_MSG = 1;
2447 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2449 public void handleMessage(Message msg) {
2451 case COLLECT_PSS_BG_MSG: {
2452 long start = SystemClock.uptimeMillis();
2453 MemInfoReader memInfo = null;
2454 synchronized (ActivityManagerService.this) {
2455 if (mFullPssPending) {
2456 mFullPssPending = false;
2457 memInfo = new MemInfoReader();
2460 if (memInfo != null) {
2461 updateCpuStatsNow();
2462 long nativeTotalPss = 0;
2463 final List<ProcessCpuTracker.Stats> stats;
2464 synchronized (mProcessCpuTracker) {
2465 stats = mProcessCpuTracker.getStats( (st)-> {
2466 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2469 final int N = stats.size();
2470 for (int j = 0; j < N; j++) {
2471 synchronized (mPidsSelfLocked) {
2472 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2473 // This is one of our own processes; skip it.
2477 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2479 memInfo.readMemInfo();
2480 synchronized (ActivityManagerService.this) {
2481 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2482 + (SystemClock.uptimeMillis()-start) + "ms");
2483 final long cachedKb = memInfo.getCachedSizeKb();
2484 final long freeKb = memInfo.getFreeSizeKb();
2485 final long zramKb = memInfo.getZramTotalSizeKb();
2486 final long kernelKb = memInfo.getKernelUsedSizeKb();
2487 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2488 kernelKb*1024, nativeTotalPss*1024);
2489 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2495 long[] tmp = new long[2];
2501 synchronized (ActivityManagerService.this) {
2502 if (mPendingPssProcesses.size() <= 0) {
2503 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2504 "Collected PSS of " + num + " processes in "
2505 + (SystemClock.uptimeMillis() - start) + "ms");
2506 mPendingPssProcesses.clear();
2509 proc = mPendingPssProcesses.remove(0);
2510 procState = proc.pssProcState;
2511 lastPssTime = proc.lastPssTime;
2512 if (proc.thread != null && procState == proc.setProcState
2513 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2514 < SystemClock.uptimeMillis()) {
2522 long pss = Debug.getPss(pid, tmp, null);
2523 synchronized (ActivityManagerService.this) {
2524 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2525 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2527 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2528 SystemClock.uptimeMillis());
2538 public void setSystemProcess() {
2540 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2541 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2542 ServiceManager.addService("meminfo", new MemBinder(this));
2543 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2544 ServiceManager.addService("dbinfo", new DbBinder(this));
2545 if (MONITOR_CPU_USAGE) {
2546 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2548 ServiceManager.addService("permission", new PermissionController(this));
2549 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2551 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2552 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2553 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2555 synchronized (this) {
2556 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2557 app.persistent = true;
2559 app.maxAdj = ProcessList.SYSTEM_ADJ;
2560 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2561 synchronized (mPidsSelfLocked) {
2562 mPidsSelfLocked.put(app.pid, app);
2564 updateLruProcessLocked(app, false, null);
2565 updateOomAdjLocked();
2567 } catch (PackageManager.NameNotFoundException e) {
2568 throw new RuntimeException(
2569 "Unable to find android system package", e);
2573 public void setWindowManager(WindowManagerService wm) {
2574 mWindowManager = wm;
2575 mStackSupervisor.setWindowManager(wm);
2576 mActivityStarter.setWindowManager(wm);
2579 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2580 mUsageStatsService = usageStatsManager;
2583 public void startObservingNativeCrashes() {
2584 final NativeCrashListener ncl = new NativeCrashListener(this);
2588 public IAppOpsService getAppOpsService() {
2589 return mAppOpsService;
2592 static class MemBinder extends Binder {
2593 ActivityManagerService mActivityManagerService;
2594 MemBinder(ActivityManagerService activityManagerService) {
2595 mActivityManagerService = activityManagerService;
2599 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2600 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2601 "meminfo", pw)) return;
2602 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2606 static class GraphicsBinder extends Binder {
2607 ActivityManagerService mActivityManagerService;
2608 GraphicsBinder(ActivityManagerService activityManagerService) {
2609 mActivityManagerService = activityManagerService;
2613 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2614 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2615 "gfxinfo", pw)) return;
2616 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2620 static class DbBinder extends Binder {
2621 ActivityManagerService mActivityManagerService;
2622 DbBinder(ActivityManagerService activityManagerService) {
2623 mActivityManagerService = activityManagerService;
2627 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2628 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2629 "dbinfo", pw)) return;
2630 mActivityManagerService.dumpDbInfo(fd, pw, args);
2634 static class CpuBinder extends Binder {
2635 ActivityManagerService mActivityManagerService;
2636 CpuBinder(ActivityManagerService activityManagerService) {
2637 mActivityManagerService = activityManagerService;
2641 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2642 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2643 "cpuinfo", pw)) return;
2644 synchronized (mActivityManagerService.mProcessCpuTracker) {
2645 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2646 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2647 SystemClock.uptimeMillis()));
2652 public static final class Lifecycle extends SystemService {
2653 private final ActivityManagerService mService;
2655 public Lifecycle(Context context) {
2657 mService = new ActivityManagerService(context);
2661 public void onStart() {
2665 public ActivityManagerService getService() {
2671 public ActivityManagerService(Injector injector) {
2672 mInjector = injector;
2673 mContext = mInjector.getContext();
2676 mActivityStarter = null;
2678 mAppOpsService = mInjector.getAppOpsService(null, null);
2679 mBatteryStatsService = null;
2680 mCompatModePackages = null;
2684 mHandlerThread = null;
2685 mIntentFirewall = null;
2686 mKeyguardController = null;
2687 mPermissionReviewRequired = false;
2688 mProcessCpuThread = null;
2689 mProcessStats = null;
2690 mProviderMap = null;
2691 mRecentTasks = null;
2693 mStackSupervisor = null;
2694 mSystemThread = null;
2695 mTaskChangeNotificationController = null;
2696 mUiHandler = injector.getUiHandler(null);
2697 mUserController = null;
2698 mVrController = null;
2701 // Note: This method is invoked on the main thread but may need to attach various
2702 // handlers to other threads. So take care to be explicit about the looper.
2703 public ActivityManagerService(Context systemContext) {
2704 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2705 mInjector = new Injector();
2706 mContext = systemContext;
2708 mFactoryTest = FactoryTest.getMode();
2709 mSystemThread = ActivityThread.currentActivityThread();
2710 mUiContext = mSystemThread.getSystemUiContext();
2712 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2714 mPermissionReviewRequired = mContext.getResources().getBoolean(
2715 com.android.internal.R.bool.config_permissionReviewRequired);
2717 mHandlerThread = new ServiceThread(TAG,
2718 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2719 mHandlerThread.start();
2720 mHandler = new MainHandler(mHandlerThread.getLooper());
2721 mUiHandler = mInjector.getUiHandler(this);
2723 mConstants = new ActivityManagerConstants(this, mHandler);
2725 /* static; one-time init here */
2726 if (sKillHandler == null) {
2727 sKillThread = new ServiceThread(TAG + ":kill",
2728 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2729 sKillThread.start();
2730 sKillHandler = new KillHandler(sKillThread.getLooper());
2733 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2734 "foreground", BROADCAST_FG_TIMEOUT, false);
2735 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2736 "background", BROADCAST_BG_TIMEOUT, true);
2737 mBroadcastQueues[0] = mFgBroadcastQueue;
2738 mBroadcastQueues[1] = mBgBroadcastQueue;
2740 mServices = new ActiveServices(this);
2741 mProviderMap = new ProviderMap(this);
2742 mAppErrors = new AppErrors(mUiContext, this);
2744 // TODO: Move creation of battery stats service outside of activity manager service.
2745 File dataDir = Environment.getDataDirectory();
2746 File systemDir = new File(dataDir, "system");
2748 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2749 mBatteryStatsService.getActiveStatistics().readLocked();
2750 mBatteryStatsService.scheduleWriteToDisk();
2751 mOnBattery = DEBUG_POWER ? true
2752 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2753 mBatteryStatsService.getActiveStatistics().setCallback(this);
2755 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2757 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2758 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2759 new IAppOpsCallback.Stub() {
2760 @Override public void opChanged(int op, int uid, String packageName) {
2761 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2762 if (mAppOpsService.checkOperation(op, uid, packageName)
2763 != AppOpsManager.MODE_ALLOWED) {
2764 runInBackgroundDisabled(uid);
2770 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2772 mUserController = new UserController(this);
2774 mVrController = new VrController(this);
2776 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2777 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2779 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2780 mUseFifoUiScheduling = true;
2783 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2784 mTempConfig.setToDefaults();
2785 mTempConfig.setLocales(LocaleList.getDefault());
2786 mConfigurationSeq = mTempConfig.seq = 1;
2787 mStackSupervisor = createStackSupervisor();
2788 mStackSupervisor.onConfigurationChanged(mTempConfig);
2789 mKeyguardController = mStackSupervisor.mKeyguardController;
2790 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2791 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2792 mTaskChangeNotificationController =
2793 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2794 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2795 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2797 mProcessCpuThread = new Thread("CpuTracker") {
2800 synchronized (mProcessCpuTracker) {
2801 mProcessCpuInitLatch.countDown();
2802 mProcessCpuTracker.init();
2807 synchronized(this) {
2808 final long now = SystemClock.uptimeMillis();
2809 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2810 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2811 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2812 // + ", write delay=" + nextWriteDelay);
2813 if (nextWriteDelay < nextCpuDelay) {
2814 nextCpuDelay = nextWriteDelay;
2816 if (nextCpuDelay > 0) {
2817 mProcessCpuMutexFree.set(true);
2818 this.wait(nextCpuDelay);
2821 } catch (InterruptedException e) {
2823 updateCpuStatsNow();
2824 } catch (Exception e) {
2825 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2831 Watchdog.getInstance().addMonitor(this);
2832 Watchdog.getInstance().addThread(mHandler);
2835 protected ActivityStackSupervisor createStackSupervisor() {
2836 return new ActivityStackSupervisor(this, mHandler.getLooper());
2839 public void setSystemServiceManager(SystemServiceManager mgr) {
2840 mSystemServiceManager = mgr;
2843 public void setInstaller(Installer installer) {
2844 mInstaller = installer;
2847 private void start() {
2848 removeAllProcessGroups();
2849 mProcessCpuThread.start();
2851 mBatteryStatsService.publish(mContext);
2852 mAppOpsService.publish(mContext);
2853 Slog.d("AppOps", "AppOpsService published");
2854 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2855 // Wait for the synchronized block started in mProcessCpuThread,
2856 // so that any other acccess to mProcessCpuTracker from main thread
2857 // will be blocked during mProcessCpuTracker initialization.
2859 mProcessCpuInitLatch.await();
2860 } catch (InterruptedException e) {
2861 Slog.wtf(TAG, "Interrupted wait during start", e);
2862 Thread.currentThread().interrupt();
2863 throw new IllegalStateException("Interrupted wait during start");
2867 void onUserStoppedLocked(int userId) {
2868 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2871 public void initPowerManagement() {
2872 mStackSupervisor.initPowerManagement();
2873 mBatteryStatsService.initPowerManagement();
2874 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2875 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2876 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2877 mVoiceWakeLock.setReferenceCounted(false);
2880 private ArraySet<String> getBackgroundLaunchBroadcasts() {
2881 if (mBackgroundLaunchBroadcasts == null) {
2882 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2884 return mBackgroundLaunchBroadcasts;
2888 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2889 throws RemoteException {
2890 if (code == SYSPROPS_TRANSACTION) {
2891 // We need to tell all apps about the system property change.
2892 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2893 synchronized(this) {
2894 final int NP = mProcessNames.getMap().size();
2895 for (int ip=0; ip<NP; ip++) {
2896 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2897 final int NA = apps.size();
2898 for (int ia=0; ia<NA; ia++) {
2899 ProcessRecord app = apps.valueAt(ia);
2900 if (app.thread != null) {
2901 procs.add(app.thread.asBinder());
2907 int N = procs.size();
2908 for (int i=0; i<N; i++) {
2909 Parcel data2 = Parcel.obtain();
2911 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2912 Binder.FLAG_ONEWAY);
2913 } catch (RemoteException e) {
2919 return super.onTransact(code, data, reply, flags);
2920 } catch (RuntimeException e) {
2921 // The activity manager only throws security exceptions, so let's
2923 if (!(e instanceof SecurityException)) {
2924 Slog.wtf(TAG, "Activity Manager Crash."
2925 + " UID:" + Binder.getCallingUid()
2926 + " PID:" + Binder.getCallingPid()
2927 + " TRANS:" + code, e);
2933 void updateCpuStats() {
2934 final long now = SystemClock.uptimeMillis();
2935 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2938 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2939 synchronized (mProcessCpuThread) {
2940 mProcessCpuThread.notify();
2945 void updateCpuStatsNow() {
2946 synchronized (mProcessCpuTracker) {
2947 mProcessCpuMutexFree.set(false);
2948 final long now = SystemClock.uptimeMillis();
2949 boolean haveNewCpuStats = false;
2951 if (MONITOR_CPU_USAGE &&
2952 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2953 mLastCpuTime.set(now);
2954 mProcessCpuTracker.update();
2955 if (mProcessCpuTracker.hasGoodLastStats()) {
2956 haveNewCpuStats = true;
2957 //Slog.i(TAG, mProcessCpu.printCurrentState());
2958 //Slog.i(TAG, "Total CPU usage: "
2959 // + mProcessCpu.getTotalCpuPercent() + "%");
2961 // Slog the cpu usage if the property is set.
2962 if ("true".equals(SystemProperties.get("events.cpu"))) {
2963 int user = mProcessCpuTracker.getLastUserTime();
2964 int system = mProcessCpuTracker.getLastSystemTime();
2965 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2966 int irq = mProcessCpuTracker.getLastIrqTime();
2967 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2968 int idle = mProcessCpuTracker.getLastIdleTime();
2970 int total = user + system + iowait + irq + softIrq + idle;
2971 if (total == 0) total = 1;
2973 EventLog.writeEvent(EventLogTags.CPU,
2974 ((user+system+iowait+irq+softIrq) * 100) / total,
2975 (user * 100) / total,
2976 (system * 100) / total,
2977 (iowait * 100) / total,
2978 (irq * 100) / total,
2979 (softIrq * 100) / total);
2984 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2985 synchronized(bstats) {
2986 synchronized(mPidsSelfLocked) {
2987 if (haveNewCpuStats) {
2988 if (bstats.startAddingCpuLocked()) {
2991 final int N = mProcessCpuTracker.countStats();
2992 for (int i=0; i<N; i++) {
2993 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2997 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2998 totalUTime += st.rel_utime;
2999 totalSTime += st.rel_stime;
3001 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3002 if (ps == null || !ps.isActive()) {
3003 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3004 pr.info.uid, pr.processName);
3006 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3007 pr.curCpuTime += st.rel_utime + st.rel_stime;
3009 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3010 if (ps == null || !ps.isActive()) {
3011 st.batteryStats = ps = bstats.getProcessStatsLocked(
3012 bstats.mapUid(st.uid), st.name);
3014 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3017 final int userTime = mProcessCpuTracker.getLastUserTime();
3018 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3019 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3020 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3021 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3022 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3023 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3024 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3029 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3030 mLastWriteTime = now;
3031 mBatteryStatsService.scheduleWriteToDisk();
3038 public void batteryNeedsCpuUpdate() {
3039 updateCpuStatsNow();
3043 public void batteryPowerChanged(boolean onBattery) {
3044 // When plugging in, update the CPU stats first before changing
3046 updateCpuStatsNow();
3047 synchronized (this) {
3048 synchronized(mPidsSelfLocked) {
3049 mOnBattery = DEBUG_POWER ? true : onBattery;
3055 public void batterySendBroadcast(Intent intent) {
3056 synchronized (this) {
3057 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3058 AppOpsManager.OP_NONE, null, false, false,
3059 -1, SYSTEM_UID, UserHandle.USER_ALL);
3064 * Initialize the application bind args. These are passed to each
3065 * process when the bindApplication() IPC is sent to the process. They're
3066 * lazily setup to make sure the services are running when they're asked for.
3068 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3069 // Isolated processes won't get this optimization, so that we don't
3070 // violate the rules about which services they have access to.
3072 if (mIsolatedAppBindArgs == null) {
3073 mIsolatedAppBindArgs = new HashMap<>();
3074 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3076 return mIsolatedAppBindArgs;
3079 if (mAppBindArgs == null) {
3080 mAppBindArgs = new HashMap<>();
3082 // Setup the application init args
3083 mAppBindArgs.put("package", ServiceManager.getService("package"));
3084 mAppBindArgs.put("window", ServiceManager.getService("window"));
3085 mAppBindArgs.put(Context.ALARM_SERVICE,
3086 ServiceManager.getService(Context.ALARM_SERVICE));
3088 return mAppBindArgs;
3092 * Update AMS states when an activity is resumed. This should only be called by
3093 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3095 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3096 final TaskRecord task = r.getTask();
3097 if (task.isApplicationTask()) {
3098 if (mCurAppTimeTracker != r.appTimeTracker) {
3099 // We are switching app tracking. Complete the current one.
3100 if (mCurAppTimeTracker != null) {
3101 mCurAppTimeTracker.stop();
3102 mHandler.obtainMessage(
3103 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3104 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3105 mCurAppTimeTracker = null;
3107 if (r.appTimeTracker != null) {
3108 mCurAppTimeTracker = r.appTimeTracker;
3109 startTimeTrackingFocusedActivityLocked();
3112 startTimeTrackingFocusedActivityLocked();
3115 r.appTimeTracker = null;
3117 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3118 // TODO: Probably not, because we don't want to resume voice on switching
3119 // back to this activity
3120 if (task.voiceInteractor != null) {
3121 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3123 finishRunningVoiceLocked();
3125 if (mLastResumedActivity != null) {
3126 final IVoiceInteractionSession session;
3128 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3129 if (lastResumedActivityTask != null
3130 && lastResumedActivityTask.voiceSession != null) {
3131 session = lastResumedActivityTask.voiceSession;
3133 session = mLastResumedActivity.voiceSession;
3136 if (session != null) {
3137 // We had been in a voice interaction session, but now focused has
3138 // move to something different. Just finish the session, we can't
3139 // return to it and retain the proper state and synchronization with
3140 // the voice interaction service.
3141 finishVoiceTask(session);
3146 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3147 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3148 mHandler.obtainMessage(
3149 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3151 mLastResumedActivity = r;
3153 mWindowManager.setFocusedApp(r.appToken, true);
3155 applyUpdateLockStateLocked(r);
3156 applyUpdateVrModeLocked(r);
3158 EventLogTags.writeAmSetResumedActivity(
3159 r == null ? -1 : r.userId,
3160 r == null ? "NULL" : r.shortComponentName,
3165 public void setFocusedStack(int stackId) {
3166 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3167 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3168 final long callingId = Binder.clearCallingIdentity();
3170 synchronized (this) {
3171 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3172 if (stack == null) {
3175 final ActivityRecord r = stack.topRunningActivityLocked();
3176 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3177 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3181 Binder.restoreCallingIdentity(callingId);
3186 public void setFocusedTask(int taskId) {
3187 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3188 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3189 final long callingId = Binder.clearCallingIdentity();
3191 synchronized (this) {
3192 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3196 final ActivityRecord r = task.topRunningActivityLocked();
3197 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3198 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3202 Binder.restoreCallingIdentity(callingId);
3206 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3208 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3209 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3210 mTaskChangeNotificationController.registerTaskStackListener(listener);
3214 * Unregister a task stack listener so that it stops receiving callbacks.
3217 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3218 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3219 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3223 public void notifyActivityDrawn(IBinder token) {
3224 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3225 synchronized (this) {
3226 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3228 r.getStack().notifyActivityDrawnLocked(r);
3233 final void applyUpdateLockStateLocked(ActivityRecord r) {
3234 // Modifications to the UpdateLock state are done on our handler, outside
3235 // the activity manager's locks. The new state is determined based on the
3236 // state *now* of the relevant activity record. The object is passed to
3237 // the handler solely for logging detail, not to be consulted/modified.
3238 final boolean nextState = r != null && r.immersive;
3239 mHandler.sendMessage(
3240 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3243 final void applyUpdateVrModeLocked(ActivityRecord r) {
3244 mHandler.sendMessage(
3245 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3248 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3249 mHandler.sendMessage(
3250 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3253 private void notifyVrManagerOfSleepState(boolean isSleeping) {
3254 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3255 if (vrService == null) {
3258 vrService.onSleepStateChanged(isSleeping);
3261 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3262 Message msg = Message.obtain();
3263 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3264 msg.obj = r.getTask().askedCompatMode ? null : r;
3265 mUiHandler.sendMessage(msg);
3268 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3269 final Configuration globalConfig = getGlobalConfiguration();
3270 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3271 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3272 final Message msg = Message.obtain();
3273 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3275 mUiHandler.sendMessage(msg);
3279 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3280 String what, Object obj, ProcessRecord srcApp) {
3281 app.lastActivityTime = now;
3283 if (app.activities.size() > 0) {
3284 // Don't want to touch dependent processes that are hosting activities.
3288 int lrui = mLruProcesses.lastIndexOf(app);
3290 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3291 + what + " " + obj + " from " + srcApp);
3295 if (lrui >= index) {
3296 // Don't want to cause this to move dependent processes *back* in the
3297 // list as if they were less frequently used.
3301 if (lrui >= mLruProcessActivityStart) {
3302 // Don't want to touch dependent processes that are hosting activities.
3306 mLruProcesses.remove(lrui);
3310 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3311 + " in LRU list: " + app);
3312 mLruProcesses.add(index, app);
3316 static void killProcessGroup(int uid, int pid) {
3317 if (sKillHandler != null) {
3318 sKillHandler.sendMessage(
3319 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3321 Slog.w(TAG, "Asked to kill process group before system bringup!");
3322 Process.killProcessGroup(uid, pid);
3326 final void removeLruProcessLocked(ProcessRecord app) {
3327 int lrui = mLruProcesses.lastIndexOf(app);
3330 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3331 killProcessQuiet(app.pid);
3332 killProcessGroup(app.uid, app.pid);
3334 if (lrui <= mLruProcessActivityStart) {
3335 mLruProcessActivityStart--;
3337 if (lrui <= mLruProcessServiceStart) {
3338 mLruProcessServiceStart--;
3340 mLruProcesses.remove(lrui);
3344 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3345 ProcessRecord client) {
3346 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3347 || app.treatLikeActivity;
3348 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3349 if (!activityChange && hasActivity) {
3350 // The process has activities, so we are only allowing activity-based adjustments
3351 // to move it. It should be kept in the front of the list with other
3352 // processes that have activities, and we don't want those to change their
3353 // order except due to activity operations.
3358 final long now = SystemClock.uptimeMillis();
3359 app.lastActivityTime = now;
3361 // First a quick reject: if the app is already at the position we will
3362 // put it, then there is nothing to do.
3364 final int N = mLruProcesses.size();
3365 if (N > 0 && mLruProcesses.get(N-1) == app) {
3366 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3370 if (mLruProcessServiceStart > 0
3371 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3372 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3377 int lrui = mLruProcesses.lastIndexOf(app);
3379 if (app.persistent && lrui >= 0) {
3380 // We don't care about the position of persistent processes, as long as
3381 // they are in the list.
3382 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3386 /* In progress: compute new position first, so we can avoid doing work
3387 if the process is not actually going to move. Not yet working.
3390 boolean inActivity = false, inService = false;
3392 // Process has activities, put it at the very tipsy-top.
3393 addIndex = mLruProcesses.size();
3394 nextIndex = mLruProcessServiceStart;
3396 } else if (hasService) {
3397 // Process has services, put it at the top of the service list.
3398 addIndex = mLruProcessActivityStart;
3399 nextIndex = mLruProcessServiceStart;
3403 // Process not otherwise of interest, it goes to the top of the non-service area.
3404 addIndex = mLruProcessServiceStart;
3405 if (client != null) {
3406 int clientIndex = mLruProcesses.lastIndexOf(client);
3407 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3409 if (clientIndex >= 0 && addIndex > clientIndex) {
3410 addIndex = clientIndex;
3413 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3416 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3417 + mLruProcessActivityStart + "): " + app);
3421 if (lrui < mLruProcessActivityStart) {
3422 mLruProcessActivityStart--;
3424 if (lrui < mLruProcessServiceStart) {
3425 mLruProcessServiceStart--;
3428 if (addIndex > lrui) {
3431 if (nextIndex > lrui) {
3435 mLruProcesses.remove(lrui);
3439 mLruProcesses.add(addIndex, app);
3441 mLruProcessActivityStart++;
3444 mLruProcessActivityStart++;
3450 final int N = mLruProcesses.size();
3451 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3452 // Process doesn't have activities, but has clients with
3453 // activities... move it up, but one below the top (the top
3454 // should always have a real activity).
3455 if (DEBUG_LRU) Slog.d(TAG_LRU,
3456 "Adding to second-top of LRU activity list: " + app);
3457 mLruProcesses.add(N - 1, app);
3458 // To keep it from spamming the LRU list (by making a bunch of clients),
3459 // we will push down any other entries owned by the app.
3460 final int uid = app.info.uid;
3461 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3462 ProcessRecord subProc = mLruProcesses.get(i);
3463 if (subProc.info.uid == uid) {
3464 // We want to push this one down the list. If the process after
3465 // it is for the same uid, however, don't do so, because we don't
3466 // want them internally to be re-ordered.
3467 if (mLruProcesses.get(i - 1).info.uid != uid) {
3468 if (DEBUG_LRU) Slog.d(TAG_LRU,
3469 "Pushing uid " + uid + " swapping at " + i + ": "
3470 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3471 ProcessRecord tmp = mLruProcesses.get(i);
3472 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3473 mLruProcesses.set(i - 1, tmp);
3477 // A gap, we can stop here.
3482 // Process has activities, put it at the very tipsy-top.
3483 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3484 mLruProcesses.add(app);
3486 nextIndex = mLruProcessServiceStart;
3487 } else if (hasService) {
3488 // Process has services, put it at the top of the service list.
3489 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3490 mLruProcesses.add(mLruProcessActivityStart, app);
3491 nextIndex = mLruProcessServiceStart;
3492 mLruProcessActivityStart++;
3494 // Process not otherwise of interest, it goes to the top of the non-service area.
3495 int index = mLruProcessServiceStart;
3496 if (client != null) {
3497 // If there is a client, don't allow the process to be moved up higher
3498 // in the list than that client.
3499 int clientIndex = mLruProcesses.lastIndexOf(client);
3500 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3501 + " when updating " + app);
3502 if (clientIndex <= lrui) {
3503 // Don't allow the client index restriction to push it down farther in the
3504 // list than it already is.
3507 if (clientIndex >= 0 && index > clientIndex) {
3508 index = clientIndex;
3511 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3512 mLruProcesses.add(index, app);
3513 nextIndex = index-1;
3514 mLruProcessActivityStart++;
3515 mLruProcessServiceStart++;
3518 // If the app is currently using a content provider or service,
3519 // bump those processes as well.
3520 for (int j=app.connections.size()-1; j>=0; j--) {
3521 ConnectionRecord cr = app.connections.valueAt(j);
3522 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3523 && cr.binding.service.app != null
3524 && cr.binding.service.app.lruSeq != mLruSeq
3525 && !cr.binding.service.app.persistent) {
3526 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3527 "service connection", cr, app);
3530 for (int j=app.conProviders.size()-1; j>=0; j--) {
3531 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3532 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3533 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3534 "provider reference", cpr, app);
3539 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3540 if (uid == SYSTEM_UID) {
3541 // The system gets to run in any process. If there are multiple
3542 // processes with the same uid, just pick the first (this
3543 // should never happen).
3544 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3545 if (procs == null) return null;
3546 final int procCount = procs.size();
3547 for (int i = 0; i < procCount; i++) {
3548 final int procUid = procs.keyAt(i);
3549 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3550 // Don't use an app process or different user process for system component.
3553 return procs.valueAt(i);
3556 ProcessRecord proc = mProcessNames.get(processName, uid);
3557 if (false && proc != null && !keepIfLarge
3558 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3559 && proc.lastCachedPss >= 4000) {
3560 // Turn this condition on to cause killing to happen regularly, for testing.
3561 if (proc.baseProcessTracker != null) {
3562 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3564 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3565 } else if (proc != null && !keepIfLarge
3566 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3567 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3568 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3569 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3570 if (proc.baseProcessTracker != null) {
3571 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3573 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3579 void notifyPackageUse(String packageName, int reason) {
3580 IPackageManager pm = AppGlobals.getPackageManager();
3582 pm.notifyPackageUse(packageName, reason);
3583 } catch (RemoteException e) {
3587 boolean isNextTransitionForward() {
3588 int transit = mWindowManager.getPendingAppTransition();
3589 return transit == TRANSIT_ACTIVITY_OPEN
3590 || transit == TRANSIT_TASK_OPEN
3591 || transit == TRANSIT_TASK_TO_FRONT;
3594 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3595 String processName, String abiOverride, int uid, Runnable crashHandler) {
3596 synchronized(this) {
3597 ApplicationInfo info = new ApplicationInfo();
3598 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3599 // For isolated processes, the former contains the parent's uid and the latter the
3600 // actual uid of the isolated process.
3601 // In the special case introduced by this method (which is, starting an isolated
3602 // process directly from the SystemServer without an actual parent app process) the
3603 // closest thing to a parent's uid is SYSTEM_UID.
3604 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3605 // the |isolated| logic in the ProcessRecord constructor.
3606 info.uid = SYSTEM_UID;
3607 info.processName = processName;
3608 info.className = entryPoint;
3609 info.packageName = "android";
3610 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3611 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3612 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3613 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3614 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3616 return proc != null ? proc.pid : 0;
3620 final ProcessRecord startProcessLocked(String processName,
3621 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3622 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3623 boolean isolated, boolean keepIfLarge) {
3624 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3625 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3626 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3627 null /* crashHandler */);
3630 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3631 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3632 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3633 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3634 long startTime = SystemClock.elapsedRealtime();
3637 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3638 checkTime(startTime, "startProcess: after getProcessRecord");
3640 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3641 // If we are in the background, then check to see if this process
3642 // is bad. If so, we will just silently fail.
3643 if (mAppErrors.isBadProcessLocked(info)) {
3644 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3645 + "/" + info.processName);
3649 // When the user is explicitly starting a process, then clear its
3650 // crash count so that we won't make it bad until they see at
3651 // least one crash dialog again, and make the process good again
3652 // if it had been bad.
3653 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3654 + "/" + info.processName);
3655 mAppErrors.resetProcessCrashTimeLocked(info);
3656 if (mAppErrors.isBadProcessLocked(info)) {
3657 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3658 UserHandle.getUserId(info.uid), info.uid,
3660 mAppErrors.clearBadProcessLocked(info);
3667 // If this is an isolated process, it can't re-use an existing process.
3671 // We don't have to do anything more if:
3672 // (1) There is an existing application record; and
3673 // (2) The caller doesn't think it is dead, OR there is no thread
3674 // object attached to it so we know it couldn't have crashed; and
3675 // (3) There is a pid assigned to it, so it is either starting or
3677 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3678 + " app=" + app + " knownToBeDead=" + knownToBeDead
3679 + " thread=" + (app != null ? app.thread : null)
3680 + " pid=" + (app != null ? app.pid : -1));
3681 if (app != null && app.pid > 0) {
3682 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3683 // We already have the app running, or are waiting for it to
3684 // come up (we have a pid but not yet its thread), so keep it.
3685 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3686 // If this is a new package in the process, add the package to the list
3687 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3688 checkTime(startTime, "startProcess: done, added package to proc");
3692 // An application record is attached to a previous process,
3694 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3695 checkTime(startTime, "startProcess: bad proc running, killing");
3696 killProcessGroup(app.uid, app.pid);
3697 handleAppDiedLocked(app, true, true);
3698 checkTime(startTime, "startProcess: done killing old proc");
3701 String hostingNameStr = hostingName != null
3702 ? hostingName.flattenToShortString() : null;
3705 checkTime(startTime, "startProcess: creating new process record");
3706 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3708 Slog.w(TAG, "Failed making new process record for "
3709 + processName + "/" + info.uid + " isolated=" + isolated);
3712 app.crashHandler = crashHandler;
3713 checkTime(startTime, "startProcess: done creating new process record");
3715 // If this is a new package in the process, add the package to the list
3716 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3717 checkTime(startTime, "startProcess: added package to existing proc");
3720 // If the system is not ready yet, then hold off on starting this
3721 // process until it is.
3722 if (!mProcessesReady
3723 && !isAllowedWhileBooting(info)
3724 && !allowWhileBooting) {
3725 if (!mProcessesOnHold.contains(app)) {
3726 mProcessesOnHold.add(app);
3728 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3729 "System not ready, putting on hold: " + app);
3730 checkTime(startTime, "startProcess: returning with proc on hold");
3734 checkTime(startTime, "startProcess: stepping in to startProcess");
3736 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3737 checkTime(startTime, "startProcess: done starting proc!");
3738 return (app.pid != 0) ? app : null;
3741 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3742 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3745 private final void startProcessLocked(ProcessRecord app,
3746 String hostingType, String hostingNameStr) {
3747 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3748 null /* entryPoint */, null /* entryPointArgs */);
3751 private final void startProcessLocked(ProcessRecord app, String hostingType,
3752 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3753 long startTime = SystemClock.elapsedRealtime();
3754 if (app.pid > 0 && app.pid != MY_PID) {
3755 checkTime(startTime, "startProcess: removing from pids map");
3756 synchronized (mPidsSelfLocked) {
3757 mPidsSelfLocked.remove(app.pid);
3758 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3760 checkTime(startTime, "startProcess: done removing from pids map");
3764 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3765 "startProcessLocked removing on hold: " + app);
3766 mProcessesOnHold.remove(app);
3768 checkTime(startTime, "startProcess: starting to update cpu stats");
3770 checkTime(startTime, "startProcess: done updating cpu stats");
3774 final int userId = UserHandle.getUserId(app.uid);
3775 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3776 } catch (RemoteException e) {
3777 throw e.rethrowAsRuntimeException();
3782 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3783 if (!app.isolated) {
3784 int[] permGids = null;
3786 checkTime(startTime, "startProcess: getting gids from package manager");
3787 final IPackageManager pm = AppGlobals.getPackageManager();
3788 permGids = pm.getPackageGids(app.info.packageName,
3789 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3790 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3791 StorageManagerInternal.class);
3792 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3793 app.info.packageName);
3794 } catch (RemoteException e) {
3795 throw e.rethrowAsRuntimeException();
3799 * Add shared application and profile GIDs so applications can share some
3800 * resources like shared libraries and access user-wide resources
3802 if (ArrayUtils.isEmpty(permGids)) {
3805 gids = new int[permGids.length + 3];
3806 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3808 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3809 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3810 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3812 checkTime(startTime, "startProcess: building args");
3813 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3814 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3815 && mTopComponent != null
3816 && app.processName.equals(mTopComponent.getPackageName())) {
3819 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3820 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3825 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3826 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3827 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3828 // Also turn on CheckJNI for debuggable apps. It's quite
3829 // awkward to turn on otherwise.
3830 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3832 // Run the app in safe mode if its manifest requests so or the
3833 // system is booted in safe mode.
3834 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3835 mSafeMode == true) {
3836 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3838 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3839 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3841 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3842 if ("true".equals(genDebugInfoProperty)) {
3843 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3845 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3846 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3848 if ("1".equals(SystemProperties.get("debug.assert"))) {
3849 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3851 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3852 // Enable all debug flags required by the native debugger.
3853 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3854 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3855 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3856 mNativeDebuggingApp = null;
3859 String invokeWith = null;
3860 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3861 // Debuggable apps may include a wrapper script with their library directory.
3862 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3863 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3865 if (new File(wrapperFileName).exists()) {
3866 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3869 StrictMode.setThreadPolicy(oldPolicy);
3873 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3874 if (requiredAbi == null) {
3875 requiredAbi = Build.SUPPORTED_ABIS[0];
3878 String instructionSet = null;
3879 if (app.info.primaryCpuAbi != null) {
3880 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3884 app.requiredAbi = requiredAbi;
3885 app.instructionSet = instructionSet;
3887 // the per-user SELinux context must be set
3888 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3889 Slog.wtf(TAG, "SELinux tag not defined",
3890 new IllegalStateException("SELinux tag not defined for "
3891 + app.info.packageName + " (uid " + app.uid + ")"));
3893 final String seInfo = app.info.seInfo
3894 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3895 // Start the process. It will either succeed and return a result containing
3896 // the PID of the new process, or else throw a RuntimeException.
3897 boolean isActivityProcess = (entryPoint == null);
3898 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3899 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3901 checkTime(startTime, "startProcess: asking zygote to start proc");
3902 ProcessStartResult startResult;
3903 if (hostingType.equals("webview_service")) {
3904 startResult = startWebView(entryPoint,
3905 app.processName, uid, uid, gids, debugFlags, mountExternal,
3906 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3907 app.info.dataDir, null, entryPointArgs);
3909 startResult = Process.start(entryPoint,
3910 app.processName, uid, uid, gids, debugFlags, mountExternal,
3911 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3912 app.info.dataDir, invokeWith, entryPointArgs);
3914 checkTime(startTime, "startProcess: returned from zygote!");
3915 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3917 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3918 checkTime(startTime, "startProcess: done updating battery stats");
3920 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3921 UserHandle.getUserId(uid), startResult.pid, uid,
3922 app.processName, hostingType,
3923 hostingNameStr != null ? hostingNameStr : "");
3926 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3927 seInfo, app.info.sourceDir, startResult.pid);
3928 } catch (RemoteException ex) {
3932 if (app.persistent) {
3933 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3936 checkTime(startTime, "startProcess: building log message");
3937 StringBuilder buf = mStringBuilder;
3939 buf.append("Start proc ");
3940 buf.append(startResult.pid);
3942 buf.append(app.processName);
3944 UserHandle.formatUid(buf, uid);
3945 if (!isActivityProcess) {
3947 buf.append(entryPoint);
3950 buf.append(" for ");
3951 buf.append(hostingType);
3952 if (hostingNameStr != null) {
3954 buf.append(hostingNameStr);
3956 Slog.i(TAG, buf.toString());
3957 app.setPid(startResult.pid);
3958 app.usingWrapper = startResult.usingWrapper;
3959 app.removed = false;
3961 app.killedByAm = false;
3962 checkTime(startTime, "startProcess: starting to update pids map");
3963 ProcessRecord oldApp;
3964 synchronized (mPidsSelfLocked) {
3965 oldApp = mPidsSelfLocked.get(startResult.pid);
3967 // If there is already an app occupying that pid that hasn't been cleaned up
3968 if (oldApp != null && !app.isolated) {
3969 // Clean up anything relating to this pid first
3970 Slog.w(TAG, "Reusing pid " + startResult.pid
3971 + " while app is still mapped to it");
3972 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3973 true /*replacingPid*/);
3975 synchronized (mPidsSelfLocked) {
3976 this.mPidsSelfLocked.put(startResult.pid, app);
3977 if (isActivityProcess) {
3978 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3980 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3981 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3984 checkTime(startTime, "startProcess: done updating pids map");
3985 } catch (RuntimeException e) {
3986 Slog.e(TAG, "Failure starting process " + app.processName, e);
3988 // Something went very wrong while trying to start this process; one
3989 // common case is when the package is frozen due to an active
3990 // upgrade. To recover, clean up any active bookkeeping related to
3991 // starting this process. (We already invoked this method once when
3992 // the package was initially frozen through KILL_APPLICATION_MSG, so
3993 // it doesn't hurt to use it again.)
3994 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3995 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3999 void updateUsageStats(ActivityRecord component, boolean resumed) {
4000 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4001 "updateUsageStats: comp=" + component + "res=" + resumed);
4002 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4004 if (mUsageStatsService != null) {
4005 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4006 UsageEvents.Event.MOVE_TO_FOREGROUND);
4008 synchronized (stats) {
4009 stats.noteActivityResumedLocked(component.app.uid);
4012 if (mUsageStatsService != null) {
4013 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4014 UsageEvents.Event.MOVE_TO_BACKGROUND);
4016 synchronized (stats) {
4017 stats.noteActivityPausedLocked(component.app.uid);
4022 Intent getHomeIntent() {
4023 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4024 intent.setComponent(mTopComponent);
4025 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4026 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4027 intent.addCategory(Intent.CATEGORY_HOME);
4032 boolean startHomeActivityLocked(int userId, String reason) {
4033 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4034 && mTopAction == null) {
4035 // We are running in factory test mode, but unable to find
4036 // the factory test app, so just sit around displaying the
4037 // error message and don't try to start anything.
4040 Intent intent = getHomeIntent();
4041 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4042 if (aInfo != null) {
4043 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4044 // Don't do this if the home app is currently being
4046 aInfo = new ActivityInfo(aInfo);
4047 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4048 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4049 aInfo.applicationInfo.uid, true);
4050 if (app == null || app.instr == null) {
4051 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4052 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4053 // For ANR debugging to verify if the user activity is the one that actually
4055 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4056 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4059 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4065 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4066 ActivityInfo ai = null;
4067 ComponentName comp = intent.getComponent();
4071 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4073 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4075 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4079 ai = info.activityInfo;
4082 } catch (RemoteException e) {
4090 * Starts the "new version setup screen" if appropriate.
4092 void startSetupActivityLocked() {
4093 // Only do this once per boot.
4094 if (mCheckedForSetup) {
4098 // We will show this screen if the current one is a different
4099 // version than the last one shown, and we are not running in
4100 // low-level factory test mode.
4101 final ContentResolver resolver = mContext.getContentResolver();
4102 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4103 Settings.Global.getInt(resolver,
4104 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4105 mCheckedForSetup = true;
4107 // See if we should be showing the platform update setup UI.
4108 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4109 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4110 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4111 if (!ris.isEmpty()) {
4112 final ResolveInfo ri = ris.get(0);
4113 String vers = ri.activityInfo.metaData != null
4114 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4116 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4117 vers = ri.activityInfo.applicationInfo.metaData.getString(
4118 Intent.METADATA_SETUP_VERSION);
4120 String lastVers = Settings.Secure.getString(
4121 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4122 if (vers != null && !vers.equals(lastVers)) {
4123 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4124 intent.setComponent(new ComponentName(
4125 ri.activityInfo.packageName, ri.activityInfo.name));
4126 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4127 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4128 null, 0, 0, 0, null, false, false, null, null, null,
4129 "startSetupActivity");
4135 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4136 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4139 void enforceNotIsolatedCaller(String caller) {
4140 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4141 throw new SecurityException("Isolated process not allowed to call " + caller);
4145 void enforceShellRestriction(String restriction, int userHandle) {
4146 if (Binder.getCallingUid() == SHELL_UID) {
4147 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4148 throw new SecurityException("Shell does not have permission to access user "
4155 public int getFrontActivityScreenCompatMode() {
4156 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4157 synchronized (this) {
4158 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4163 public void setFrontActivityScreenCompatMode(int mode) {
4164 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4165 "setFrontActivityScreenCompatMode");
4166 synchronized (this) {
4167 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4172 public int getPackageScreenCompatMode(String packageName) {
4173 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4174 synchronized (this) {
4175 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4180 public void setPackageScreenCompatMode(String packageName, int mode) {
4181 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4182 "setPackageScreenCompatMode");
4183 synchronized (this) {
4184 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4189 public boolean getPackageAskScreenCompat(String packageName) {
4190 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4191 synchronized (this) {
4192 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4197 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4198 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4199 "setPackageAskScreenCompat");
4200 synchronized (this) {
4201 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4205 private boolean hasUsageStatsPermission(String callingPackage) {
4206 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4207 Binder.getCallingUid(), callingPackage);
4208 if (mode == AppOpsManager.MODE_DEFAULT) {
4209 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4210 == PackageManager.PERMISSION_GRANTED;
4212 return mode == AppOpsManager.MODE_ALLOWED;
4216 public int getPackageProcessState(String packageName, String callingPackage) {
4217 if (!hasUsageStatsPermission(callingPackage)) {
4218 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4219 "getPackageProcessState");
4222 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4223 synchronized (this) {
4224 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4225 final ProcessRecord proc = mLruProcesses.get(i);
4226 if (procState > proc.setProcState) {
4227 if (proc.pkgList.containsKey(packageName) ||
4228 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4229 procState = proc.setProcState;
4238 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4239 throws RemoteException {
4240 synchronized (this) {
4241 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4243 throw new IllegalArgumentException("Unknown process: " + process);
4245 if (app.thread == null) {
4246 throw new IllegalArgumentException("Process has no app thread");
4248 if (app.trimMemoryLevel >= level) {
4249 throw new IllegalArgumentException(
4250 "Unable to set a higher trim level than current level");
4252 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4253 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4254 throw new IllegalArgumentException("Unable to set a background trim level "
4255 + "on a foreground process");
4257 app.thread.scheduleTrimMemory(level);
4258 app.trimMemoryLevel = level;
4263 private void dispatchProcessesChanged() {
4265 synchronized (this) {
4266 N = mPendingProcessChanges.size();
4267 if (mActiveProcessChanges.length < N) {
4268 mActiveProcessChanges = new ProcessChangeItem[N];
4270 mPendingProcessChanges.toArray(mActiveProcessChanges);
4271 mPendingProcessChanges.clear();
4272 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4273 "*** Delivering " + N + " process changes");
4276 int i = mProcessObservers.beginBroadcast();
4279 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4280 if (observer != null) {
4282 for (int j=0; j<N; j++) {
4283 ProcessChangeItem item = mActiveProcessChanges[j];
4284 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4285 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4286 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4287 + item.uid + ": " + item.foregroundActivities);
4288 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4289 item.foregroundActivities);
4292 } catch (RemoteException e) {
4296 mProcessObservers.finishBroadcast();
4298 synchronized (this) {
4299 for (int j=0; j<N; j++) {
4300 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4305 private void dispatchProcessDied(int pid, int uid) {
4306 int i = mProcessObservers.beginBroadcast();
4309 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4310 if (observer != null) {
4312 observer.onProcessDied(pid, uid);
4313 } catch (RemoteException e) {
4317 mProcessObservers.finishBroadcast();
4321 void dispatchUidsChanged() {
4323 synchronized (this) {
4324 N = mPendingUidChanges.size();
4325 if (mActiveUidChanges.length < N) {
4326 mActiveUidChanges = new UidRecord.ChangeItem[N];
4328 for (int i=0; i<N; i++) {
4329 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4330 mActiveUidChanges[i] = change;
4331 if (change.uidRecord != null) {
4332 change.uidRecord.pendingChange = null;
4333 change.uidRecord = null;
4336 mPendingUidChanges.clear();
4337 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4338 "*** Delivering " + N + " uid changes");
4341 int i = mUidObservers.beginBroadcast();
4344 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4345 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4347 mUidObservers.finishBroadcast();
4349 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4350 for (int j = 0; j < N; ++j) {
4351 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4352 if (item.change == UidRecord.CHANGE_GONE
4353 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4354 mValidateUids.remove(item.uid);
4356 UidRecord validateUid = mValidateUids.get(item.uid);
4357 if (validateUid == null) {
4358 validateUid = new UidRecord(item.uid);
4359 mValidateUids.put(item.uid, validateUid);
4361 if (item.change == UidRecord.CHANGE_IDLE) {
4362 validateUid.idle = true;
4363 } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4364 validateUid.idle = false;
4366 validateUid.curProcState = validateUid.setProcState = item.processState;
4367 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4372 synchronized (this) {
4373 for (int j = 0; j < N; j++) {
4374 mAvailUidChanges.add(mActiveUidChanges[j]);
4379 private void dispatchUidsChangedForObserver(IUidObserver observer,
4380 UidObserverRegistration reg, int changesSize) {
4381 if (observer == null) {
4385 for (int j = 0; j < changesSize; j++) {
4386 UidRecord.ChangeItem item = mActiveUidChanges[j];
4387 final int change = item.change;
4388 if (change == UidRecord.CHANGE_IDLE
4389 || change == UidRecord.CHANGE_GONE_IDLE) {
4390 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4391 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4392 "UID idle uid=" + item.uid);
4393 observer.onUidIdle(item.uid, item.ephemeral);
4395 } else if (change == UidRecord.CHANGE_ACTIVE) {
4396 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4397 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4398 "UID active uid=" + item.uid);
4399 observer.onUidActive(item.uid);
4402 if (change == UidRecord.CHANGE_GONE
4403 || change == UidRecord.CHANGE_GONE_IDLE) {
4404 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4405 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4406 "UID gone uid=" + item.uid);
4407 observer.onUidGone(item.uid, item.ephemeral);
4409 if (reg.lastProcStates != null) {
4410 reg.lastProcStates.delete(item.uid);
4413 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4414 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4415 "UID CHANGED uid=" + item.uid
4416 + ": " + item.processState);
4417 boolean doReport = true;
4418 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4419 final int lastState = reg.lastProcStates.get(item.uid,
4420 ActivityManager.PROCESS_STATE_UNKNOWN);
4421 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4422 final boolean lastAboveCut = lastState <= reg.cutpoint;
4423 final boolean newAboveCut = item.processState <= reg.cutpoint;
4424 doReport = lastAboveCut != newAboveCut;
4426 doReport = item.processState
4427 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4431 if (reg.lastProcStates != null) {
4432 reg.lastProcStates.put(item.uid, item.processState);
4434 observer.onUidStateChanged(item.uid, item.processState,
4440 } catch (RemoteException e) {
4445 public final int startActivity(IApplicationThread caller, String callingPackage,
4446 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4447 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4448 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4449 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4450 UserHandle.getCallingUserId());
4453 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4454 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4455 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4456 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4457 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4459 // TODO: Switch to user app stacks here.
4460 String mimeType = intent.getType();
4461 final Uri data = intent.getData();
4462 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4463 mimeType = getProviderMimeType(data, userId);
4465 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4467 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4468 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
4469 null, null, 0, 0, null, null, null, null, false, userId, container, null,
4474 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4475 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4476 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4477 enforceNotIsolatedCaller("startActivity");
4478 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4479 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4480 // TODO: Switch to user app stacks here.
4481 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4482 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4483 profilerInfo, null, null, bOptions, false, userId, null, null,
4484 "startActivityAsUser");
4488 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4489 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4490 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4493 // This is very dangerous -- it allows you to perform a start activity (including
4494 // permission grants) as any app that may launch one of your own activities. So
4495 // we will only allow this to be done from activities that are part of the core framework,
4496 // and then only when they are running as the system.
4497 final ActivityRecord sourceRecord;
4498 final int targetUid;
4499 final String targetPackage;
4500 synchronized (this) {
4501 if (resultTo == null) {
4502 throw new SecurityException("Must be called from an activity");
4504 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4505 if (sourceRecord == null) {
4506 throw new SecurityException("Called with bad activity token: " + resultTo);
4508 if (!sourceRecord.info.packageName.equals("android")) {
4509 throw new SecurityException(
4510 "Must be called from an activity that is declared in the android package");
4512 if (sourceRecord.app == null) {
4513 throw new SecurityException("Called without a process attached to activity");
4515 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4516 // This is still okay, as long as this activity is running under the
4517 // uid of the original calling activity.
4518 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4519 throw new SecurityException(
4520 "Calling activity in uid " + sourceRecord.app.uid
4521 + " must be system uid or original calling uid "
4522 + sourceRecord.launchedFromUid);
4525 if (ignoreTargetSecurity) {
4526 if (intent.getComponent() == null) {
4527 throw new SecurityException(
4528 "Component must be specified with ignoreTargetSecurity");
4530 if (intent.getSelector() != null) {
4531 throw new SecurityException(
4532 "Selector not allowed with ignoreTargetSecurity");
4535 targetUid = sourceRecord.launchedFromUid;
4536 targetPackage = sourceRecord.launchedFromPackage;
4539 if (userId == UserHandle.USER_NULL) {
4540 userId = UserHandle.getUserId(sourceRecord.app.uid);
4543 // TODO: Switch to user app stacks here.
4545 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4546 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4547 null, null, bOptions, ignoreTargetSecurity, userId, null, null,
4548 "startActivityAsCaller");
4550 } catch (SecurityException e) {
4551 // XXX need to figure out how to propagate to original app.
4552 // A SecurityException here is generally actually a fault of the original
4553 // calling activity (such as a fairly granting permissions), so propagate it
4556 StringBuilder msg = new StringBuilder();
4557 msg.append("While launching");
4558 msg.append(intent.toString());
4560 msg.append(e.getMessage());
4567 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4568 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4569 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4570 enforceNotIsolatedCaller("startActivityAndWait");
4571 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4572 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4573 WaitResult res = new WaitResult();
4574 // TODO: Switch to user app stacks here.
4575 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4576 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4577 bOptions, false, userId, null, null, "startActivityAndWait");
4582 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4583 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4584 int startFlags, Configuration config, Bundle bOptions, int userId) {
4585 enforceNotIsolatedCaller("startActivityWithConfig");
4586 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4587 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4588 // TODO: Switch to user app stacks here.
4589 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4590 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4591 null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
4596 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4597 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4598 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4599 throws TransactionTooLargeException {
4600 enforceNotIsolatedCaller("startActivityIntentSender");
4601 // Refuse possible leaked file descriptors
4602 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4603 throw new IllegalArgumentException("File descriptors passed in Intent");
4606 if (!(target instanceof PendingIntentRecord)) {
4607 throw new IllegalArgumentException("Bad PendingIntent object");
4610 PendingIntentRecord pir = (PendingIntentRecord)target;
4612 synchronized (this) {
4613 // If this is coming from the currently resumed activity, it is
4614 // effectively saying that app switches are allowed at this point.
4615 final ActivityStack stack = getFocusedStack();
4616 if (stack.mResumedActivity != null &&
4617 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4618 mAppSwitchesAllowedTime = 0;
4621 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4622 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4627 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4628 Intent intent, String resolvedType, IVoiceInteractionSession session,
4629 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4630 Bundle bOptions, int userId) {
4631 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4632 != PackageManager.PERMISSION_GRANTED) {
4633 String msg = "Permission Denial: startVoiceActivity() from pid="
4634 + Binder.getCallingPid()
4635 + ", uid=" + Binder.getCallingUid()
4636 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4638 throw new SecurityException(msg);
4640 if (session == null || interactor == null) {
4641 throw new NullPointerException("null session or interactor");
4643 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4644 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4645 // TODO: Switch to user app stacks here.
4646 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4647 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4648 null, bOptions, false, userId, null, null, "startVoiceActivity");
4652 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4653 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4654 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4655 != PackageManager.PERMISSION_GRANTED) {
4656 final String msg = "Permission Denial: startAssistantActivity() from pid="
4657 + Binder.getCallingPid()
4658 + ", uid=" + Binder.getCallingUid()
4659 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4661 throw new SecurityException(msg);
4663 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4664 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4665 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4666 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4667 userId, null, null, "startAssistantActivity");
4671 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4672 throws RemoteException {
4673 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4674 synchronized (this) {
4675 ActivityRecord activity = getFocusedStack().topActivity();
4676 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4677 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4679 if (mRunningVoice != null || activity.getTask().voiceSession != null
4680 || activity.voiceSession != null) {
4681 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4684 if (activity.pendingVoiceInteractionStart) {
4685 Slog.w(TAG, "Pending start of voice interaction already.");
4688 activity.pendingVoiceInteractionStart = true;
4690 LocalServices.getService(VoiceInteractionManagerInternal.class)
4691 .startLocalVoiceInteraction(callingActivity, options);
4695 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4696 LocalServices.getService(VoiceInteractionManagerInternal.class)
4697 .stopLocalVoiceInteraction(callingActivity);
4701 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4702 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4703 .supportsLocalVoiceInteraction();
4706 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4707 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4708 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4709 if (activityToCallback == null) return;
4710 activityToCallback.setVoiceSessionLocked(voiceSession);
4712 // Inform the activity
4714 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4716 long token = Binder.clearCallingIdentity();
4718 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4720 Binder.restoreCallingIdentity(token);
4722 // TODO: VI Should we cache the activity so that it's easier to find later
4723 // rather than scan through all the stacks and activities?
4724 } catch (RemoteException re) {
4725 activityToCallback.clearVoiceSessionLocked();
4726 // TODO: VI Should this terminate the voice session?
4731 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4732 synchronized (this) {
4733 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4735 mVoiceWakeLock.acquire();
4737 mVoiceWakeLock.release();
4744 public boolean startNextMatchingActivity(IBinder callingActivity,
4745 Intent intent, Bundle bOptions) {
4746 // Refuse possible leaked file descriptors
4747 if (intent != null && intent.hasFileDescriptors() == true) {
4748 throw new IllegalArgumentException("File descriptors passed in Intent");
4750 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4752 synchronized (this) {
4753 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4755 ActivityOptions.abort(options);
4758 if (r.app == null || r.app.thread == null) {
4759 // The caller is not running... d'oh!
4760 ActivityOptions.abort(options);
4763 intent = new Intent(intent);
4764 // The caller is not allowed to change the data.
4765 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4766 // And we are resetting to find the next component...
4767 intent.setComponent(null);
4769 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4771 ActivityInfo aInfo = null;
4773 List<ResolveInfo> resolves =
4774 AppGlobals.getPackageManager().queryIntentActivities(
4775 intent, r.resolvedType,
4776 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4777 UserHandle.getCallingUserId()).getList();
4779 // Look for the original activity in the list...
4780 final int N = resolves != null ? resolves.size() : 0;
4781 for (int i=0; i<N; i++) {
4782 ResolveInfo rInfo = resolves.get(i);
4783 if (rInfo.activityInfo.packageName.equals(r.packageName)
4784 && rInfo.activityInfo.name.equals(r.info.name)) {
4785 // We found the current one... the next matching is
4789 aInfo = resolves.get(i).activityInfo;
4792 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4793 + "/" + r.info.name);
4794 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4795 ? "null" : aInfo.packageName + "/" + aInfo.name));
4800 } catch (RemoteException e) {
4803 if (aInfo == null) {
4804 // Nobody who is next!
4805 ActivityOptions.abort(options);
4806 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4810 intent.setComponent(new ComponentName(
4811 aInfo.applicationInfo.packageName, aInfo.name));
4812 intent.setFlags(intent.getFlags()&~(
4813 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4814 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4815 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4816 Intent.FLAG_ACTIVITY_NEW_TASK));
4818 // Okay now we need to start the new activity, replacing the
4819 // currently running activity. This is a little tricky because
4820 // we want to start the new one as if the current one is finished,
4821 // but not finish the current one first so that there is no flicker.
4823 final boolean wasFinishing = r.finishing;
4826 // Propagate reply information over to the new activity.
4827 final ActivityRecord resultTo = r.resultTo;
4828 final String resultWho = r.resultWho;
4829 final int requestCode = r.requestCode;
4831 if (resultTo != null) {
4832 resultTo.removeResultsLocked(r, resultWho, requestCode);
4835 final long origId = Binder.clearCallingIdentity();
4836 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4837 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4838 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4839 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4840 false, false, null, null, null, "startNextMatchingActivity");
4841 Binder.restoreCallingIdentity(origId);
4843 r.finishing = wasFinishing;
4844 if (res != ActivityManager.START_SUCCESS) {
4852 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4853 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4854 String msg = "Permission Denial: startActivityFromRecents called without " +
4855 START_TASKS_FROM_RECENTS;
4857 throw new SecurityException(msg);
4859 final long origId = Binder.clearCallingIdentity();
4861 synchronized (this) {
4862 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4865 Binder.restoreCallingIdentity(origId);
4869 final int startActivityInPackage(int uid, String callingPackage,
4870 Intent intent, String resolvedType, IBinder resultTo,
4871 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4872 IActivityContainer container, TaskRecord inTask, String reason) {
4874 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4875 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4877 // TODO: Switch to user app stacks here.
4878 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4879 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4880 null, null, null, bOptions, false, userId, container, inTask, reason);
4885 public final int startActivities(IApplicationThread caller, String callingPackage,
4886 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4888 final String reason = "startActivities";
4889 enforceNotIsolatedCaller(reason);
4890 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4891 userId, false, ALLOW_FULL_ONLY, reason, null);
4892 // TODO: Switch to user app stacks here.
4893 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4894 resolvedTypes, resultTo, bOptions, userId, reason);
4898 final int startActivitiesInPackage(int uid, String callingPackage,
4899 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4900 Bundle bOptions, int userId) {
4902 final String reason = "startActivityInPackage";
4903 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4904 userId, false, ALLOW_FULL_ONLY, reason, null);
4905 // TODO: Switch to user app stacks here.
4906 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4907 resultTo, bOptions, userId, reason);
4912 public void reportActivityFullyDrawn(IBinder token) {
4913 synchronized (this) {
4914 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4918 r.reportFullyDrawnLocked();
4923 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4924 synchronized (this) {
4925 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4929 final long origId = Binder.clearCallingIdentity();
4931 r.setRequestedOrientation(requestedOrientation);
4933 Binder.restoreCallingIdentity(origId);
4939 public int getRequestedOrientation(IBinder token) {
4940 synchronized (this) {
4941 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4943 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4945 return r.getRequestedOrientation();
4950 public final void requestActivityRelaunch(IBinder token) {
4951 synchronized(this) {
4952 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4956 final long origId = Binder.clearCallingIdentity();
4958 r.forceNewConfig = true;
4959 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4960 true /* preserveWindow */);
4962 Binder.restoreCallingIdentity(origId);
4968 * This is the internal entry point for handling Activity.finish().
4970 * @param token The Binder token referencing the Activity we want to finish.
4971 * @param resultCode Result code, if any, from this Activity.
4972 * @param resultData Result data (Intent), if any, from this Activity.
4973 * @param finishTask Whether to finish the task associated with this Activity.
4975 * @return Returns true if the activity successfully finished, or false if it is still running.
4978 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4980 // Refuse possible leaked file descriptors
4981 if (resultData != null && resultData.hasFileDescriptors() == true) {
4982 throw new IllegalArgumentException("File descriptors passed in Intent");
4985 synchronized(this) {
4986 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4990 // Keep track of the root activity of the task before we finish it
4991 TaskRecord tr = r.getTask();
4992 ActivityRecord rootR = tr.getRootActivity();
4993 if (rootR == null) {
4994 Slog.w(TAG, "Finishing task with all activities already finished");
4996 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4998 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4999 mStackSupervisor.isLastLockedTask(tr)) {
5000 Slog.i(TAG, "Not finishing task in lock task mode");
5001 mStackSupervisor.showLockTaskToast();
5004 if (mController != null) {
5005 // Find the first activity that is not finishing.
5006 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5008 // ask watcher if this is allowed
5009 boolean resumeOK = true;
5011 resumeOK = mController.activityResuming(next.packageName);
5012 } catch (RemoteException e) {
5014 Watchdog.getInstance().setActivityController(null);
5018 Slog.i(TAG, "Not finishing activity because controller resumed");
5023 final long origId = Binder.clearCallingIdentity();
5026 final boolean finishWithRootActivity =
5027 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5028 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5029 || (finishWithRootActivity && r == rootR)) {
5030 // If requested, remove the task that is associated to this activity only if it
5031 // was the root activity in the task. The result code and data is ignored
5032 // because we don't support returning them across task boundaries. Also, to
5033 // keep backwards compatibility we remove the task from recents when finishing
5034 // task with root activity.
5035 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5037 Slog.i(TAG, "Removing task failed to finish activity");
5040 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5041 resultData, "app-request", true);
5043 Slog.i(TAG, "Failed to finish by app-request");
5048 Binder.restoreCallingIdentity(origId);
5054 public final void finishHeavyWeightApp() {
5055 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5056 != PackageManager.PERMISSION_GRANTED) {
5057 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5058 + Binder.getCallingPid()
5059 + ", uid=" + Binder.getCallingUid()
5060 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5062 throw new SecurityException(msg);
5065 synchronized(this) {
5066 if (mHeavyWeightProcess == null) {
5070 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5071 for (int i = 0; i < activities.size(); i++) {
5072 ActivityRecord r = activities.get(i);
5073 if (!r.finishing && r.isInStackLocked()) {
5074 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5075 null, "finish-heavy", true);
5079 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5080 mHeavyWeightProcess.userId, 0));
5081 mHeavyWeightProcess = null;
5086 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5088 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5089 != PackageManager.PERMISSION_GRANTED) {
5090 String msg = "Permission Denial: crashApplication() from pid="
5091 + Binder.getCallingPid()
5092 + ", uid=" + Binder.getCallingUid()
5093 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5095 throw new SecurityException(msg);
5098 synchronized(this) {
5099 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5104 public final void finishSubActivity(IBinder token, String resultWho,
5106 synchronized(this) {
5107 final long origId = Binder.clearCallingIdentity();
5108 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5110 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5112 Binder.restoreCallingIdentity(origId);
5117 public boolean finishActivityAffinity(IBinder token) {
5118 synchronized(this) {
5119 final long origId = Binder.clearCallingIdentity();
5121 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5126 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5128 final TaskRecord task = r.getTask();
5129 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5130 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5131 mStackSupervisor.showLockTaskToast();
5134 return task.getStack().finishActivityAffinityLocked(r);
5136 Binder.restoreCallingIdentity(origId);
5142 public void finishVoiceTask(IVoiceInteractionSession session) {
5143 synchronized (this) {
5144 final long origId = Binder.clearCallingIdentity();
5146 // TODO: VI Consider treating local voice interactions and voice tasks
5148 mStackSupervisor.finishVoiceTask(session);
5150 Binder.restoreCallingIdentity(origId);
5157 public boolean releaseActivityInstance(IBinder token) {
5158 synchronized(this) {
5159 final long origId = Binder.clearCallingIdentity();
5161 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5165 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5167 Binder.restoreCallingIdentity(origId);
5173 public void releaseSomeActivities(IApplicationThread appInt) {
5174 synchronized(this) {
5175 final long origId = Binder.clearCallingIdentity();
5177 ProcessRecord app = getRecordForAppLocked(appInt);
5178 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5180 Binder.restoreCallingIdentity(origId);
5186 public boolean willActivityBeVisible(IBinder token) {
5187 synchronized(this) {
5188 ActivityStack stack = ActivityRecord.getStackLocked(token);
5189 if (stack != null) {
5190 return stack.willActivityBeVisibleLocked(token);
5197 public void overridePendingTransition(IBinder token, String packageName,
5198 int enterAnim, int exitAnim) {
5199 synchronized(this) {
5200 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5205 final long origId = Binder.clearCallingIdentity();
5207 if (self.state == ActivityState.RESUMED
5208 || self.state == ActivityState.PAUSING) {
5209 mWindowManager.overridePendingAppTransition(packageName,
5210 enterAnim, exitAnim, null);
5213 Binder.restoreCallingIdentity(origId);
5218 * Main function for removing an existing process from the activity manager
5219 * as a result of that process going away. Clears out all connections
5222 private final void handleAppDiedLocked(ProcessRecord app,
5223 boolean restarting, boolean allowRestart) {
5225 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5226 false /*replacingPid*/);
5227 if (!kept && !restarting) {
5228 removeLruProcessLocked(app);
5230 ProcessList.remove(pid);
5234 if (mProfileProc == app) {
5235 clearProfilerLocked();
5238 // Remove this application's activities from active lists.
5239 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5241 app.activities.clear();
5243 if (app.instr != null) {
5244 Slog.w(TAG, "Crash of app " + app.processName
5245 + " running instrumentation " + app.instr.mClass);
5246 Bundle info = new Bundle();
5247 info.putString("shortMsg", "Process crashed.");
5248 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5251 mWindowManager.deferSurfaceLayout();
5253 if (!restarting && hasVisibleActivities
5254 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5255 // If there was nothing to resume, and we are not already restarting this process, but
5256 // there is a visible activity that is hosted by the process... then make sure all
5257 // visible activities are running, taking care of restarting this process.
5258 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5261 mWindowManager.continueSurfaceLayout();
5265 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5266 final IBinder threadBinder = thread.asBinder();
5267 // Find the application record.
5268 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5269 final ProcessRecord rec = mLruProcesses.get(i);
5270 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5277 final ProcessRecord getRecordForAppLocked(
5278 IApplicationThread thread) {
5279 if (thread == null) {
5283 int appIndex = getLRURecordIndexForAppLocked(thread);
5284 if (appIndex >= 0) {
5285 return mLruProcesses.get(appIndex);
5288 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5289 // double-check that.
5290 final IBinder threadBinder = thread.asBinder();
5291 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5292 for (int i = pmap.size()-1; i >= 0; i--) {
5293 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5294 for (int j = procs.size()-1; j >= 0; j--) {
5295 final ProcessRecord proc = procs.valueAt(j);
5296 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5297 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5307 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5308 // If there are no longer any background processes running,
5309 // and the app that died was not running instrumentation,
5310 // then tell everyone we are now low on memory.
5311 boolean haveBg = false;
5312 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5313 ProcessRecord rec = mLruProcesses.get(i);
5314 if (rec.thread != null
5315 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5322 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5324 long now = SystemClock.uptimeMillis();
5325 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5328 mLastMemUsageReportTime = now;
5331 final ArrayList<ProcessMemInfo> memInfos
5332 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5333 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5334 long now = SystemClock.uptimeMillis();
5335 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5336 ProcessRecord rec = mLruProcesses.get(i);
5337 if (rec == dyingProc || rec.thread == null) {
5341 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5342 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5344 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5345 // The low memory report is overriding any current
5346 // state for a GC request. Make sure to do
5347 // heavy/important/visible/foreground processes first.
5348 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5349 rec.lastRequestedGc = 0;
5351 rec.lastRequestedGc = rec.lastLowMemory;
5353 rec.reportLowMemory = true;
5354 rec.lastLowMemory = now;
5355 mProcessesToGc.remove(rec);
5356 addProcessToGcListLocked(rec);
5360 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5361 mHandler.sendMessage(msg);
5363 scheduleAppGcsLocked();
5367 final void appDiedLocked(ProcessRecord app) {
5368 appDiedLocked(app, app.pid, app.thread, false);
5371 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5372 boolean fromBinderDied) {
5373 // First check if this ProcessRecord is actually active for the pid.
5374 synchronized (mPidsSelfLocked) {
5375 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5376 if (curProc != app) {
5377 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5382 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5383 synchronized (stats) {
5384 stats.noteProcessDiedLocked(app.info.uid, pid);
5388 if (!fromBinderDied) {
5389 killProcessQuiet(pid);
5391 killProcessGroup(app.uid, pid);
5395 // Clean up already done if the process has been re-started.
5396 if (app.pid == pid && app.thread != null &&
5397 app.thread.asBinder() == thread.asBinder()) {
5398 boolean doLowMem = app.instr == null;
5399 boolean doOomAdj = doLowMem;
5400 if (!app.killedByAm) {
5401 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5402 + ProcessList.makeOomAdjString(app.setAdj)
5403 + ProcessList.makeProcStateString(app.setProcState));
5404 mAllowLowerMemLevel = true;
5406 // Note that we always want to do oom adj to update our state with the
5407 // new number of procs.
5408 mAllowLowerMemLevel = false;
5411 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5412 app.setAdj, app.setProcState);
5413 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5414 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5415 handleAppDiedLocked(app, false, true);
5418 updateOomAdjLocked();
5421 doLowMemReportIfNeededLocked(app);
5423 } else if (app.pid != pid) {
5424 // A new process has already been started.
5425 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5426 + ") has died and restarted (pid " + app.pid + ").");
5427 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5428 } else if (DEBUG_PROCESSES) {
5429 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5430 + thread.asBinder());
5435 * If a stack trace dump file is configured, dump process stack traces.
5436 * @param clearTraces causes the dump file to be erased prior to the new
5437 * traces being written, if true; when false, the new traces will be
5438 * appended to any existing file content.
5439 * @param firstPids of dalvik VM processes to dump stack traces for first
5440 * @param lastPids of dalvik VM processes to dump stack traces for last
5441 * @param nativePids optional list of native pids to dump stack crawls
5443 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5444 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5445 ArrayList<Integer> nativePids) {
5446 ArrayList<Integer> extraPids = null;
5448 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5449 // of the top users at the time of the request.
5450 if (processCpuTracker != null) {
5451 processCpuTracker.init();
5454 } catch (InterruptedException ignored) {
5457 processCpuTracker.update();
5459 // We'll take the stack crawls of just the top apps using CPU.
5460 final int N = processCpuTracker.countWorkingStats();
5461 extraPids = new ArrayList<>();
5462 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5463 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5464 if (lastPids.indexOfKey(stats.pid) >= 0) {
5465 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5467 extraPids.add(stats.pid);
5468 } else if (DEBUG_ANR) {
5469 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5475 boolean useTombstonedForJavaTraces = false;
5478 final String tracesDir = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5479 if (tracesDir.isEmpty()) {
5480 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5481 // dumping scheme. All traces are written to a global trace file (usually
5482 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5483 // the file if requested.
5485 // This mode of operation will be removed in the near future.
5488 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5489 if (globalTracesPath.isEmpty()) {
5490 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5494 tracesFile = new File(globalTracesPath);
5496 if (clearTraces && tracesFile.exists()) {
5497 tracesFile.delete();
5500 tracesFile.createNewFile();
5501 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5502 } catch (IOException e) {
5503 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5507 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5508 // Each set of ANR traces is written to a separate file and dumpstate will process
5509 // all such files and add them to a captured bug report if they're recent enough.
5511 // NOTE: We should consider creating the file in native code atomically once we've
5512 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5515 tracesFile = File.createTempFile("anr_", "", new File(tracesDir));
5516 FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5517 } catch (IOException ioe) {
5518 Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
5522 useTombstonedForJavaTraces = true;
5525 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5526 useTombstonedForJavaTraces);
5531 * Legacy code, do not use. Existing users will be deleted.
5536 public static class DumpStackFileObserver extends FileObserver {
5537 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5538 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5540 private final String mTracesPath;
5541 private boolean mClosed;
5543 public DumpStackFileObserver(String tracesPath) {
5544 super(tracesPath, FileObserver.CLOSE_WRITE);
5545 mTracesPath = tracesPath;
5549 public synchronized void onEvent(int event, String path) {
5554 public long dumpWithTimeout(int pid, long timeout) {
5555 sendSignal(pid, SIGNAL_QUIT);
5556 final long start = SystemClock.elapsedRealtime();
5558 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5559 synchronized (this) {
5561 wait(waitTime); // Wait for traces file to be closed.
5562 } catch (InterruptedException e) {
5567 // This avoids a corner case of passing a negative time to the native
5568 // trace in case we've already hit the overall timeout.
5569 final long timeWaited = SystemClock.elapsedRealtime() - start;
5570 if (timeWaited >= timeout) {
5575 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5576 ". Attempting native stack collection.");
5578 final long nativeDumpTimeoutMs = Math.min(
5579 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5581 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5582 (int) (nativeDumpTimeoutMs / 1000));
5585 final long end = SystemClock.elapsedRealtime();
5588 return (end - start);
5593 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5594 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5595 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5596 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5599 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5600 final long timeStart = SystemClock.elapsedRealtime();
5601 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5602 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5603 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5606 return SystemClock.elapsedRealtime() - timeStart;
5609 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5610 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5611 boolean useTombstonedForJavaTraces) {
5613 // We don't need any sort of inotify based monitoring when we're dumping traces via
5614 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5615 // control of all writes to the file in question.
5616 final DumpStackFileObserver observer;
5617 if (useTombstonedForJavaTraces) {
5620 // Use a FileObserver to detect when traces finish writing.
5621 // The order of traces is considered important to maintain for legibility.
5622 observer = new DumpStackFileObserver(tracesFile);
5625 // We must complete all stack dumps within 20 seconds.
5626 long remainingTime = 20 * 1000;
5628 if (observer != null) {
5629 observer.startWatching();
5632 // First collect all of the stacks of the most important pids.
5633 if (firstPids != null) {
5634 int num = firstPids.size();
5635 for (int i = 0; i < num; i++) {
5636 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5637 + firstPids.get(i));
5638 final long timeTaken;
5639 if (useTombstonedForJavaTraces) {
5640 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5642 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5645 remainingTime -= timeTaken;
5646 if (remainingTime <= 0) {
5647 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5648 "); deadline exceeded.");
5653 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5658 // Next collect the stacks of the native pids
5659 if (nativePids != null) {
5660 for (int pid : nativePids) {
5661 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5662 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5664 final long start = SystemClock.elapsedRealtime();
5665 Debug.dumpNativeBacktraceToFileTimeout(
5666 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5667 final long timeTaken = SystemClock.elapsedRealtime() - start;
5669 remainingTime -= timeTaken;
5670 if (remainingTime <= 0) {
5671 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5672 "); deadline exceeded.");
5677 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5682 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5683 if (extraPids != null) {
5684 for (int pid : extraPids) {
5685 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5687 final long timeTaken;
5688 if (useTombstonedForJavaTraces) {
5689 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5691 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5694 remainingTime -= timeTaken;
5695 if (remainingTime <= 0) {
5696 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5697 "); deadline exceeded.");
5702 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5707 if (observer != null) {
5708 observer.stopWatching();
5713 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5714 if (true || IS_USER_BUILD) {
5717 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5718 if (tracesPath == null || tracesPath.length() == 0) {
5722 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5723 StrictMode.allowThreadDiskWrites();
5725 final File tracesFile = new File(tracesPath);
5726 final File tracesDir = tracesFile.getParentFile();
5727 final File tracesTmp = new File(tracesDir, "__tmp__");
5729 if (tracesFile.exists()) {
5731 tracesFile.renameTo(tracesTmp);
5733 StringBuilder sb = new StringBuilder();
5734 Time tobj = new Time();
5735 tobj.set(System.currentTimeMillis());
5736 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5738 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5739 sb.append(" since ");
5741 FileOutputStream fos = new FileOutputStream(tracesFile);
5742 fos.write(sb.toString().getBytes());
5744 fos.write("\n*** No application process!".getBytes());
5747 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5748 } catch (IOException e) {
5749 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5754 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5755 firstPids.add(app.pid);
5756 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5759 File lastTracesFile = null;
5760 File curTracesFile = null;
5761 for (int i=9; i>=0; i--) {
5762 String name = String.format(Locale.US, "slow%02d.txt", i);
5763 curTracesFile = new File(tracesDir, name);
5764 if (curTracesFile.exists()) {
5765 if (lastTracesFile != null) {
5766 curTracesFile.renameTo(lastTracesFile);
5768 curTracesFile.delete();
5771 lastTracesFile = curTracesFile;
5773 tracesFile.renameTo(curTracesFile);
5774 if (tracesTmp.exists()) {
5775 tracesTmp.renameTo(tracesFile);
5778 StrictMode.setThreadPolicy(oldPolicy);
5782 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5783 if (!mLaunchWarningShown) {
5784 mLaunchWarningShown = true;
5785 mUiHandler.post(new Runnable() {
5788 synchronized (ActivityManagerService.this) {
5789 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5791 mUiHandler.postDelayed(new Runnable() {
5794 synchronized (ActivityManagerService.this) {
5796 mLaunchWarningShown = false;
5807 public boolean clearApplicationUserData(final String packageName,
5808 final IPackageDataObserver observer, int userId) {
5809 enforceNotIsolatedCaller("clearApplicationUserData");
5810 int uid = Binder.getCallingUid();
5811 int pid = Binder.getCallingPid();
5812 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5813 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5816 long callingId = Binder.clearCallingIdentity();
5818 IPackageManager pm = AppGlobals.getPackageManager();
5820 synchronized(this) {
5821 if (getPackageManagerInternalLocked().isPackageDataProtected(
5822 userId, packageName)) {
5823 throw new SecurityException(
5824 "Cannot clear data for a protected package: " + packageName);
5828 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5829 } catch (RemoteException e) {
5832 Slog.w(TAG, "Invalid packageName: " + packageName);
5833 if (observer != null) {
5835 observer.onRemoveCompleted(packageName, false);
5836 } catch (RemoteException e) {
5837 Slog.i(TAG, "Observer no longer exists.");
5842 if (uid == pkgUid || checkComponentPermission(
5843 android.Manifest.permission.CLEAR_APP_USER_DATA,
5845 == PackageManager.PERMISSION_GRANTED) {
5846 forceStopPackageLocked(packageName, pkgUid, "clear data");
5848 throw new SecurityException("PID " + pid + " does not have permission "
5849 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5850 + " of package " + packageName);
5853 // Remove all tasks match the cleared application package and user
5854 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5855 final TaskRecord tr = mRecentTasks.get(i);
5856 final String taskPackageName =
5857 tr.getBaseIntent().getComponent().getPackageName();
5858 if (tr.userId != userId) continue;
5859 if (!taskPackageName.equals(packageName)) continue;
5860 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5864 final int pkgUidF = pkgUid;
5865 final int userIdF = userId;
5866 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5868 public void onRemoveCompleted(String packageName, boolean succeeded)
5869 throws RemoteException {
5870 synchronized (ActivityManagerService.this) {
5871 finishForceStopPackageLocked(packageName, pkgUidF);
5874 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5875 Uri.fromParts("package", packageName, null));
5876 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5877 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5878 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5879 broadcastIntentInPackage("android", SYSTEM_UID, intent,
5880 null, null, 0, null, null, null, null, false, false, userIdF);
5882 if (observer != null) {
5883 observer.onRemoveCompleted(packageName, succeeded);
5889 // Clear application user data
5890 pm.clearApplicationUserData(packageName, localObserver, userId);
5892 synchronized(this) {
5893 // Remove all permissions granted from/to this package
5894 removeUriPermissionsForPackageLocked(packageName, userId, true);
5897 // Reset notification settings.
5898 INotificationManager inm = NotificationManager.getService();
5899 inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5900 } catch (RemoteException e) {
5903 Binder.restoreCallingIdentity(callingId);
5909 public void killBackgroundProcesses(final String packageName, int userId) {
5910 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5911 != PackageManager.PERMISSION_GRANTED &&
5912 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5913 != PackageManager.PERMISSION_GRANTED) {
5914 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5915 + Binder.getCallingPid()
5916 + ", uid=" + Binder.getCallingUid()
5917 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5919 throw new SecurityException(msg);
5922 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5923 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5924 long callingId = Binder.clearCallingIdentity();
5926 IPackageManager pm = AppGlobals.getPackageManager();
5927 synchronized(this) {
5930 appId = UserHandle.getAppId(
5931 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5932 } catch (RemoteException e) {
5935 Slog.w(TAG, "Invalid packageName: " + packageName);
5938 killPackageProcessesLocked(packageName, appId, userId,
5939 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5942 Binder.restoreCallingIdentity(callingId);
5947 public void killAllBackgroundProcesses() {
5948 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5949 != PackageManager.PERMISSION_GRANTED) {
5950 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5951 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5952 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5954 throw new SecurityException(msg);
5957 final long callingId = Binder.clearCallingIdentity();
5959 synchronized (this) {
5960 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5961 final int NP = mProcessNames.getMap().size();
5962 for (int ip = 0; ip < NP; ip++) {
5963 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5964 final int NA = apps.size();
5965 for (int ia = 0; ia < NA; ia++) {
5966 final ProcessRecord app = apps.valueAt(ia);
5967 if (app.persistent) {
5968 // We don't kill persistent processes.
5973 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5980 final int N = procs.size();
5981 for (int i = 0; i < N; i++) {
5982 removeProcessLocked(procs.get(i), false, true, "kill all background");
5985 mAllowLowerMemLevel = true;
5987 updateOomAdjLocked();
5988 doLowMemReportIfNeededLocked(null);
5991 Binder.restoreCallingIdentity(callingId);
5996 * Kills all background processes, except those matching any of the
5997 * specified properties.
5999 * @param minTargetSdk the target SDK version at or above which to preserve
6000 * processes, or {@code -1} to ignore the target SDK
6001 * @param maxProcState the process state at or below which to preserve
6002 * processes, or {@code -1} to ignore the process state
6004 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6005 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6006 != PackageManager.PERMISSION_GRANTED) {
6007 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6008 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6009 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6011 throw new SecurityException(msg);
6014 final long callingId = Binder.clearCallingIdentity();
6016 synchronized (this) {
6017 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6018 final int NP = mProcessNames.getMap().size();
6019 for (int ip = 0; ip < NP; ip++) {
6020 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6021 final int NA = apps.size();
6022 for (int ia = 0; ia < NA; ia++) {
6023 final ProcessRecord app = apps.valueAt(ia);
6026 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6027 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6034 final int N = procs.size();
6035 for (int i = 0; i < N; i++) {
6036 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6040 Binder.restoreCallingIdentity(callingId);
6045 public void forceStopPackage(final String packageName, int userId) {
6046 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6047 != PackageManager.PERMISSION_GRANTED) {
6048 String msg = "Permission Denial: forceStopPackage() from pid="
6049 + Binder.getCallingPid()
6050 + ", uid=" + Binder.getCallingUid()
6051 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6053 throw new SecurityException(msg);
6055 final int callingPid = Binder.getCallingPid();
6056 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6057 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6058 long callingId = Binder.clearCallingIdentity();
6060 IPackageManager pm = AppGlobals.getPackageManager();
6061 synchronized(this) {
6062 int[] users = userId == UserHandle.USER_ALL
6063 ? mUserController.getUsers() : new int[] { userId };
6064 for (int user : users) {
6067 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6069 } catch (RemoteException e) {
6072 Slog.w(TAG, "Invalid packageName: " + packageName);
6076 pm.setPackageStoppedState(packageName, true, user);
6077 } catch (RemoteException e) {
6078 } catch (IllegalArgumentException e) {
6079 Slog.w(TAG, "Failed trying to unstop package "
6080 + packageName + ": " + e);
6082 if (mUserController.isUserRunningLocked(user, 0)) {
6083 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6084 finishForceStopPackageLocked(packageName, pkgUid);
6089 Binder.restoreCallingIdentity(callingId);
6094 public void addPackageDependency(String packageName) {
6095 synchronized (this) {
6096 int callingPid = Binder.getCallingPid();
6097 if (callingPid == myPid()) {
6102 synchronized (mPidsSelfLocked) {
6103 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6106 if (proc.pkgDeps == null) {
6107 proc.pkgDeps = new ArraySet<String>(1);
6109 proc.pkgDeps.add(packageName);
6115 * The pkg name and app id have to be specified.
6118 public void killApplication(String pkg, int appId, int userId, String reason) {
6122 // Make sure the uid is valid.
6124 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6127 int callerUid = Binder.getCallingUid();
6128 // Only the system server can kill an application
6129 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6130 // Post an aysnc message to kill the application
6131 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6134 Bundle bundle = new Bundle();
6135 bundle.putString("pkg", pkg);
6136 bundle.putString("reason", reason);
6138 mHandler.sendMessage(msg);
6140 throw new SecurityException(callerUid + " cannot kill pkg: " +
6146 public void closeSystemDialogs(String reason) {
6147 enforceNotIsolatedCaller("closeSystemDialogs");
6149 final int pid = Binder.getCallingPid();
6150 final int uid = Binder.getCallingUid();
6151 final long origId = Binder.clearCallingIdentity();
6153 synchronized (this) {
6154 // Only allow this from foreground processes, so that background
6155 // applications can't abuse it to prevent system UI from being shown.
6156 if (uid >= FIRST_APPLICATION_UID) {
6158 synchronized (mPidsSelfLocked) {
6159 proc = mPidsSelfLocked.get(pid);
6161 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6162 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6163 + " from background process " + proc);
6167 closeSystemDialogsLocked(reason);
6170 Binder.restoreCallingIdentity(origId);
6174 void closeSystemDialogsLocked(String reason) {
6175 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6176 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6177 | Intent.FLAG_RECEIVER_FOREGROUND);
6178 if (reason != null) {
6179 intent.putExtra("reason", reason);
6181 mWindowManager.closeSystemDialogs(reason);
6183 mStackSupervisor.closeSystemDialogsLocked();
6185 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6186 AppOpsManager.OP_NONE, null, false, false,
6187 -1, SYSTEM_UID, UserHandle.USER_ALL);
6191 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6192 enforceNotIsolatedCaller("getProcessMemoryInfo");
6193 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6194 for (int i=pids.length-1; i>=0; i--) {
6197 synchronized (this) {
6198 synchronized (mPidsSelfLocked) {
6199 proc = mPidsSelfLocked.get(pids[i]);
6200 oomAdj = proc != null ? proc.setAdj : 0;
6203 infos[i] = new Debug.MemoryInfo();
6204 Debug.getMemoryInfo(pids[i], infos[i]);
6206 synchronized (this) {
6207 if (proc.thread != null && proc.setAdj == oomAdj) {
6208 // Record this for posterity if the process has been stable.
6209 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6210 infos[i].getTotalUss(), false, proc.pkgList);
6219 public long[] getProcessPss(int[] pids) {
6220 enforceNotIsolatedCaller("getProcessPss");
6221 long[] pss = new long[pids.length];
6222 for (int i=pids.length-1; i>=0; i--) {
6225 synchronized (this) {
6226 synchronized (mPidsSelfLocked) {
6227 proc = mPidsSelfLocked.get(pids[i]);
6228 oomAdj = proc != null ? proc.setAdj : 0;
6231 long[] tmpUss = new long[1];
6232 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6234 synchronized (this) {
6235 if (proc.thread != null && proc.setAdj == oomAdj) {
6236 // Record this for posterity if the process has been stable.
6237 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6246 public void killApplicationProcess(String processName, int uid) {
6247 if (processName == null) {
6251 int callerUid = Binder.getCallingUid();
6252 // Only the system server can kill an application
6253 if (callerUid == SYSTEM_UID) {
6254 synchronized (this) {
6255 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6256 if (app != null && app.thread != null) {
6258 app.thread.scheduleSuicide();
6259 } catch (RemoteException e) {
6260 // If the other end already died, then our work here is done.
6263 Slog.w(TAG, "Process/uid not found attempting kill of "
6264 + processName + " / " + uid);
6268 throw new SecurityException(callerUid + " cannot kill app process: " +
6273 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6274 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6275 false, true, false, false, UserHandle.getUserId(uid), reason);
6278 private void finishForceStopPackageLocked(final String packageName, int uid) {
6279 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6280 Uri.fromParts("package", packageName, null));
6281 if (!mProcessesReady) {
6282 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6283 | Intent.FLAG_RECEIVER_FOREGROUND);
6285 intent.putExtra(Intent.EXTRA_UID, uid);
6286 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6287 broadcastIntentLocked(null, null, intent,
6288 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6289 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6293 private final boolean killPackageProcessesLocked(String packageName, int appId,
6294 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6295 boolean doit, boolean evenPersistent, String reason) {
6296 ArrayList<ProcessRecord> procs = new ArrayList<>();
6298 // Remove all processes this package may have touched: all with the
6299 // same UID (except for the system or root user), and all whose name
6300 // matches the package name.
6301 final int NP = mProcessNames.getMap().size();
6302 for (int ip=0; ip<NP; ip++) {
6303 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6304 final int NA = apps.size();
6305 for (int ia=0; ia<NA; ia++) {
6306 ProcessRecord app = apps.valueAt(ia);
6307 if (app.persistent && !evenPersistent) {
6308 // we don't kill persistent processes
6318 // Skip process if it doesn't meet our oom adj requirement.
6319 if (app.setAdj < minOomAdj) {
6323 // If no package is specified, we call all processes under the
6325 if (packageName == null) {
6326 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6329 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6332 // Package has been specified, we want to hit all processes
6333 // that match it. We need to qualify this by the processes
6334 // that are running under the specified app and user ID.
6336 final boolean isDep = app.pkgDeps != null
6337 && app.pkgDeps.contains(packageName);
6338 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6341 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6344 if (!app.pkgList.containsKey(packageName) && !isDep) {
6349 // Process has passed all conditions, kill it!
6358 int N = procs.size();
6359 for (int i=0; i<N; i++) {
6360 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6362 updateOomAdjLocked();
6366 private void cleanupDisabledPackageComponentsLocked(
6367 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6369 Set<String> disabledClasses = null;
6370 boolean packageDisabled = false;
6371 IPackageManager pm = AppGlobals.getPackageManager();
6373 if (changedClasses == null) {
6374 // Nothing changed...
6378 // Determine enable/disable state of the package and its components.
6379 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6380 for (int i = changedClasses.length - 1; i >= 0; i--) {
6381 final String changedClass = changedClasses[i];
6383 if (changedClass.equals(packageName)) {
6385 // Entire package setting changed
6386 enabled = pm.getApplicationEnabledSetting(packageName,
6387 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6388 } catch (Exception e) {
6389 // No such package/component; probably racing with uninstall. In any
6390 // event it means we have nothing further to do here.
6393 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6394 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6395 if (packageDisabled) {
6396 // Entire package is disabled.
6397 // No need to continue to check component states.
6398 disabledClasses = null;
6403 enabled = pm.getComponentEnabledSetting(
6404 new ComponentName(packageName, changedClass),
6405 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6406 } catch (Exception e) {
6407 // As above, probably racing with uninstall.
6410 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6411 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6412 if (disabledClasses == null) {
6413 disabledClasses = new ArraySet<>(changedClasses.length);
6415 disabledClasses.add(changedClass);
6420 if (!packageDisabled && disabledClasses == null) {
6421 // Nothing to do here...
6425 // Clean-up disabled activities.
6426 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6427 packageName, disabledClasses, true, false, userId) && mBooted) {
6428 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6429 mStackSupervisor.scheduleIdleLocked();
6432 // Clean-up disabled tasks
6433 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6435 // Clean-up disabled services.
6436 mServices.bringDownDisabledPackageServicesLocked(
6437 packageName, disabledClasses, userId, false, killProcess, true);
6439 // Clean-up disabled providers.
6440 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6441 mProviderMap.collectPackageProvidersLocked(
6442 packageName, disabledClasses, true, false, userId, providers);
6443 for (int i = providers.size() - 1; i >= 0; i--) {
6444 removeDyingProviderLocked(null, providers.get(i), true);
6447 // Clean-up disabled broadcast receivers.
6448 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6449 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6450 packageName, disabledClasses, userId, true);
6455 final boolean clearBroadcastQueueForUserLocked(int userId) {
6456 boolean didSomething = false;
6457 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6458 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6459 null, null, userId, true);
6461 return didSomething;
6464 final boolean forceStopPackageLocked(String packageName, int appId,
6465 boolean callerWillRestart, boolean purgeCache, boolean doit,
6466 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6469 if (userId == UserHandle.USER_ALL && packageName == null) {
6470 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6473 if (appId < 0 && packageName != null) {
6475 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6476 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6477 } catch (RemoteException e) {
6482 if (packageName != null) {
6483 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6484 + " user=" + userId + ": " + reason);
6486 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6489 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6492 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6493 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6494 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6496 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6498 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6499 packageName, null, doit, evenPersistent, userId)) {
6503 didSomething = true;
6506 if (mServices.bringDownDisabledPackageServicesLocked(
6507 packageName, null, userId, evenPersistent, true, doit)) {
6511 didSomething = true;
6514 if (packageName == null) {
6515 // Remove all sticky broadcasts from this user.
6516 mStickyBroadcasts.remove(userId);
6519 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6520 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6521 userId, providers)) {
6525 didSomething = true;
6527 for (i = providers.size() - 1; i >= 0; i--) {
6528 removeDyingProviderLocked(null, providers.get(i), true);
6531 // Remove transient permissions granted from/to this package/user
6532 removeUriPermissionsForPackageLocked(packageName, userId, false);
6535 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6536 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6537 packageName, null, userId, doit);
6541 if (packageName == null || uninstalling) {
6542 // Remove pending intents. For now we only do this when force
6543 // stopping users, because we have some problems when doing this
6544 // for packages -- app widgets are not currently cleaned up for
6545 // such packages, so they can be left with bad pending intents.
6546 if (mIntentSenderRecords.size() > 0) {
6547 Iterator<WeakReference<PendingIntentRecord>> it
6548 = mIntentSenderRecords.values().iterator();
6549 while (it.hasNext()) {
6550 WeakReference<PendingIntentRecord> wpir = it.next();
6555 PendingIntentRecord pir = wpir.get();
6560 if (packageName == null) {
6561 // Stopping user, remove all objects for the user.
6562 if (pir.key.userId != userId) {
6563 // Not the same user, skip it.
6567 if (UserHandle.getAppId(pir.uid) != appId) {
6568 // Different app id, skip it.
6571 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6572 // Different user, skip it.
6575 if (!pir.key.packageName.equals(packageName)) {
6576 // Different package, skip it.
6583 didSomething = true;
6585 makeIntentSenderCanceledLocked(pir);
6586 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6587 pir.key.activity.pendingResults.remove(pir.ref);
6594 if (purgeCache && packageName != null) {
6595 AttributeCache ac = AttributeCache.instance();
6597 ac.removePackage(packageName);
6601 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6602 mStackSupervisor.scheduleIdleLocked();
6606 return didSomething;
6609 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6610 return removeProcessNameLocked(name, uid, null);
6613 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6614 final ProcessRecord expecting) {
6615 ProcessRecord old = mProcessNames.get(name, uid);
6616 // Only actually remove when the currently recorded value matches the
6617 // record that we expected; if it doesn't match then we raced with a
6618 // newly created process and we don't want to destroy the new one.
6619 if ((expecting == null) || (old == expecting)) {
6620 mProcessNames.remove(name, uid);
6622 if (old != null && old.uidRecord != null) {
6623 old.uidRecord.numProcs--;
6624 if (old.uidRecord.numProcs == 0) {
6625 // No more processes using this uid, tell clients it is gone.
6626 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6627 "No more processes in " + old.uidRecord);
6628 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6629 EventLogTags.writeAmUidStopped(uid);
6630 mActiveUids.remove(uid);
6631 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6633 old.uidRecord = null;
6635 mIsolatedProcesses.remove(uid);
6639 private final void addProcessNameLocked(ProcessRecord proc) {
6640 // We shouldn't already have a process under this name, but just in case we
6641 // need to clean up whatever may be there now.
6642 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6643 if (old == proc && proc.persistent) {
6644 // We are re-adding a persistent process. Whatevs! Just leave it there.
6645 Slog.w(TAG, "Re-adding persistent process " + proc);
6646 } else if (old != null) {
6647 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6649 UidRecord uidRec = mActiveUids.get(proc.uid);
6650 if (uidRec == null) {
6651 uidRec = new UidRecord(proc.uid);
6652 // This is the first appearance of the uid, report it now!
6653 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6654 "Creating new process uid: " + uidRec);
6655 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6656 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6657 uidRec.setWhitelist = uidRec.curWhitelist = true;
6659 uidRec.updateHasInternetPermission();
6660 mActiveUids.put(proc.uid, uidRec);
6661 EventLogTags.writeAmUidRunning(uidRec.uid);
6662 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6663 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6665 proc.uidRecord = uidRec;
6667 // Reset render thread tid if it was already set, so new process can set it again.
6668 proc.renderThreadTid = 0;
6670 mProcessNames.put(proc.processName, proc.uid, proc);
6671 if (proc.isolated) {
6672 mIsolatedProcesses.put(proc.uid, proc);
6676 boolean removeProcessLocked(ProcessRecord app,
6677 boolean callerWillRestart, boolean allowRestart, String reason) {
6678 final String name = app.processName;
6679 final int uid = app.uid;
6680 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6681 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6683 ProcessRecord old = mProcessNames.get(name, uid);
6685 // This process is no longer active, so nothing to do.
6686 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6689 removeProcessNameLocked(name, uid);
6690 if (mHeavyWeightProcess == app) {
6691 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6692 mHeavyWeightProcess.userId, 0));
6693 mHeavyWeightProcess = null;
6695 boolean needRestart = false;
6696 if (app.pid > 0 && app.pid != MY_PID) {
6698 synchronized (mPidsSelfLocked) {
6699 mPidsSelfLocked.remove(pid);
6700 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6702 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6704 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6705 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6707 boolean willRestart = false;
6708 if (app.persistent && !app.isolated) {
6709 if (!callerWillRestart) {
6715 app.kill(reason, true);
6716 handleAppDiedLocked(app, willRestart, allowRestart);
6718 removeLruProcessLocked(app);
6719 addAppLocked(app.info, null, false, null /* ABI override */);
6722 mRemovedProcesses.add(app);
6728 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6729 cleanupAppInLaunchingProvidersLocked(app, true);
6730 removeProcessLocked(app, false, true, "timeout publishing content providers");
6733 private final void processStartTimedOutLocked(ProcessRecord app) {
6734 final int pid = app.pid;
6735 boolean gone = false;
6736 synchronized (mPidsSelfLocked) {
6737 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6738 if (knownApp != null && knownApp.thread == null) {
6739 mPidsSelfLocked.remove(pid);
6745 Slog.w(TAG, "Process " + app + " failed to attach");
6746 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6747 pid, app.uid, app.processName);
6748 removeProcessNameLocked(app.processName, app.uid);
6749 if (mHeavyWeightProcess == app) {
6750 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6751 mHeavyWeightProcess.userId, 0));
6752 mHeavyWeightProcess = null;
6754 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6756 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6758 // Take care of any launching providers waiting for this process.
6759 cleanupAppInLaunchingProvidersLocked(app, true);
6760 // Take care of any services that are waiting for the process.
6761 mServices.processStartTimedOutLocked(app);
6762 app.kill("start timeout", true);
6763 removeLruProcessLocked(app);
6764 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6765 Slog.w(TAG, "Unattached app died before backup, skipping");
6766 mHandler.post(new Runnable() {
6770 IBackupManager bm = IBackupManager.Stub.asInterface(
6771 ServiceManager.getService(Context.BACKUP_SERVICE));
6772 bm.agentDisconnected(app.info.packageName);
6773 } catch (RemoteException e) {
6774 // Can't happen; the backup manager is local
6779 if (isPendingBroadcastProcessLocked(pid)) {
6780 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6781 skipPendingBroadcastLocked(pid);
6784 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6788 private final boolean attachApplicationLocked(IApplicationThread thread,
6791 // Find the application record that is being attached... either via
6792 // the pid if we are running in multiple processes, or just pull the
6793 // next app record if we are emulating process with anonymous threads.
6795 long startTime = SystemClock.uptimeMillis();
6796 if (pid != MY_PID && pid >= 0) {
6797 synchronized (mPidsSelfLocked) {
6798 app = mPidsSelfLocked.get(pid);
6805 Slog.w(TAG, "No pending application record for pid " + pid
6806 + " (IApplicationThread " + thread + "); dropping process");
6807 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6808 if (pid > 0 && pid != MY_PID) {
6809 killProcessQuiet(pid);
6810 //TODO: killProcessGroup(app.info.uid, pid);
6813 thread.scheduleExit();
6814 } catch (Exception e) {
6815 // Ignore exceptions.
6821 // If this application record is still attached to a previous
6822 // process, clean it up now.
6823 if (app.thread != null) {
6824 handleAppDiedLocked(app, true, true);
6827 // Tell the process all about itself.
6829 if (DEBUG_ALL) Slog.v(
6830 TAG, "Binding process pid " + pid + " to record " + app);
6832 final String processName = app.processName;
6834 AppDeathRecipient adr = new AppDeathRecipient(
6836 thread.asBinder().linkToDeath(adr, 0);
6837 app.deathRecipient = adr;
6838 } catch (RemoteException e) {
6839 app.resetPackageList(mProcessStats);
6840 startProcessLocked(app, "link fail", processName);
6844 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6846 app.makeActive(thread, mProcessStats);
6847 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6848 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6849 app.forcingToImportant = null;
6850 updateProcessForegroundLocked(app, false, false);
6851 app.hasShownUi = false;
6852 app.debugging = false;
6854 app.killedByAm = false;
6858 // We carefully use the same state that PackageManager uses for
6859 // filtering, since we use this flag to decide if we need to install
6860 // providers when user is unlocked later
6861 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6863 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6865 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6866 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6868 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6869 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6871 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6874 checkTime(startTime, "attachApplicationLocked: before bindApplication");
6877 Slog.i(TAG, "Launching preboot mode app: " + app);
6880 if (DEBUG_ALL) Slog.v(
6881 TAG, "New app record " + app
6882 + " thread=" + thread.asBinder() + " pid=" + pid);
6884 int testMode = ApplicationThreadConstants.DEBUG_OFF;
6885 if (mDebugApp != null && mDebugApp.equals(processName)) {
6886 testMode = mWaitForDebugger
6887 ? ApplicationThreadConstants.DEBUG_WAIT
6888 : ApplicationThreadConstants.DEBUG_ON;
6889 app.debugging = true;
6890 if (mDebugTransient) {
6891 mDebugApp = mOrigDebugApp;
6892 mWaitForDebugger = mOrigWaitForDebugger;
6895 String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6896 ParcelFileDescriptor profileFd = null;
6897 int samplingInterval = 0;
6898 boolean profileAutoStop = false;
6899 boolean profileStreamingOutput = false;
6900 if (mProfileApp != null && mProfileApp.equals(processName)) {
6902 profileFile = mProfileFile;
6903 profileFd = mProfileFd;
6904 samplingInterval = mSamplingInterval;
6905 profileAutoStop = mAutoStopProfiler;
6906 profileStreamingOutput = mStreamingOutput;
6908 boolean enableTrackAllocation = false;
6909 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6910 enableTrackAllocation = true;
6911 mTrackAllocationApp = null;
6914 // If the app is being launched for restore or full backup, set it up specially
6915 boolean isRestrictedBackupMode = false;
6916 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6917 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6918 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6919 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6920 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6923 if (app.instr != null) {
6924 notifyPackageUse(app.instr.mClass.getPackageName(),
6925 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6927 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6928 + processName + " with config " + getGlobalConfiguration());
6929 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6930 app.compat = compatibilityInfoForPackageLocked(appInfo);
6931 if (profileFd != null) {
6932 profileFd = profileFd.dup();
6934 ProfilerInfo profilerInfo = profileFile == null ? null
6935 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6936 profileStreamingOutput);
6938 // We deprecated Build.SERIAL and it is not accessible to
6939 // apps that target the v2 security sandbox. Since access to
6940 // the serial is now behind a permission we push down the value.
6941 String buildSerial = Build.UNKNOWN;
6942 if (appInfo.targetSandboxVersion != 2) {
6943 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6944 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6948 // Check if this is a secondary process that should be incorporated into some
6949 // currently active instrumentation. (Note we do this AFTER all of the profiling
6950 // stuff above because profiling can currently happen only in the primary
6951 // instrumentation process.)
6952 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6953 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6954 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6955 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6956 if (aInstr.mTargetProcesses.length == 0) {
6957 // This is the wildcard mode, where every process brought up for
6958 // the target instrumentation should be included.
6959 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6961 aInstr.mRunningProcesses.add(app);
6964 for (String proc : aInstr.mTargetProcesses) {
6965 if (proc.equals(app.processName)) {
6967 aInstr.mRunningProcesses.add(app);
6976 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6977 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6978 if (app.instr != null) {
6979 thread.bindApplication(processName, appInfo, providers,
6981 profilerInfo, app.instr.mArguments,
6983 app.instr.mUiAutomationConnection, testMode,
6984 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6985 isRestrictedBackupMode || !normalMode, app.persistent,
6986 new Configuration(getGlobalConfiguration()), app.compat,
6987 getCommonServicesLocked(app.isolated),
6988 mCoreSettingsObserver.getCoreSettingsLocked(),
6991 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6992 null, null, null, testMode,
6993 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6994 isRestrictedBackupMode || !normalMode, app.persistent,
6995 new Configuration(getGlobalConfiguration()), app.compat,
6996 getCommonServicesLocked(app.isolated),
6997 mCoreSettingsObserver.getCoreSettingsLocked(),
7001 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7002 updateLruProcessLocked(app, false, null);
7003 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7004 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7005 } catch (Exception e) {
7006 // todo: Yikes! What should we do? For now we will try to
7007 // start another process, but that could easily get us in
7008 // an infinite loop of restarting processes...
7009 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7011 app.resetPackageList(mProcessStats);
7012 app.unlinkDeathRecipient();
7013 startProcessLocked(app, "bind fail", processName);
7017 // Remove this record from the list of starting applications.
7018 mPersistentStartingProcesses.remove(app);
7019 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7020 "Attach application locked removing on hold: " + app);
7021 mProcessesOnHold.remove(app);
7023 boolean badApp = false;
7024 boolean didSomething = false;
7026 // See if the top visible activity is waiting to run in this process...
7029 if (mStackSupervisor.attachApplicationLocked(app)) {
7030 didSomething = true;
7032 } catch (Exception e) {
7033 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7038 // Find any services that should be running in this process...
7041 didSomething |= mServices.attachApplicationLocked(app, processName);
7042 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7043 } catch (Exception e) {
7044 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7049 // Check if a next-broadcast receiver is in this process...
7050 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7052 didSomething |= sendPendingBroadcastsLocked(app);
7053 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7054 } catch (Exception e) {
7055 // If the app died trying to launch the receiver we declare it 'bad'
7056 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7061 // Check whether the next backup agent is in this process...
7062 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7063 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7064 "New app is backup target, launching agent for " + app);
7065 notifyPackageUse(mBackupTarget.appInfo.packageName,
7066 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7068 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7069 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7070 mBackupTarget.backupMode);
7071 } catch (Exception e) {
7072 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7078 app.kill("error during init", true);
7079 handleAppDiedLocked(app, false, true);
7083 if (!didSomething) {
7084 updateOomAdjLocked();
7085 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7092 public final void attachApplication(IApplicationThread thread) {
7093 synchronized (this) {
7094 int callingPid = Binder.getCallingPid();
7095 final long origId = Binder.clearCallingIdentity();
7096 attachApplicationLocked(thread, callingPid);
7097 Binder.restoreCallingIdentity(origId);
7102 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7103 final long origId = Binder.clearCallingIdentity();
7104 synchronized (this) {
7105 ActivityStack stack = ActivityRecord.getStackLocked(token);
7106 if (stack != null) {
7108 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7109 false /* processPausingActivities */, config);
7110 if (stopProfiling) {
7111 if ((mProfileProc == r.app) && (mProfileFd != null)) {
7114 } catch (IOException e) {
7116 clearProfilerLocked();
7121 Binder.restoreCallingIdentity(origId);
7124 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7125 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7126 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7129 void enableScreenAfterBoot() {
7130 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7131 SystemClock.uptimeMillis());
7132 mWindowManager.enableScreenAfterBoot();
7134 synchronized (this) {
7135 updateEventDispatchingLocked();
7140 public void showBootMessage(final CharSequence msg, final boolean always) {
7141 if (Binder.getCallingUid() != myUid()) {
7142 throw new SecurityException();
7144 mWindowManager.showBootMessage(msg, always);
7148 public void keyguardGoingAway(int flags) {
7149 enforceNotIsolatedCaller("keyguardGoingAway");
7150 final long token = Binder.clearCallingIdentity();
7152 synchronized (this) {
7153 mKeyguardController.keyguardGoingAway(flags);
7156 Binder.restoreCallingIdentity(token);
7161 * @return whther the keyguard is currently locked.
7163 boolean isKeyguardLocked() {
7164 return mKeyguardController.isKeyguardLocked();
7167 final void finishBooting() {
7168 synchronized (this) {
7169 if (!mBootAnimationComplete) {
7170 mCallFinishBooting = true;
7173 mCallFinishBooting = false;
7176 ArraySet<String> completedIsas = new ArraySet<String>();
7177 for (String abi : Build.SUPPORTED_ABIS) {
7178 zygoteProcess.establishZygoteConnectionForAbi(abi);
7179 final String instructionSet = VMRuntime.getInstructionSet(abi);
7180 if (!completedIsas.contains(instructionSet)) {
7182 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7183 } catch (InstallerException e) {
7184 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7185 e.getMessage() +")");
7187 completedIsas.add(instructionSet);
7191 IntentFilter pkgFilter = new IntentFilter();
7192 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7193 pkgFilter.addDataScheme("package");
7194 mContext.registerReceiver(new BroadcastReceiver() {
7196 public void onReceive(Context context, Intent intent) {
7197 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7199 for (String pkg : pkgs) {
7200 synchronized (ActivityManagerService.this) {
7201 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7202 0, "query restart")) {
7203 setResultCode(Activity.RESULT_OK);
7212 IntentFilter dumpheapFilter = new IntentFilter();
7213 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7214 mContext.registerReceiver(new BroadcastReceiver() {
7216 public void onReceive(Context context, Intent intent) {
7217 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7218 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7220 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7225 // Let system services know.
7226 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7228 synchronized (this) {
7229 // Ensure that any processes we had put on hold are now started
7231 final int NP = mProcessesOnHold.size();
7233 ArrayList<ProcessRecord> procs =
7234 new ArrayList<ProcessRecord>(mProcessesOnHold);
7235 for (int ip=0; ip<NP; ip++) {
7236 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7238 startProcessLocked(procs.get(ip), "on-hold", null);
7242 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7243 // Start looking for apps that are abusing wake locks.
7244 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7245 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7246 // Tell anyone interested that we are done booting!
7247 SystemProperties.set("sys.boot_completed", "1");
7249 // And trigger dev.bootcomplete if we are not showing encryption progress
7250 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7251 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7252 SystemProperties.set("dev.bootcomplete", "1");
7254 mUserController.sendBootCompletedLocked(
7255 new IIntentReceiver.Stub() {
7257 public void performReceive(Intent intent, int resultCode,
7258 String data, Bundle extras, boolean ordered,
7259 boolean sticky, int sendingUser) {
7260 synchronized (ActivityManagerService.this) {
7261 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7266 scheduleStartProfilesLocked();
7272 public void bootAnimationComplete() {
7273 final boolean callFinishBooting;
7274 synchronized (this) {
7275 callFinishBooting = mCallFinishBooting;
7276 mBootAnimationComplete = true;
7278 if (callFinishBooting) {
7279 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7281 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7285 final void ensureBootCompleted() {
7287 boolean enableScreen;
7288 synchronized (this) {
7291 enableScreen = !mBooted;
7296 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7298 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7302 enableScreenAfterBoot();
7307 public final void activityResumed(IBinder token) {
7308 final long origId = Binder.clearCallingIdentity();
7309 synchronized(this) {
7310 ActivityRecord.activityResumedLocked(token);
7311 mWindowManager.notifyAppResumedFinished(token);
7313 Binder.restoreCallingIdentity(origId);
7317 public final void activityPaused(IBinder token) {
7318 final long origId = Binder.clearCallingIdentity();
7319 synchronized(this) {
7320 ActivityStack stack = ActivityRecord.getStackLocked(token);
7321 if (stack != null) {
7322 stack.activityPausedLocked(token, false);
7325 Binder.restoreCallingIdentity(origId);
7329 public final void activityStopped(IBinder token, Bundle icicle,
7330 PersistableBundle persistentState, CharSequence description) {
7331 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7333 // Refuse possible leaked file descriptors
7334 if (icicle != null && icicle.hasFileDescriptors()) {
7335 throw new IllegalArgumentException("File descriptors passed in Bundle");
7338 final long origId = Binder.clearCallingIdentity();
7340 synchronized (this) {
7341 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7343 r.activityStoppedLocked(icicle, persistentState, description);
7349 Binder.restoreCallingIdentity(origId);
7353 public final void activityDestroyed(IBinder token) {
7354 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7355 synchronized (this) {
7356 ActivityStack stack = ActivityRecord.getStackLocked(token);
7357 if (stack != null) {
7358 stack.activityDestroyedLocked(token, "activityDestroyed");
7364 public final void activityRelaunched(IBinder token) {
7365 final long origId = Binder.clearCallingIdentity();
7366 synchronized (this) {
7367 mStackSupervisor.activityRelaunchedLocked(token);
7369 Binder.restoreCallingIdentity(origId);
7373 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7374 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7375 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7376 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7377 synchronized (this) {
7378 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7379 if (record == null) {
7380 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7381 + "found for: " + token);
7383 record.setSizeConfigurations(horizontalSizeConfiguration,
7384 verticalSizeConfigurations, smallestSizeConfigurations);
7389 public final void backgroundResourcesReleased(IBinder token) {
7390 final long origId = Binder.clearCallingIdentity();
7392 synchronized (this) {
7393 ActivityStack stack = ActivityRecord.getStackLocked(token);
7394 if (stack != null) {
7395 stack.backgroundResourcesReleased();
7399 Binder.restoreCallingIdentity(origId);
7404 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7405 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7409 public final void notifyEnterAnimationComplete(IBinder token) {
7410 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7414 public String getCallingPackage(IBinder token) {
7415 synchronized (this) {
7416 ActivityRecord r = getCallingRecordLocked(token);
7417 return r != null ? r.info.packageName : null;
7422 public ComponentName getCallingActivity(IBinder token) {
7423 synchronized (this) {
7424 ActivityRecord r = getCallingRecordLocked(token);
7425 return r != null ? r.intent.getComponent() : null;
7429 private ActivityRecord getCallingRecordLocked(IBinder token) {
7430 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7438 public ComponentName getActivityClassForToken(IBinder token) {
7439 synchronized(this) {
7440 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7444 return r.intent.getComponent();
7449 public String getPackageForToken(IBinder token) {
7450 synchronized(this) {
7451 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7455 return r.packageName;
7460 public boolean isRootVoiceInteraction(IBinder token) {
7461 synchronized(this) {
7462 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7466 return r.rootVoiceInteraction;
7471 public IIntentSender getIntentSender(int type,
7472 String packageName, IBinder token, String resultWho,
7473 int requestCode, Intent[] intents, String[] resolvedTypes,
7474 int flags, Bundle bOptions, int userId) {
7475 enforceNotIsolatedCaller("getIntentSender");
7476 // Refuse possible leaked file descriptors
7477 if (intents != null) {
7478 if (intents.length < 1) {
7479 throw new IllegalArgumentException("Intents array length must be >= 1");
7481 for (int i=0; i<intents.length; i++) {
7482 Intent intent = intents[i];
7483 if (intent != null) {
7484 if (intent.hasFileDescriptors()) {
7485 throw new IllegalArgumentException("File descriptors passed in Intent");
7487 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7488 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7489 throw new IllegalArgumentException(
7490 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7492 intents[i] = new Intent(intent);
7495 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7496 throw new IllegalArgumentException(
7497 "Intent array length does not match resolvedTypes length");
7500 if (bOptions != null) {
7501 if (bOptions.hasFileDescriptors()) {
7502 throw new IllegalArgumentException("File descriptors passed in options");
7506 synchronized(this) {
7507 int callingUid = Binder.getCallingUid();
7508 int origUserId = userId;
7509 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7510 type == ActivityManager.INTENT_SENDER_BROADCAST,
7511 ALLOW_NON_FULL, "getIntentSender", null);
7512 if (origUserId == UserHandle.USER_CURRENT) {
7513 // We don't want to evaluate this until the pending intent is
7514 // actually executed. However, we do want to always do the
7515 // security checking for it above.
7516 userId = UserHandle.USER_CURRENT;
7519 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7520 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7521 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7522 if (!UserHandle.isSameApp(callingUid, uid)) {
7523 String msg = "Permission Denial: getIntentSender() from pid="
7524 + Binder.getCallingPid()
7525 + ", uid=" + Binder.getCallingUid()
7526 + ", (need uid=" + uid + ")"
7527 + " is not allowed to send as package " + packageName;
7529 throw new SecurityException(msg);
7533 return getIntentSenderLocked(type, packageName, callingUid, userId,
7534 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7536 } catch (RemoteException e) {
7537 throw new SecurityException(e);
7542 IIntentSender getIntentSenderLocked(int type, String packageName,
7543 int callingUid, int userId, IBinder token, String resultWho,
7544 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7546 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7547 ActivityRecord activity = null;
7548 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7549 activity = ActivityRecord.isInStackLocked(token);
7550 if (activity == null) {
7551 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7554 if (activity.finishing) {
7555 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7560 // We're going to be splicing together extras before sending, so we're
7561 // okay poking into any contained extras.
7562 if (intents != null) {
7563 for (int i = 0; i < intents.length; i++) {
7564 intents[i].setDefusable(true);
7567 Bundle.setDefusable(bOptions, true);
7569 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7570 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7571 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7572 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7573 |PendingIntent.FLAG_UPDATE_CURRENT);
7575 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7576 type, packageName, activity, resultWho,
7577 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7578 WeakReference<PendingIntentRecord> ref;
7579 ref = mIntentSenderRecords.get(key);
7580 PendingIntentRecord rec = ref != null ? ref.get() : null;
7582 if (!cancelCurrent) {
7583 if (updateCurrent) {
7584 if (rec.key.requestIntent != null) {
7585 rec.key.requestIntent.replaceExtras(intents != null ?
7586 intents[intents.length - 1] : null);
7588 if (intents != null) {
7589 intents[intents.length-1] = rec.key.requestIntent;
7590 rec.key.allIntents = intents;
7591 rec.key.allResolvedTypes = resolvedTypes;
7593 rec.key.allIntents = null;
7594 rec.key.allResolvedTypes = null;
7599 makeIntentSenderCanceledLocked(rec);
7600 mIntentSenderRecords.remove(key);
7605 rec = new PendingIntentRecord(this, key, callingUid);
7606 mIntentSenderRecords.put(key, rec.ref);
7607 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7608 if (activity.pendingResults == null) {
7609 activity.pendingResults
7610 = new HashSet<WeakReference<PendingIntentRecord>>();
7612 activity.pendingResults.add(rec.ref);
7618 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7619 Intent intent, String resolvedType,
7620 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7621 if (target instanceof PendingIntentRecord) {
7622 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7623 whitelistToken, finishedReceiver, requiredPermission, options);
7625 if (intent == null) {
7626 // Weird case: someone has given us their own custom IIntentSender, and now
7627 // they have someone else trying to send to it but of course this isn't
7628 // really a PendingIntent, so there is no base Intent, and the caller isn't
7629 // supplying an Intent... but we never want to dispatch a null Intent to
7630 // a receiver, so um... let's make something up.
7631 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7632 intent = new Intent(Intent.ACTION_MAIN);
7635 target.send(code, intent, resolvedType, whitelistToken, null,
7636 requiredPermission, options);
7637 } catch (RemoteException e) {
7639 // Platform code can rely on getting a result back when the send is done, but if
7640 // this intent sender is from outside of the system we can't rely on it doing that.
7641 // So instead we don't give it the result receiver, and instead just directly
7642 // report the finish immediately.
7643 if (finishedReceiver != null) {
7645 finishedReceiver.performReceive(intent, 0,
7646 null, null, false, false, UserHandle.getCallingUserId());
7647 } catch (RemoteException e) {
7655 public void cancelIntentSender(IIntentSender sender) {
7656 if (!(sender instanceof PendingIntentRecord)) {
7659 synchronized(this) {
7660 PendingIntentRecord rec = (PendingIntentRecord)sender;
7662 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7663 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7664 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7665 String msg = "Permission Denial: cancelIntentSender() from pid="
7666 + Binder.getCallingPid()
7667 + ", uid=" + Binder.getCallingUid()
7668 + " is not allowed to cancel package "
7669 + rec.key.packageName;
7671 throw new SecurityException(msg);
7673 } catch (RemoteException e) {
7674 throw new SecurityException(e);
7676 cancelIntentSenderLocked(rec, true);
7680 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7681 makeIntentSenderCanceledLocked(rec);
7682 mIntentSenderRecords.remove(rec.key);
7683 if (cleanActivity && rec.key.activity != null) {
7684 rec.key.activity.pendingResults.remove(rec.ref);
7688 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7689 rec.canceled = true;
7690 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7691 if (callbacks != null) {
7692 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7697 public String getPackageForIntentSender(IIntentSender pendingResult) {
7698 if (!(pendingResult instanceof PendingIntentRecord)) {
7702 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7703 return res.key.packageName;
7704 } catch (ClassCastException e) {
7710 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7711 if (!(sender instanceof PendingIntentRecord)) {
7714 synchronized(this) {
7715 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7720 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7721 IResultReceiver receiver) {
7722 if (!(sender instanceof PendingIntentRecord)) {
7725 synchronized(this) {
7726 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7731 public int getUidForIntentSender(IIntentSender sender) {
7732 if (sender instanceof PendingIntentRecord) {
7734 PendingIntentRecord res = (PendingIntentRecord)sender;
7736 } catch (ClassCastException e) {
7743 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7744 if (!(pendingResult instanceof PendingIntentRecord)) {
7748 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7749 if (res.key.allIntents == null) {
7752 for (int i=0; i<res.key.allIntents.length; i++) {
7753 Intent intent = res.key.allIntents[i];
7754 if (intent.getPackage() != null && intent.getComponent() != null) {
7759 } catch (ClassCastException e) {
7765 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7766 if (!(pendingResult instanceof PendingIntentRecord)) {
7770 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7771 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7775 } catch (ClassCastException e) {
7781 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7782 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7783 "getIntentForIntentSender()");
7784 if (!(pendingResult instanceof PendingIntentRecord)) {
7788 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7789 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7790 } catch (ClassCastException e) {
7796 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7797 if (!(pendingResult instanceof PendingIntentRecord)) {
7801 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7802 synchronized (this) {
7803 return getTagForIntentSenderLocked(res, prefix);
7805 } catch (ClassCastException e) {
7810 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7811 final Intent intent = res.key.requestIntent;
7812 if (intent != null) {
7813 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7814 || res.lastTagPrefix.equals(prefix))) {
7817 res.lastTagPrefix = prefix;
7818 final StringBuilder sb = new StringBuilder(128);
7819 if (prefix != null) {
7822 if (intent.getAction() != null) {
7823 sb.append(intent.getAction());
7824 } else if (intent.getComponent() != null) {
7825 intent.getComponent().appendShortString(sb);
7829 return res.lastTag = sb.toString();
7835 public void setProcessLimit(int max) {
7836 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7837 "setProcessLimit()");
7838 synchronized (this) {
7839 mConstants.setOverrideMaxCachedProcesses(max);
7845 public int getProcessLimit() {
7846 synchronized (this) {
7847 return mConstants.getOverrideMaxCachedProcesses();
7851 void importanceTokenDied(ImportanceToken token) {
7852 synchronized (ActivityManagerService.this) {
7853 synchronized (mPidsSelfLocked) {
7855 = mImportantProcesses.get(token.pid);
7859 mImportantProcesses.remove(token.pid);
7860 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7864 pr.forcingToImportant = null;
7865 updateProcessForegroundLocked(pr, false, false);
7867 updateOomAdjLocked();
7872 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7873 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7874 "setProcessImportant()");
7875 synchronized(this) {
7876 boolean changed = false;
7878 synchronized (mPidsSelfLocked) {
7879 ProcessRecord pr = mPidsSelfLocked.get(pid);
7880 if (pr == null && isForeground) {
7881 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7884 ImportanceToken oldToken = mImportantProcesses.get(pid);
7885 if (oldToken != null) {
7886 oldToken.token.unlinkToDeath(oldToken, 0);
7887 mImportantProcesses.remove(pid);
7889 pr.forcingToImportant = null;
7893 if (isForeground && token != null) {
7894 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7896 public void binderDied() {
7897 importanceTokenDied(this);
7901 token.linkToDeath(newToken, 0);
7902 mImportantProcesses.put(pid, newToken);
7903 pr.forcingToImportant = newToken;
7905 } catch (RemoteException e) {
7906 // If the process died while doing this, we will later
7907 // do the cleanup with the process death link.
7913 updateOomAdjLocked();
7919 public boolean isAppForeground(int uid) throws RemoteException {
7920 int callerUid = Binder.getCallingUid();
7921 if (UserHandle.isCore(callerUid) || callerUid == uid) {
7922 return isAppForegroundInternal(uid);
7927 private boolean isAppForegroundInternal(int uid) {
7928 synchronized (this) {
7929 UidRecord uidRec = mActiveUids.get(uid);
7930 if (uidRec == null || uidRec.idle) {
7933 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7937 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7938 // be guarded by permission checking.
7939 int getUidState(int uid) {
7940 synchronized (this) {
7941 return getUidStateLocked(uid);
7945 int getUidStateLocked(int uid) {
7946 UidRecord uidRec = mActiveUids.get(uid);
7947 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7951 public boolean isInMultiWindowMode(IBinder token) {
7952 final long origId = Binder.clearCallingIdentity();
7954 synchronized(this) {
7955 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7959 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7960 return !r.getTask().mFullscreen;
7963 Binder.restoreCallingIdentity(origId);
7968 public boolean isInPictureInPictureMode(IBinder token) {
7969 final long origId = Binder.clearCallingIdentity();
7971 synchronized(this) {
7972 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7975 Binder.restoreCallingIdentity(origId);
7979 private boolean isInPictureInPictureMode(ActivityRecord r) {
7980 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7981 r.getStack().isInStackLocked(r) == null) {
7985 // If we are animating to fullscreen then we have already dispatched the PIP mode
7986 // changed, so we should reflect that check here as well.
7987 final PinnedActivityStack stack = r.getStack();
7988 final PinnedStackWindowController windowController = stack.getWindowContainerController();
7989 return !windowController.isAnimatingBoundsToFullscreen();
7993 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7994 final long origId = Binder.clearCallingIdentity();
7996 synchronized(this) {
7997 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7998 "enterPictureInPictureMode", token, params);
8000 // If the activity is already in picture in picture mode, then just return early
8001 if (isInPictureInPictureMode(r)) {
8005 // Activity supports picture-in-picture, now check that we can enter PiP at this
8007 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8008 false /* noThrow */, false /* beforeStopping */)) {
8012 final Runnable enterPipRunnable = () -> {
8013 // Only update the saved args from the args that are set
8014 r.pictureInPictureArgs.copyOnlySet(params);
8015 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8016 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8017 // Adjust the source bounds by the insets for the transition down
8018 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8019 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8020 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8021 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8022 stack.setPictureInPictureAspectRatio(aspectRatio);
8023 stack.setPictureInPictureActions(actions);
8025 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8026 r.supportsPictureInPictureWhilePausing);
8027 logPictureInPictureArgs(params);
8030 if (isKeyguardLocked()) {
8031 // If the keyguard is showing or occluded, then try and dismiss it before
8032 // entering picture-in-picture (this will prompt the user to authenticate if the
8033 // device is currently locked).
8035 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8037 public void onDismissError() throws RemoteException {
8042 public void onDismissSucceeded() throws RemoteException {
8043 mHandler.post(enterPipRunnable);
8047 public void onDismissCancelled() throws RemoteException {
8051 } catch (RemoteException e) {
8055 // Enter picture in picture immediately otherwise
8056 enterPipRunnable.run();
8061 Binder.restoreCallingIdentity(origId);
8066 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8067 final long origId = Binder.clearCallingIdentity();
8069 synchronized(this) {
8070 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8071 "setPictureInPictureParams", token, params);
8073 // Only update the saved args from the args that are set
8074 r.pictureInPictureArgs.copyOnlySet(params);
8075 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8076 // If the activity is already in picture-in-picture, update the pinned stack now
8077 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8078 // be used the next time the activity enters PiP
8079 final PinnedActivityStack stack = r.getStack();
8080 if (!stack.isAnimatingBoundsToFullscreen()) {
8081 stack.setPictureInPictureAspectRatio(
8082 r.pictureInPictureArgs.getAspectRatio());
8083 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8086 logPictureInPictureArgs(params);
8089 Binder.restoreCallingIdentity(origId);
8094 public int getMaxNumPictureInPictureActions(IBinder token) {
8095 // Currently, this is a static constant, but later, we may change this to be dependent on
8096 // the context of the activity
8100 private void logPictureInPictureArgs(PictureInPictureParams params) {
8101 if (params.hasSetActions()) {
8102 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8103 params.getActions().size());
8105 if (params.hasSetAspectRatio()) {
8106 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8107 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8108 MetricsLogger.action(lm);
8113 * Checks the state of the system and the activity associated with the given {@param token} to
8114 * verify that picture-in-picture is supported for that activity.
8116 * @return the activity record for the given {@param token} if all the checks pass.
8118 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8119 IBinder token, PictureInPictureParams params) {
8120 if (!mSupportsPictureInPicture) {
8121 throw new IllegalStateException(caller
8122 + ": Device doesn't support picture-in-picture mode.");
8125 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8127 throw new IllegalStateException(caller
8128 + ": Can't find activity for token=" + token);
8131 if (!r.supportsPictureInPicture()) {
8132 throw new IllegalStateException(caller
8133 + ": Current activity does not support picture-in-picture.");
8136 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8137 throw new IllegalStateException(caller
8138 + ": Activities on the home, assistant, or recents stack not supported");
8141 if (params.hasSetAspectRatio()
8142 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8143 params.getAspectRatio())) {
8144 final float minAspectRatio = mContext.getResources().getFloat(
8145 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8146 final float maxAspectRatio = mContext.getResources().getFloat(
8147 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8148 throw new IllegalArgumentException(String.format(caller
8149 + ": Aspect ratio is too extreme (must be between %f and %f).",
8150 minAspectRatio, maxAspectRatio));
8153 // Truncate the number of actions if necessary
8154 params.truncateActions(getMaxNumPictureInPictureActions(token));
8159 // =========================================================
8161 // =========================================================
8163 static class ProcessInfoService extends IProcessInfoService.Stub {
8164 final ActivityManagerService mActivityManagerService;
8165 ProcessInfoService(ActivityManagerService activityManagerService) {
8166 mActivityManagerService = activityManagerService;
8170 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8171 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8172 /*in*/ pids, /*out*/ states, null);
8176 public void getProcessStatesAndOomScoresFromPids(
8177 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8178 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8179 /*in*/ pids, /*out*/ states, /*out*/ scores);
8184 * For each PID in the given input array, write the current process state
8185 * for that process into the states array, or -1 to indicate that no
8186 * process with the given PID exists. If scores array is provided, write
8187 * the oom score for the process into the scores array, with INVALID_ADJ
8188 * indicating the PID doesn't exist.
8190 public void getProcessStatesAndOomScoresForPIDs(
8191 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8192 if (scores != null) {
8193 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8194 "getProcessStatesAndOomScoresForPIDs()");
8198 throw new NullPointerException("pids");
8199 } else if (states == null) {
8200 throw new NullPointerException("states");
8201 } else if (pids.length != states.length) {
8202 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8203 } else if (scores != null && pids.length != scores.length) {
8204 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8207 synchronized (mPidsSelfLocked) {
8208 for (int i = 0; i < pids.length; i++) {
8209 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8210 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8212 if (scores != null) {
8213 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8219 // =========================================================
8221 // =========================================================
8223 static class PermissionController extends IPermissionController.Stub {
8224 ActivityManagerService mActivityManagerService;
8225 PermissionController(ActivityManagerService activityManagerService) {
8226 mActivityManagerService = activityManagerService;
8230 public boolean checkPermission(String permission, int pid, int uid) {
8231 return mActivityManagerService.checkPermission(permission, pid,
8232 uid) == PackageManager.PERMISSION_GRANTED;
8236 public String[] getPackagesForUid(int uid) {
8237 return mActivityManagerService.mContext.getPackageManager()
8238 .getPackagesForUid(uid);
8242 public boolean isRuntimePermission(String permission) {
8244 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8245 .getPermissionInfo(permission, 0);
8246 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8247 == PermissionInfo.PROTECTION_DANGEROUS;
8248 } catch (NameNotFoundException nnfe) {
8249 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8255 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8257 public int checkComponentPermission(String permission, int pid, int uid,
8258 int owningUid, boolean exported) {
8259 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8260 owningUid, exported);
8264 public Object getAMSLock() {
8265 return ActivityManagerService.this;
8270 * This can be called with or without the global lock held.
8272 int checkComponentPermission(String permission, int pid, int uid,
8273 int owningUid, boolean exported) {
8274 if (pid == MY_PID) {
8275 return PackageManager.PERMISSION_GRANTED;
8277 return ActivityManager.checkComponentPermission(permission, uid,
8278 owningUid, exported);
8282 * As the only public entry point for permissions checking, this method
8283 * can enforce the semantic that requesting a check on a null global
8284 * permission is automatically denied. (Internally a null permission
8285 * string is used when calling {@link #checkComponentPermission} in cases
8286 * when only uid-based security is needed.)
8288 * This can be called with or without the global lock held.
8291 public int checkPermission(String permission, int pid, int uid) {
8292 if (permission == null) {
8293 return PackageManager.PERMISSION_DENIED;
8295 return checkComponentPermission(permission, pid, uid, -1, true);
8299 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8300 if (permission == null) {
8301 return PackageManager.PERMISSION_DENIED;
8304 // We might be performing an operation on behalf of an indirect binder
8305 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8306 // client identity accordingly before proceeding.
8307 Identity tlsIdentity = sCallerIdentity.get();
8308 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8309 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8310 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8311 uid = tlsIdentity.uid;
8312 pid = tlsIdentity.pid;
8315 return checkComponentPermission(permission, pid, uid, -1, true);
8319 * Binder IPC calls go through the public entry point.
8320 * This can be called with or without the global lock held.
8322 int checkCallingPermission(String permission) {
8323 return checkPermission(permission,
8324 Binder.getCallingPid(),
8325 UserHandle.getAppId(Binder.getCallingUid()));
8329 * This can be called with or without the global lock held.
8331 void enforceCallingPermission(String permission, String func) {
8332 if (checkCallingPermission(permission)
8333 == PackageManager.PERMISSION_GRANTED) {
8337 String msg = "Permission Denial: " + func + " from pid="
8338 + Binder.getCallingPid()
8339 + ", uid=" + Binder.getCallingUid()
8340 + " requires " + permission;
8342 throw new SecurityException(msg);
8346 * Determine if UID is holding permissions required to access {@link Uri} in
8347 * the given {@link ProviderInfo}. Final permission checking is always done
8348 * in {@link ContentProvider}.
8350 private final boolean checkHoldingPermissionsLocked(
8351 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8352 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8353 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8354 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8355 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8356 != PERMISSION_GRANTED) {
8360 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8363 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8364 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8365 if (pi.applicationInfo.uid == uid) {
8367 } else if (!pi.exported) {
8371 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8372 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8374 // check if target holds top-level <provider> permissions
8375 if (!readMet && pi.readPermission != null && considerUidPermissions
8376 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8379 if (!writeMet && pi.writePermission != null && considerUidPermissions
8380 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8384 // track if unprotected read/write is allowed; any denied
8385 // <path-permission> below removes this ability
8386 boolean allowDefaultRead = pi.readPermission == null;
8387 boolean allowDefaultWrite = pi.writePermission == null;
8389 // check if target holds any <path-permission> that match uri
8390 final PathPermission[] pps = pi.pathPermissions;
8392 final String path = grantUri.uri.getPath();
8394 while (i > 0 && (!readMet || !writeMet)) {
8396 PathPermission pp = pps[i];
8397 if (pp.match(path)) {
8399 final String pprperm = pp.getReadPermission();
8400 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8401 "Checking read perm for " + pprperm + " for " + pp.getPath()
8402 + ": match=" + pp.match(path)
8403 + " check=" + pm.checkUidPermission(pprperm, uid));
8404 if (pprperm != null) {
8405 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8406 == PERMISSION_GRANTED) {
8409 allowDefaultRead = false;
8414 final String ppwperm = pp.getWritePermission();
8415 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8416 "Checking write perm " + ppwperm + " for " + pp.getPath()
8417 + ": match=" + pp.match(path)
8418 + " check=" + pm.checkUidPermission(ppwperm, uid));
8419 if (ppwperm != null) {
8420 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8421 == PERMISSION_GRANTED) {
8424 allowDefaultWrite = false;
8432 // grant unprotected <provider> read/write, if not blocked by
8433 // <path-permission> above
8434 if (allowDefaultRead) readMet = true;
8435 if (allowDefaultWrite) writeMet = true;
8437 } catch (RemoteException e) {
8441 return readMet && writeMet;
8444 public boolean isAppStartModeDisabled(int uid, String packageName) {
8445 synchronized (this) {
8446 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8447 == ActivityManager.APP_START_MODE_DISABLED;
8451 // Unified app-op and target sdk check
8452 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8453 // Apps that target O+ are always subject to background check
8454 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8455 if (DEBUG_BACKGROUND_CHECK) {
8456 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8458 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8460 // ...and legacy apps get an AppOp check
8461 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8463 if (DEBUG_BACKGROUND_CHECK) {
8464 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8467 case AppOpsManager.MODE_ALLOWED:
8468 return ActivityManager.APP_START_MODE_NORMAL;
8469 case AppOpsManager.MODE_IGNORED:
8470 return ActivityManager.APP_START_MODE_DELAYED;
8472 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8476 // Service launch is available to apps with run-in-background exemptions but
8477 // some other background operations are not. If we're doing a check
8478 // of service-launch policy, allow those callers to proceed unrestricted.
8479 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8481 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8482 if (DEBUG_BACKGROUND_CHECK) {
8483 Slog.i(TAG, "App " + uid + "/" + packageName
8484 + " is persistent; not restricted in background");
8486 return ActivityManager.APP_START_MODE_NORMAL;
8489 // Non-persistent but background whitelisted?
8490 if (uidOnBackgroundWhitelist(uid)) {
8491 if (DEBUG_BACKGROUND_CHECK) {
8492 Slog.i(TAG, "App " + uid + "/" + packageName
8493 + " on background whitelist; not restricted in background");
8495 return ActivityManager.APP_START_MODE_NORMAL;
8498 // Is this app on the battery whitelist?
8499 if (isOnDeviceIdleWhitelistLocked(uid)) {
8500 if (DEBUG_BACKGROUND_CHECK) {
8501 Slog.i(TAG, "App " + uid + "/" + packageName
8502 + " on idle whitelist; not restricted in background");
8504 return ActivityManager.APP_START_MODE_NORMAL;
8507 // None of the service-policy criteria apply, so we apply the common criteria
8508 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8511 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8512 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8513 UidRecord uidRec = mActiveUids.get(uid);
8514 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8515 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8516 + (uidRec != null ? uidRec.idle : false));
8517 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8519 if (uidRec == null) {
8520 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8521 UserHandle.getUserId(uid), packageName);
8523 ephemeral = uidRec.ephemeral;
8527 // We are hard-core about ephemeral apps not running in the background.
8528 return ActivityManager.APP_START_MODE_DISABLED;
8531 // The caller is only interested in whether app starts are completely
8532 // disabled for the given package (that is, it is an instant app). So
8533 // we don't need to go further, which is all just seeing if we should
8534 // apply a "delayed" mode for a regular app.
8535 return ActivityManager.APP_START_MODE_NORMAL;
8537 final int startMode = (alwaysRestrict)
8538 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8539 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8541 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8542 + " pkg=" + packageName + " startMode=" + startMode
8543 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8544 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8545 // This is an old app that has been forced into a "compatible as possible"
8546 // mode of background check. To increase compatibility, we will allow other
8547 // foreground apps to cause its services to start.
8548 if (callingPid >= 0) {
8550 synchronized (mPidsSelfLocked) {
8551 proc = mPidsSelfLocked.get(callingPid);
8554 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8555 // Whoever is instigating this is in the foreground, so we will allow it
8557 return ActivityManager.APP_START_MODE_NORMAL;
8564 return ActivityManager.APP_START_MODE_NORMAL;
8567 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8568 final int appId = UserHandle.getAppId(uid);
8569 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8570 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8571 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8574 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8575 ProviderInfo pi = null;
8576 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8581 pi = AppGlobals.getPackageManager().resolveContentProvider(
8582 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8584 } catch (RemoteException ex) {
8590 void grantEphemeralAccessLocked(int userId, Intent intent,
8591 int targetAppId, int ephemeralAppId) {
8592 getPackageManagerInternalLocked().
8593 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8596 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8597 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8598 if (targetUris != null) {
8599 return targetUris.get(grantUri);
8604 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8605 String targetPkg, int targetUid, GrantUri grantUri) {
8606 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8607 if (targetUris == null) {
8608 targetUris = Maps.newArrayMap();
8609 mGrantedUriPermissions.put(targetUid, targetUris);
8612 UriPermission perm = targetUris.get(grantUri);
8614 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8615 targetUris.put(grantUri, perm);
8621 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8622 final int modeFlags) {
8623 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8624 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8625 : UriPermission.STRENGTH_OWNED;
8627 // Root gets to do everything.
8632 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8633 if (perms == null) return false;
8635 // First look for exact match
8636 final UriPermission exactPerm = perms.get(grantUri);
8637 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8641 // No exact match, look for prefixes
8642 final int N = perms.size();
8643 for (int i = 0; i < N; i++) {
8644 final UriPermission perm = perms.valueAt(i);
8645 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8646 && perm.getStrength(modeFlags) >= minStrength) {
8655 * @param uri This uri must NOT contain an embedded userId.
8656 * @param userId The userId in which the uri is to be resolved.
8659 public int checkUriPermission(Uri uri, int pid, int uid,
8660 final int modeFlags, int userId, IBinder callerToken) {
8661 enforceNotIsolatedCaller("checkUriPermission");
8663 // Another redirected-binder-call permissions check as in
8664 // {@link checkPermissionWithToken}.
8665 Identity tlsIdentity = sCallerIdentity.get();
8666 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8667 uid = tlsIdentity.uid;
8668 pid = tlsIdentity.pid;
8671 // Our own process gets to do everything.
8672 if (pid == MY_PID) {
8673 return PackageManager.PERMISSION_GRANTED;
8675 synchronized (this) {
8676 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8677 ? PackageManager.PERMISSION_GRANTED
8678 : PackageManager.PERMISSION_DENIED;
8683 * Check if the targetPkg can be granted permission to access uri by
8684 * the callingUid using the given modeFlags. Throws a security exception
8685 * if callingUid is not allowed to do this. Returns the uid of the target
8686 * if the URI permission grant should be performed; returns -1 if it is not
8687 * needed (for example targetPkg already has permission to access the URI).
8688 * If you already know the uid of the target, you can supply it in
8689 * lastTargetUid else set that to -1.
8691 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8692 final int modeFlags, int lastTargetUid) {
8693 if (!Intent.isAccessUriMode(modeFlags)) {
8697 if (targetPkg != null) {
8698 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8699 "Checking grant " + targetPkg + " permission to " + grantUri);
8702 final IPackageManager pm = AppGlobals.getPackageManager();
8704 // If this is not a content: uri, we can't do anything with it.
8705 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8706 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8707 "Can't grant URI permission for non-content URI: " + grantUri);
8711 // Bail early if system is trying to hand out permissions directly; it
8712 // must always grant permissions on behalf of someone explicit.
8713 final int callingAppId = UserHandle.getAppId(callingUid);
8714 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8715 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8716 // Exempted authority for cropping user photos in Settings app
8718 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8719 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8724 final String authority = grantUri.uri.getAuthority();
8725 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8726 MATCH_DEBUG_TRIAGED_MISSING);
8728 Slog.w(TAG, "No content provider found for permission check: " +
8729 grantUri.uri.toSafeString());
8733 int targetUid = lastTargetUid;
8734 if (targetUid < 0 && targetPkg != null) {
8736 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8737 UserHandle.getUserId(callingUid));
8738 if (targetUid < 0) {
8739 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8740 "Can't grant URI permission no uid for: " + targetPkg);
8743 } catch (RemoteException ex) {
8748 // Figure out the value returned when access is allowed
8749 final int allowedResult;
8750 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8751 // If we're extending a persistable grant, then we need to return
8752 // "targetUid" so that we always create a grant data structure to
8753 // support take/release APIs
8754 allowedResult = targetUid;
8756 // Otherwise, we can return "-1" to indicate that no grant data
8757 // structures need to be created
8761 if (targetUid >= 0) {
8762 // First... does the target actually need this permission?
8763 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8764 // No need to grant the target this permission.
8765 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8766 "Target " + targetPkg + " already has full permission to " + grantUri);
8767 return allowedResult;
8770 // First... there is no target package, so can anyone access it?
8771 boolean allowed = pi.exported;
8772 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8773 if (pi.readPermission != null) {
8777 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8778 if (pi.writePermission != null) {
8783 return allowedResult;
8787 /* There is a special cross user grant if:
8788 * - The target is on another user.
8789 * - Apps on the current user can access the uri without any uid permissions.
8790 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8791 * grant uri permissions.
8793 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8794 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8795 modeFlags, false /*without considering the uid permissions*/);
8797 // Second... is the provider allowing granting of URI permissions?
8798 if (!specialCrossUserGrant) {
8799 if (!pi.grantUriPermissions) {
8800 throw new SecurityException("Provider " + pi.packageName
8802 + " does not allow granting of Uri permissions (uri "
8805 if (pi.uriPermissionPatterns != null) {
8806 final int N = pi.uriPermissionPatterns.length;
8807 boolean allowed = false;
8808 for (int i=0; i<N; i++) {
8809 if (pi.uriPermissionPatterns[i] != null
8810 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8816 throw new SecurityException("Provider " + pi.packageName
8818 + " does not allow granting of permission to path of Uri "
8824 // Third... does the caller itself have permission to access
8826 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8827 // Require they hold a strong enough Uri permission
8828 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8829 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8830 throw new SecurityException(
8831 "UID " + callingUid + " does not have permission to " + grantUri
8832 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8833 + "or related APIs");
8835 throw new SecurityException(
8836 "UID " + callingUid + " does not have permission to " + grantUri);
8844 * @param uri This uri must NOT contain an embedded userId.
8845 * @param userId The userId in which the uri is to be resolved.
8848 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8849 final int modeFlags, int userId) {
8850 enforceNotIsolatedCaller("checkGrantUriPermission");
8851 synchronized(this) {
8852 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8853 new GrantUri(userId, uri, false), modeFlags, -1);
8857 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8858 final int modeFlags, UriPermissionOwner owner) {
8859 if (!Intent.isAccessUriMode(modeFlags)) {
8863 // So here we are: the caller has the assumed permission
8864 // to the uri, and the target doesn't. Let's now give this to
8867 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8868 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8870 final String authority = grantUri.uri.getAuthority();
8871 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8872 MATCH_DEBUG_TRIAGED_MISSING);
8874 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8878 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8879 grantUri.prefix = true;
8881 final UriPermission perm = findOrCreateUriPermissionLocked(
8882 pi.packageName, targetPkg, targetUid, grantUri);
8883 perm.grantModes(modeFlags, owner);
8886 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8887 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8888 if (targetPkg == null) {
8889 throw new NullPointerException("targetPkg");
8892 final IPackageManager pm = AppGlobals.getPackageManager();
8894 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8895 } catch (RemoteException ex) {
8899 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8901 if (targetUid < 0) {
8905 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8909 static class NeededUriGrants extends ArrayList<GrantUri> {
8910 final String targetPkg;
8911 final int targetUid;
8914 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8915 this.targetPkg = targetPkg;
8916 this.targetUid = targetUid;
8922 * Like checkGrantUriPermissionLocked, but takes an Intent.
8924 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8925 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8926 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8927 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8928 + " clip=" + (intent != null ? intent.getClipData() : null)
8929 + " from " + intent + "; flags=0x"
8930 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8932 if (targetPkg == null) {
8933 throw new NullPointerException("targetPkg");
8936 if (intent == null) {
8939 Uri data = intent.getData();
8940 ClipData clip = intent.getClipData();
8941 if (data == null && clip == null) {
8944 // Default userId for uris in the intent (if they don't specify it themselves)
8945 int contentUserHint = intent.getContentUserHint();
8946 if (contentUserHint == UserHandle.USER_CURRENT) {
8947 contentUserHint = UserHandle.getUserId(callingUid);
8949 final IPackageManager pm = AppGlobals.getPackageManager();
8951 if (needed != null) {
8952 targetUid = needed.targetUid;
8955 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8957 } catch (RemoteException ex) {
8960 if (targetUid < 0) {
8961 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8962 "Can't grant URI permission no uid for: " + targetPkg
8963 + " on user " + targetUserId);
8968 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8969 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8971 if (targetUid > 0) {
8972 if (needed == null) {
8973 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8975 needed.add(grantUri);
8979 for (int i=0; i<clip.getItemCount(); i++) {
8980 Uri uri = clip.getItemAt(i).getUri();
8982 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8983 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8985 if (targetUid > 0) {
8986 if (needed == null) {
8987 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8989 needed.add(grantUri);
8992 Intent clipIntent = clip.getItemAt(i).getIntent();
8993 if (clipIntent != null) {
8994 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8995 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8996 if (newNeeded != null) {
9008 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9010 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9011 UriPermissionOwner owner) {
9012 if (needed != null) {
9013 for (int i=0; i<needed.size(); i++) {
9014 GrantUri grantUri = needed.get(i);
9015 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9016 grantUri, needed.flags, owner);
9021 void grantUriPermissionFromIntentLocked(int callingUid,
9022 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9023 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9024 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9025 if (needed == null) {
9029 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9033 * @param uri This uri must NOT contain an embedded userId.
9034 * @param userId The userId in which the uri is to be resolved.
9037 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9038 final int modeFlags, int userId) {
9039 enforceNotIsolatedCaller("grantUriPermission");
9040 GrantUri grantUri = new GrantUri(userId, uri, false);
9041 synchronized(this) {
9042 final ProcessRecord r = getRecordForAppLocked(caller);
9044 throw new SecurityException("Unable to find app for caller "
9046 + " when granting permission to uri " + grantUri);
9048 if (targetPkg == null) {
9049 throw new IllegalArgumentException("null target");
9051 if (grantUri == null) {
9052 throw new IllegalArgumentException("null uri");
9055 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9056 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9057 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9058 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9060 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9061 UserHandle.getUserId(r.uid));
9065 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9066 if (perm.modeFlags == 0) {
9067 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9069 if (perms != null) {
9070 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9071 "Removing " + perm.targetUid + " permission to " + perm.uri);
9073 perms.remove(perm.uri);
9074 if (perms.isEmpty()) {
9075 mGrantedUriPermissions.remove(perm.targetUid);
9081 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9082 final int modeFlags) {
9083 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9084 "Revoking all granted permissions to " + grantUri);
9086 final IPackageManager pm = AppGlobals.getPackageManager();
9087 final String authority = grantUri.uri.getAuthority();
9088 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9089 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9091 Slog.w(TAG, "No content provider found for permission revoke: "
9092 + grantUri.toSafeString());
9096 // Does the caller have this permission on the URI?
9097 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9098 // If they don't have direct access to the URI, then revoke any
9099 // ownerless URI permissions that have been granted to them.
9100 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9101 if (perms != null) {
9102 boolean persistChanged = false;
9103 for (int i = perms.size()-1; i >= 0; i--) {
9104 final UriPermission perm = perms.valueAt(i);
9105 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9108 if (perm.uri.sourceUserId == grantUri.sourceUserId
9109 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9110 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9111 "Revoking non-owned " + perm.targetUid
9112 + " permission to " + perm.uri);
9113 persistChanged |= perm.revokeModes(
9114 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9115 if (perm.modeFlags == 0) {
9120 if (perms.isEmpty()) {
9121 mGrantedUriPermissions.remove(callingUid);
9123 if (persistChanged) {
9124 schedulePersistUriGrants();
9130 boolean persistChanged = false;
9132 // Go through all of the permissions and remove any that match.
9133 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9134 final int targetUid = mGrantedUriPermissions.keyAt(i);
9135 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9137 for (int j = perms.size()-1; j >= 0; j--) {
9138 final UriPermission perm = perms.valueAt(j);
9139 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9142 if (perm.uri.sourceUserId == grantUri.sourceUserId
9143 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9144 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9145 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9146 persistChanged |= perm.revokeModes(
9147 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9148 targetPackage == null);
9149 if (perm.modeFlags == 0) {
9155 if (perms.isEmpty()) {
9156 mGrantedUriPermissions.removeAt(i);
9160 if (persistChanged) {
9161 schedulePersistUriGrants();
9166 * @param uri This uri must NOT contain an embedded userId.
9167 * @param userId The userId in which the uri is to be resolved.
9170 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9171 final int modeFlags, int userId) {
9172 enforceNotIsolatedCaller("revokeUriPermission");
9173 synchronized(this) {
9174 final ProcessRecord r = getRecordForAppLocked(caller);
9176 throw new SecurityException("Unable to find app for caller "
9178 + " when revoking permission to uri " + uri);
9181 Slog.w(TAG, "revokeUriPermission: null uri");
9185 if (!Intent.isAccessUriMode(modeFlags)) {
9189 final String authority = uri.getAuthority();
9190 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9191 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9193 Slog.w(TAG, "No content provider found for permission revoke: "
9194 + uri.toSafeString());
9198 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9204 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9207 * @param packageName Package name to match, or {@code null} to apply to all
9209 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9211 * @param persistable If persistable grants should be removed.
9213 private void removeUriPermissionsForPackageLocked(
9214 String packageName, int userHandle, boolean persistable) {
9215 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9216 throw new IllegalArgumentException("Must narrow by either package or user");
9219 boolean persistChanged = false;
9221 int N = mGrantedUriPermissions.size();
9222 for (int i = 0; i < N; i++) {
9223 final int targetUid = mGrantedUriPermissions.keyAt(i);
9224 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9226 // Only inspect grants matching user
9227 if (userHandle == UserHandle.USER_ALL
9228 || userHandle == UserHandle.getUserId(targetUid)) {
9229 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9230 final UriPermission perm = it.next();
9232 // Only inspect grants matching package
9233 if (packageName == null || perm.sourcePkg.equals(packageName)
9234 || perm.targetPkg.equals(packageName)) {
9235 // Hacky solution as part of fixing a security bug; ignore
9236 // grants associated with DownloadManager so we don't have
9237 // to immediately launch it to regrant the permissions
9238 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9239 && !persistable) continue;
9241 persistChanged |= perm.revokeModes(persistable
9242 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9244 // Only remove when no modes remain; any persisted grants
9245 // will keep this alive.
9246 if (perm.modeFlags == 0) {
9252 if (perms.isEmpty()) {
9253 mGrantedUriPermissions.remove(targetUid);
9260 if (persistChanged) {
9261 schedulePersistUriGrants();
9266 public IBinder newUriPermissionOwner(String name) {
9267 enforceNotIsolatedCaller("newUriPermissionOwner");
9268 synchronized(this) {
9269 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9270 return owner.getExternalTokenLocked();
9275 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9276 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9277 synchronized(this) {
9278 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9280 throw new IllegalArgumentException("Activity does not exist; token="
9283 return r.getUriPermissionsLocked().getExternalTokenLocked();
9287 * @param uri This uri must NOT contain an embedded userId.
9288 * @param sourceUserId The userId in which the uri is to be resolved.
9289 * @param targetUserId The userId of the app that receives the grant.
9292 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9293 final int modeFlags, int sourceUserId, int targetUserId) {
9294 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9295 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9296 "grantUriPermissionFromOwner", null);
9297 synchronized(this) {
9298 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9299 if (owner == null) {
9300 throw new IllegalArgumentException("Unknown owner: " + token);
9302 if (fromUid != Binder.getCallingUid()) {
9303 if (Binder.getCallingUid() != myUid()) {
9304 // Only system code can grant URI permissions on behalf
9306 throw new SecurityException("nice try");
9309 if (targetPkg == null) {
9310 throw new IllegalArgumentException("null target");
9313 throw new IllegalArgumentException("null uri");
9316 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9317 modeFlags, owner, targetUserId);
9322 * @param uri This uri must NOT contain an embedded userId.
9323 * @param userId The userId in which the uri is to be resolved.
9326 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9327 synchronized(this) {
9328 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9329 if (owner == null) {
9330 throw new IllegalArgumentException("Unknown owner: " + token);
9334 owner.removeUriPermissionsLocked(mode);
9336 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9337 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9342 private void schedulePersistUriGrants() {
9343 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9344 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9345 10 * DateUtils.SECOND_IN_MILLIS);
9349 private void writeGrantedUriPermissions() {
9350 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9352 // Snapshot permissions so we can persist without lock
9353 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9354 synchronized (this) {
9355 final int size = mGrantedUriPermissions.size();
9356 for (int i = 0; i < size; i++) {
9357 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9358 for (UriPermission perm : perms.values()) {
9359 if (perm.persistedModeFlags != 0) {
9360 persist.add(perm.snapshot());
9366 FileOutputStream fos = null;
9368 fos = mGrantFile.startWrite();
9370 XmlSerializer out = new FastXmlSerializer();
9371 out.setOutput(fos, StandardCharsets.UTF_8.name());
9372 out.startDocument(null, true);
9373 out.startTag(null, TAG_URI_GRANTS);
9374 for (UriPermission.Snapshot perm : persist) {
9375 out.startTag(null, TAG_URI_GRANT);
9376 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9377 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9378 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9379 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9380 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9381 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9382 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9383 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9384 out.endTag(null, TAG_URI_GRANT);
9386 out.endTag(null, TAG_URI_GRANTS);
9389 mGrantFile.finishWrite(fos);
9390 } catch (IOException e) {
9392 mGrantFile.failWrite(fos);
9397 private void readGrantedUriPermissionsLocked() {
9398 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9400 final long now = System.currentTimeMillis();
9402 FileInputStream fis = null;
9404 fis = mGrantFile.openRead();
9405 final XmlPullParser in = Xml.newPullParser();
9406 in.setInput(fis, StandardCharsets.UTF_8.name());
9409 while ((type = in.next()) != END_DOCUMENT) {
9410 final String tag = in.getName();
9411 if (type == START_TAG) {
9412 if (TAG_URI_GRANT.equals(tag)) {
9413 final int sourceUserId;
9414 final int targetUserId;
9415 final int userHandle = readIntAttribute(in,
9416 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9417 if (userHandle != UserHandle.USER_NULL) {
9418 // For backwards compatibility.
9419 sourceUserId = userHandle;
9420 targetUserId = userHandle;
9422 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9423 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9425 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9426 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9427 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9428 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9429 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9430 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9432 // Sanity check that provider still belongs to source package
9433 // Both direct boot aware and unaware packages are fine as we
9434 // will do filtering at query time to avoid multiple parsing.
9435 final ProviderInfo pi = getProviderInfoLocked(
9436 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9437 | MATCH_DIRECT_BOOT_UNAWARE);
9438 if (pi != null && sourcePkg.equals(pi.packageName)) {
9441 targetUid = AppGlobals.getPackageManager().getPackageUid(
9442 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9443 } catch (RemoteException e) {
9445 if (targetUid != -1) {
9446 final UriPermission perm = findOrCreateUriPermissionLocked(
9447 sourcePkg, targetPkg, targetUid,
9448 new GrantUri(sourceUserId, uri, prefix));
9449 perm.initPersistedModes(modeFlags, createdTime);
9452 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9453 + " but instead found " + pi);
9458 } catch (FileNotFoundException e) {
9459 // Missing grants is okay
9460 } catch (IOException e) {
9461 Slog.wtf(TAG, "Failed reading Uri grants", e);
9462 } catch (XmlPullParserException e) {
9463 Slog.wtf(TAG, "Failed reading Uri grants", e);
9465 IoUtils.closeQuietly(fis);
9470 * @param uri This uri must NOT contain an embedded userId.
9471 * @param userId The userId in which the uri is to be resolved.
9474 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9475 enforceNotIsolatedCaller("takePersistableUriPermission");
9477 Preconditions.checkFlagsArgument(modeFlags,
9478 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9480 synchronized (this) {
9481 final int callingUid = Binder.getCallingUid();
9482 boolean persistChanged = false;
9483 GrantUri grantUri = new GrantUri(userId, uri, false);
9485 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9486 new GrantUri(userId, uri, false));
9487 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9488 new GrantUri(userId, uri, true));
9490 final boolean exactValid = (exactPerm != null)
9491 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9492 final boolean prefixValid = (prefixPerm != null)
9493 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9495 if (!(exactValid || prefixValid)) {
9496 throw new SecurityException("No persistable permission grants found for UID "
9497 + callingUid + " and Uri " + grantUri.toSafeString());
9501 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9504 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9507 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9509 if (persistChanged) {
9510 schedulePersistUriGrants();
9516 * @param uri This uri must NOT contain an embedded userId.
9517 * @param userId The userId in which the uri is to be resolved.
9520 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9521 enforceNotIsolatedCaller("releasePersistableUriPermission");
9523 Preconditions.checkFlagsArgument(modeFlags,
9524 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9526 synchronized (this) {
9527 final int callingUid = Binder.getCallingUid();
9528 boolean persistChanged = false;
9530 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9531 new GrantUri(userId, uri, false));
9532 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9533 new GrantUri(userId, uri, true));
9534 if (exactPerm == null && prefixPerm == null) {
9535 throw new SecurityException("No permission grants found for UID " + callingUid
9536 + " and Uri " + uri.toSafeString());
9539 if (exactPerm != null) {
9540 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9541 removeUriPermissionIfNeededLocked(exactPerm);
9543 if (prefixPerm != null) {
9544 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9545 removeUriPermissionIfNeededLocked(prefixPerm);
9548 if (persistChanged) {
9549 schedulePersistUriGrants();
9555 * Prune any older {@link UriPermission} for the given UID until outstanding
9556 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9558 * @return if any mutations occured that require persisting.
9560 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9561 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9562 if (perms == null) return false;
9563 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9565 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9566 for (UriPermission perm : perms.values()) {
9567 if (perm.persistedModeFlags != 0) {
9568 persisted.add(perm);
9572 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9573 if (trimCount <= 0) return false;
9575 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9576 for (int i = 0; i < trimCount; i++) {
9577 final UriPermission perm = persisted.get(i);
9579 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9580 "Trimming grant created at " + perm.persistedCreateTime);
9582 perm.releasePersistableModes(~0);
9583 removeUriPermissionIfNeededLocked(perm);
9590 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9591 String packageName, boolean incoming) {
9592 enforceNotIsolatedCaller("getPersistedUriPermissions");
9593 Preconditions.checkNotNull(packageName, "packageName");
9595 final int callingUid = Binder.getCallingUid();
9596 final int callingUserId = UserHandle.getUserId(callingUid);
9597 final IPackageManager pm = AppGlobals.getPackageManager();
9599 final int packageUid = pm.getPackageUid(packageName,
9600 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9601 if (packageUid != callingUid) {
9602 throw new SecurityException(
9603 "Package " + packageName + " does not belong to calling UID " + callingUid);
9605 } catch (RemoteException e) {
9606 throw new SecurityException("Failed to verify package name ownership");
9609 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9610 synchronized (this) {
9612 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9614 if (perms == null) {
9615 Slog.w(TAG, "No permission grants found for " + packageName);
9617 for (UriPermission perm : perms.values()) {
9618 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9619 result.add(perm.buildPersistedPublicApiObject());
9624 final int size = mGrantedUriPermissions.size();
9625 for (int i = 0; i < size; i++) {
9626 final ArrayMap<GrantUri, UriPermission> perms =
9627 mGrantedUriPermissions.valueAt(i);
9628 for (UriPermission perm : perms.values()) {
9629 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9630 result.add(perm.buildPersistedPublicApiObject());
9636 return new ParceledListSlice<android.content.UriPermission>(result);
9640 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9641 String packageName, int userId) {
9642 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9643 "getGrantedUriPermissions");
9645 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9646 synchronized (this) {
9647 final int size = mGrantedUriPermissions.size();
9648 for (int i = 0; i < size; i++) {
9649 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9650 for (UriPermission perm : perms.values()) {
9651 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9652 && perm.persistedModeFlags != 0) {
9653 result.add(perm.buildPersistedPublicApiObject());
9658 return new ParceledListSlice<android.content.UriPermission>(result);
9662 public void clearGrantedUriPermissions(String packageName, int userId) {
9663 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9664 "clearGrantedUriPermissions");
9665 removeUriPermissionsForPackageLocked(packageName, userId, true);
9669 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9670 synchronized (this) {
9672 who != null ? getRecordForAppLocked(who) : null;
9673 if (app == null) return;
9675 Message msg = Message.obtain();
9676 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9678 msg.arg1 = waiting ? 1 : 0;
9679 mUiHandler.sendMessage(msg);
9684 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9685 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9686 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9687 outInfo.availMem = getFreeMemory();
9688 outInfo.totalMem = getTotalMemory();
9689 outInfo.threshold = homeAppMem;
9690 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9691 outInfo.hiddenAppThreshold = cachedAppMem;
9692 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9693 ProcessList.SERVICE_ADJ);
9694 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9695 ProcessList.VISIBLE_APP_ADJ);
9696 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9697 ProcessList.FOREGROUND_APP_ADJ);
9700 // =========================================================
9702 // =========================================================
9705 public List<IBinder> getAppTasks(String callingPackage) {
9706 int callingUid = Binder.getCallingUid();
9707 long ident = Binder.clearCallingIdentity();
9709 synchronized(this) {
9710 ArrayList<IBinder> list = new ArrayList<IBinder>();
9712 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9714 final int N = mRecentTasks.size();
9715 for (int i = 0; i < N; i++) {
9716 TaskRecord tr = mRecentTasks.get(i);
9717 // Skip tasks that do not match the caller. We don't need to verify
9718 // callingPackage, because we are also limiting to callingUid and know
9719 // that will limit to the correct security sandbox.
9720 if (tr.effectiveUid != callingUid) {
9723 Intent intent = tr.getBaseIntent();
9724 if (intent == null ||
9725 !callingPackage.equals(intent.getComponent().getPackageName())) {
9728 ActivityManager.RecentTaskInfo taskInfo =
9729 createRecentTaskInfoFromTaskRecord(tr);
9730 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9731 list.add(taskImpl.asBinder());
9734 Binder.restoreCallingIdentity(ident);
9741 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9742 final int callingUid = Binder.getCallingUid();
9743 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9745 synchronized(this) {
9746 if (DEBUG_ALL) Slog.v(
9747 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9749 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9752 // TODO: Improve with MRU list from all ActivityStacks.
9753 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9760 * Creates a new RecentTaskInfo from a TaskRecord.
9762 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9763 // Update the task description to reflect any changes in the task stack
9764 tr.updateTaskDescription();
9766 // Compose the recent task info
9767 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9768 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9769 rti.persistentId = tr.taskId;
9770 rti.baseIntent = new Intent(tr.getBaseIntent());
9771 rti.origActivity = tr.origActivity;
9772 rti.realActivity = tr.realActivity;
9773 rti.description = tr.lastDescription;
9774 rti.stackId = tr.getStackId();
9775 rti.userId = tr.userId;
9776 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9777 rti.firstActiveTime = tr.firstActiveTime;
9778 rti.lastActiveTime = tr.lastActiveTime;
9779 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9780 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9781 rti.numActivities = 0;
9782 if (tr.mBounds != null) {
9783 rti.bounds = new Rect(tr.mBounds);
9785 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9786 rti.resizeMode = tr.mResizeMode;
9788 ActivityRecord base = null;
9789 ActivityRecord top = null;
9792 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9793 tmp = tr.mActivities.get(i);
9794 if (tmp.finishing) {
9798 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9801 rti.numActivities++;
9804 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9805 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9810 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9811 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9812 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9814 if (checkPermission(android.Manifest.permission.GET_TASKS,
9815 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9816 // Temporary compatibility: some existing apps on the system image may
9817 // still be requesting the old permission and not switched to the new
9818 // one; if so, we'll still allow them full access. This means we need
9819 // to see if they are holding the old permission and are a system app.
9821 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9823 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9824 + " is using old GET_TASKS but privileged; allowing");
9826 } catch (RemoteException e) {
9831 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9832 + " does not hold REAL_GET_TASKS; limiting output");
9838 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9840 final int callingUid = Binder.getCallingUid();
9841 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9842 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9844 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9845 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9846 synchronized (this) {
9847 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9849 final boolean detailed = checkCallingPermission(
9850 android.Manifest.permission.GET_DETAILED_TASKS)
9851 == PackageManager.PERMISSION_GRANTED;
9853 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9854 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9855 return ParceledListSlice.emptyList();
9857 mRecentTasks.loadUserRecentsLocked(userId);
9859 final int recentsCount = mRecentTasks.size();
9860 ArrayList<ActivityManager.RecentTaskInfo> res =
9861 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9863 final Set<Integer> includedUsers;
9864 if (includeProfiles) {
9865 includedUsers = mUserController.getProfileIds(userId);
9867 includedUsers = new HashSet<>();
9869 includedUsers.add(Integer.valueOf(userId));
9871 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9872 TaskRecord tr = mRecentTasks.get(i);
9873 // Only add calling user or related users recent tasks
9874 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9875 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9879 if (tr.realActivitySuspended) {
9880 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9884 // Return the entry if desired by the caller. We always return
9885 // the first entry, because callers always expect this to be the
9886 // foreground app. We may filter others if the caller has
9887 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9888 // we should exclude the entry.
9892 || (tr.intent == null)
9893 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9896 // If the caller doesn't have the GET_TASKS permission, then only
9897 // allow them to see a small subset of tasks -- their own and home.
9898 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9899 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9903 final ActivityStack stack = tr.getStack();
9904 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9905 if (stack != null && stack.isHomeOrRecentsStack()) {
9906 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9907 "Skipping, home or recents stack task: " + tr);
9911 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9912 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9913 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9914 "Skipping, top task in docked stack: " + tr);
9918 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9919 if (stack != null && stack.isPinnedStack()) {
9920 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9921 "Skipping, pinned stack task: " + tr);
9925 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9926 // Don't include auto remove tasks that are finished or finishing.
9927 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9928 "Skipping, auto-remove without activity: " + tr);
9931 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9932 && !tr.isAvailable) {
9933 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9934 "Skipping, unavail real act: " + tr);
9938 if (!tr.mUserSetupComplete) {
9939 // Don't include task launched while user is not done setting-up.
9940 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9941 "Skipping, user setup not complete: " + tr);
9945 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9947 rti.baseIntent.replaceExtras((Bundle)null);
9954 return new ParceledListSlice<>(res);
9959 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9960 synchronized (this) {
9961 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9962 "getTaskThumbnail()");
9963 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9964 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9966 return tr.getTaskThumbnailLocked();
9973 public ActivityManager.TaskDescription getTaskDescription(int id) {
9974 synchronized (this) {
9975 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9976 "getTaskDescription()");
9977 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9978 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9980 return tr.lastTaskDescription;
9987 public int addAppTask(IBinder activityToken, Intent intent,
9988 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9989 final int callingUid = Binder.getCallingUid();
9990 final long callingIdent = Binder.clearCallingIdentity();
9993 synchronized (this) {
9994 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9996 throw new IllegalArgumentException("Activity does not exist; token="
9999 ComponentName comp = intent.getComponent();
10000 if (comp == null) {
10001 throw new IllegalArgumentException("Intent " + intent
10002 + " must specify explicit component");
10004 if (thumbnail.getWidth() != mThumbnailWidth
10005 || thumbnail.getHeight() != mThumbnailHeight) {
10006 throw new IllegalArgumentException("Bad thumbnail size: got "
10007 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10008 + mThumbnailWidth + "x" + mThumbnailHeight);
10010 if (intent.getSelector() != null) {
10011 intent.setSelector(null);
10013 if (intent.getSourceBounds() != null) {
10014 intent.setSourceBounds(null);
10016 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10017 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10018 // The caller has added this as an auto-remove task... that makes no
10019 // sense, so turn off auto-remove.
10020 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10023 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10024 mLastAddedTaskActivity = null;
10026 ActivityInfo ainfo = mLastAddedTaskActivity;
10027 if (ainfo == null) {
10028 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10029 comp, 0, UserHandle.getUserId(callingUid));
10030 if (ainfo.applicationInfo.uid != callingUid) {
10031 throw new SecurityException(
10032 "Can't add task for another application: target uid="
10033 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10037 TaskRecord task = new TaskRecord(this,
10038 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10039 ainfo, intent, description, new TaskThumbnailInfo());
10041 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10042 if (trimIdx >= 0) {
10043 // If this would have caused a trim, then we'll abort because that
10044 // means it would be added at the end of the list but then just removed.
10045 return INVALID_TASK_ID;
10048 final int N = mRecentTasks.size();
10049 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10050 final TaskRecord tr = mRecentTasks.remove(N - 1);
10051 tr.removedFromRecents();
10054 task.inRecents = true;
10055 mRecentTasks.add(task);
10056 r.getStack().addTask(task, false, "addAppTask");
10058 task.setLastThumbnailLocked(thumbnail);
10059 task.freeLastThumbnail();
10060 return task.taskId;
10063 Binder.restoreCallingIdentity(callingIdent);
10068 public Point getAppTaskThumbnailSize() {
10069 synchronized (this) {
10070 return new Point(mThumbnailWidth, mThumbnailHeight);
10075 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10076 synchronized (this) {
10077 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10079 r.setTaskDescription(td);
10080 final TaskRecord task = r.getTask();
10081 task.updateTaskDescription();
10082 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10088 public void setTaskResizeable(int taskId, int resizeableMode) {
10089 synchronized (this) {
10090 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10091 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10092 if (task == null) {
10093 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10096 task.setResizeMode(resizeableMode);
10101 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10102 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10103 long ident = Binder.clearCallingIdentity();
10105 synchronized (this) {
10106 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10107 if (task == null) {
10108 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10111 // Place the task in the right stack if it isn't there already based on
10112 // the requested bounds.
10113 // The stack transition logic is:
10114 // - a null bounds on a freeform task moves that task to fullscreen
10115 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10116 // that task to freeform
10117 // - otherwise the task is not moved
10118 int stackId = task.getStackId();
10119 if (!StackId.isTaskResizeAllowed(stackId)) {
10120 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10122 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10123 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10124 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10125 stackId = FREEFORM_WORKSPACE_STACK_ID;
10128 // Reparent the task to the right stack if necessary
10129 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10130 if (stackId != task.getStackId()) {
10131 // Defer resume until the task is resized below
10132 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10133 DEFER_RESUME, "resizeTask");
10134 preserveWindow = false;
10137 // After reparenting (which only resizes the task to the stack bounds), resize the
10138 // task to the actual bounds provided
10139 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10142 Binder.restoreCallingIdentity(ident);
10147 public Rect getTaskBounds(int taskId) {
10148 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10149 long ident = Binder.clearCallingIdentity();
10150 Rect rect = new Rect();
10152 synchronized (this) {
10153 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10154 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10155 if (task == null) {
10156 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10159 if (task.getStack() != null) {
10160 // Return the bounds from window manager since it will be adjusted for various
10161 // things like the presense of a docked stack for tasks that aren't resizeable.
10162 task.getWindowContainerBounds(rect);
10164 // Task isn't in window manager yet since it isn't associated with a stack.
10165 // Return the persist value from activity manager
10166 if (task.mBounds != null) {
10167 rect.set(task.mBounds);
10168 } else if (task.mLastNonFullscreenBounds != null) {
10169 rect.set(task.mLastNonFullscreenBounds);
10174 Binder.restoreCallingIdentity(ident);
10180 public void cancelTaskWindowTransition(int taskId) {
10181 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10182 final long ident = Binder.clearCallingIdentity();
10184 synchronized (this) {
10185 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10186 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10187 if (task == null) {
10188 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10191 task.cancelWindowTransition();
10194 Binder.restoreCallingIdentity(ident);
10199 public void cancelTaskThumbnailTransition(int taskId) {
10200 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10201 final long ident = Binder.clearCallingIdentity();
10203 synchronized (this) {
10204 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10205 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10206 if (task == null) {
10207 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10210 task.cancelThumbnailTransition();
10213 Binder.restoreCallingIdentity(ident);
10218 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10219 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10220 final long ident = Binder.clearCallingIdentity();
10222 final TaskRecord task;
10223 synchronized (this) {
10224 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10225 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10226 if (task == null) {
10227 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10231 // Don't call this while holding the lock as this operation might hit the disk.
10232 return task.getSnapshot(reducedResolution);
10234 Binder.restoreCallingIdentity(ident);
10239 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10240 if (userId != UserHandle.getCallingUserId()) {
10241 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10242 "getTaskDescriptionIcon");
10244 final File passedIconFile = new File(filePath);
10245 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10246 passedIconFile.getName());
10247 if (!legitIconFile.getPath().equals(filePath)
10248 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10249 throw new IllegalArgumentException("Bad file path: " + filePath
10250 + " passed for userId " + userId);
10252 return mRecentTasks.getTaskDescriptionIcon(filePath);
10256 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10257 throws RemoteException {
10258 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10259 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10260 activityOptions.getCustomInPlaceResId() == 0) {
10261 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10262 "with valid animation");
10264 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10265 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10266 activityOptions.getCustomInPlaceResId());
10267 mWindowManager.executeAppTransition();
10270 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10271 // Remove all tasks with activities in the specified package from the list of recent tasks
10272 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10273 TaskRecord tr = mRecentTasks.get(i);
10274 if (tr.userId != userId) continue;
10276 ComponentName cn = tr.intent.getComponent();
10277 if (cn != null && cn.getPackageName().equals(packageName)) {
10278 // If the package name matches, remove the task.
10279 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10284 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10287 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10288 TaskRecord tr = mRecentTasks.get(i);
10289 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10293 ComponentName cn = tr.intent.getComponent();
10294 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10295 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10296 if (sameComponent) {
10297 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10303 public void removeStack(int stackId) {
10304 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10305 if (StackId.isHomeOrRecentsStack(stackId)) {
10306 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10309 synchronized (this) {
10310 final long ident = Binder.clearCallingIdentity();
10312 mStackSupervisor.removeStackLocked(stackId);
10314 Binder.restoreCallingIdentity(ident);
10320 public void moveStackToDisplay(int stackId, int displayId) {
10321 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10323 synchronized (this) {
10324 final long ident = Binder.clearCallingIdentity();
10326 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10327 + " to displayId=" + displayId);
10328 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10330 Binder.restoreCallingIdentity(ident);
10336 public boolean removeTask(int taskId) {
10337 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10338 synchronized (this) {
10339 final long ident = Binder.clearCallingIdentity();
10341 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10343 Binder.restoreCallingIdentity(ident);
10349 * TODO: Add mController hook
10352 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10353 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10355 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10356 synchronized(this) {
10357 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10361 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10362 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10364 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10365 Binder.getCallingUid(), -1, -1, "Task to front")) {
10366 ActivityOptions.abort(options);
10369 final long origId = Binder.clearCallingIdentity();
10371 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10372 if (task == null) {
10373 Slog.d(TAG, "Could not find task for id: "+ taskId);
10376 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10377 mStackSupervisor.showLockTaskToast();
10378 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10381 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10382 if (prev != null) {
10383 task.setTaskToReturnTo(prev);
10385 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10386 false /* forceNonResizable */);
10388 final ActivityRecord topActivity = task.getTopActivity();
10389 if (topActivity != null) {
10391 // We are reshowing a task, use a starting window to hide the initial draw delay
10392 // so the transition can start earlier.
10393 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10394 true /* taskSwitch */, fromRecents);
10397 Binder.restoreCallingIdentity(origId);
10399 ActivityOptions.abort(options);
10403 * Attempts to move a task backwards in z-order (the order of activities within the task is
10406 * There are several possible results of this call:
10407 * - if the task is locked, then we will show the lock toast
10408 * - if there is a task behind the provided task, then that task is made visible and resumed as
10409 * this task is moved to the back
10410 * - otherwise, if there are no other tasks in the stack:
10411 * - if this task is in the pinned stack, then we remove the stack completely, which will
10412 * have the effect of moving the task to the top or bottom of the fullscreen stack
10413 * (depending on whether it is visible)
10414 * - otherwise, we simply return home and hide this task
10416 * @param token A reference to the activity we wish to move
10417 * @param nonRoot If false then this only works if the activity is the root
10418 * of a task; if true it will work for any activity in a task.
10419 * @return Returns true if the move completed, false if not.
10422 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10423 enforceNotIsolatedCaller("moveActivityTaskToBack");
10424 synchronized(this) {
10425 final long origId = Binder.clearCallingIdentity();
10427 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10428 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10429 if (task != null) {
10430 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10433 Binder.restoreCallingIdentity(origId);
10440 public void moveTaskBackwards(int task) {
10441 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10442 "moveTaskBackwards()");
10444 synchronized(this) {
10445 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10446 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10449 final long origId = Binder.clearCallingIdentity();
10450 moveTaskBackwardsLocked(task);
10451 Binder.restoreCallingIdentity(origId);
10455 private final void moveTaskBackwardsLocked(int task) {
10456 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10460 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10461 IActivityContainerCallback callback) throws RemoteException {
10462 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10463 synchronized (this) {
10464 if (parentActivityToken == null) {
10465 throw new IllegalArgumentException("parent token must not be null");
10467 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10471 if (callback == null) {
10472 throw new IllegalArgumentException("callback must not be null");
10474 return mStackSupervisor.createVirtualActivityContainer(r, callback);
10479 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10480 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10481 synchronized (this) {
10482 final int stackId = mStackSupervisor.getNextStackId();
10483 final ActivityStack stack =
10484 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10485 if (stack == null) {
10488 return stack.mActivityContainer;
10493 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10494 synchronized (this) {
10495 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10496 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10497 return stack.mActivityContainer.getDisplayId();
10499 return DEFAULT_DISPLAY;
10504 public int getActivityStackId(IBinder token) throws RemoteException {
10505 synchronized (this) {
10506 ActivityStack stack = ActivityRecord.getStackLocked(token);
10507 if (stack == null) {
10508 return INVALID_STACK_ID;
10510 return stack.mStackId;
10515 public void exitFreeformMode(IBinder token) throws RemoteException {
10516 synchronized (this) {
10517 long ident = Binder.clearCallingIdentity();
10519 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10521 throw new IllegalArgumentException(
10522 "exitFreeformMode: No activity record matching token=" + token);
10525 final ActivityStack stack = r.getStack();
10526 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10527 throw new IllegalStateException(
10528 "exitFreeformMode: You can only go fullscreen from freeform.");
10531 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10532 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10533 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10535 Binder.restoreCallingIdentity(ident);
10541 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10542 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10543 if (StackId.isHomeOrRecentsStack(stackId)) {
10544 throw new IllegalArgumentException(
10545 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10547 synchronized (this) {
10548 long ident = Binder.clearCallingIdentity();
10550 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10551 if (task == null) {
10552 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10556 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10557 + " to stackId=" + stackId + " toTop=" + toTop);
10558 if (stackId == DOCKED_STACK_ID) {
10559 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10560 null /* initialBounds */);
10562 task.reparent(stackId, toTop,
10563 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10565 Binder.restoreCallingIdentity(ident);
10571 public void swapDockedAndFullscreenStack() throws RemoteException {
10572 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10573 synchronized (this) {
10574 long ident = Binder.clearCallingIdentity();
10576 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10577 FULLSCREEN_WORKSPACE_STACK_ID);
10578 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10580 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10581 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10583 if (topTask == null || tasks == null || tasks.size() == 0) {
10585 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10589 // TODO: App transition
10590 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10592 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10593 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10594 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10595 final int size = tasks.size();
10596 for (int i = 0; i < size; i++) {
10597 final int id = tasks.get(i).taskId;
10598 if (id == topTask.taskId) {
10602 // Defer the resume until after all the tasks have been moved
10603 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10604 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10605 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10608 // Because we deferred the resume to avoid conflicts with stack switches while
10609 // resuming, we need to do it after all the tasks are moved.
10610 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10611 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10613 mWindowManager.executeAppTransition();
10615 Binder.restoreCallingIdentity(ident);
10621 * Moves the input task to the docked stack.
10623 * @param taskId Id of task to move.
10624 * @param createMode The mode the docked stack should be created in if it doesn't exist
10626 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10628 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10629 * @param toTop If the task and stack should be moved to the top.
10630 * @param animate Whether we should play an animation for the moving the task
10631 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10632 * docked stack. Pass {@code null} to use default bounds.
10635 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10636 Rect initialBounds) {
10637 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10638 synchronized (this) {
10639 long ident = Binder.clearCallingIdentity();
10641 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10642 if (task == null) {
10643 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10647 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10648 + " to createMode=" + createMode + " toTop=" + toTop);
10649 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10651 // Defer resuming until we move the home stack to the front below
10652 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10653 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10654 "moveTaskToDockedStack");
10656 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10660 Binder.restoreCallingIdentity(ident);
10666 * Moves the top activity in the input stackId to the pinned stack.
10668 * @param stackId Id of stack to move the top activity to pinned stack.
10669 * @param bounds Bounds to use for pinned stack.
10671 * @return True if the top activity of the input stack was successfully moved to the pinned
10675 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10676 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10677 synchronized (this) {
10678 if (!mSupportsPictureInPicture) {
10679 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10680 + "Device doesn't support picture-in-picture mode");
10683 long ident = Binder.clearCallingIdentity();
10685 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10687 Binder.restoreCallingIdentity(ident);
10693 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10694 boolean preserveWindows, boolean animate, int animationDuration) {
10695 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10696 long ident = Binder.clearCallingIdentity();
10698 synchronized (this) {
10700 if (stackId == PINNED_STACK_ID) {
10701 final PinnedActivityStack pinnedStack =
10702 mStackSupervisor.getStack(PINNED_STACK_ID);
10703 if (pinnedStack != null) {
10704 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10705 destBounds, animationDuration, false /* fromFullscreen */);
10708 throw new IllegalArgumentException("Stack: " + stackId
10709 + " doesn't support animated resize.");
10712 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10713 null /* tempTaskInsetBounds */, preserveWindows,
10714 allowResizeInDockedMode, !DEFER_RESUME);
10718 Binder.restoreCallingIdentity(ident);
10723 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10724 Rect tempDockedTaskInsetBounds,
10725 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10726 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10727 "resizeDockedStack()");
10728 long ident = Binder.clearCallingIdentity();
10730 synchronized (this) {
10731 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10732 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10736 Binder.restoreCallingIdentity(ident);
10741 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10742 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10743 "resizePinnedStack()");
10744 final long ident = Binder.clearCallingIdentity();
10746 synchronized (this) {
10747 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10750 Binder.restoreCallingIdentity(ident);
10755 * Try to place task to provided position. The final position might be different depending on
10756 * current user and stacks state. The task will be moved to target stack if it's currently in
10760 public void positionTaskInStack(int taskId, int stackId, int position) {
10761 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10762 if (StackId.isHomeOrRecentsStack(stackId)) {
10763 throw new IllegalArgumentException(
10764 "positionTaskInStack: Attempt to change the position of task "
10765 + taskId + " in/to home/recents stack");
10767 synchronized (this) {
10768 long ident = Binder.clearCallingIdentity();
10770 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10771 + taskId + " in stackId=" + stackId + " at position=" + position);
10772 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10773 if (task == null) {
10774 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10778 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10781 // TODO: Have the callers of this API call a separate reparent method if that is
10782 // what they intended to do vs. having this method also do reparenting.
10783 if (task.getStack() == stack) {
10784 // Change position in current stack.
10785 stack.positionChildAt(task, position);
10787 // Reparent to new stack.
10788 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10789 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10792 Binder.restoreCallingIdentity(ident);
10798 public List<StackInfo> getAllStackInfos() {
10799 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10800 long ident = Binder.clearCallingIdentity();
10802 synchronized (this) {
10803 return mStackSupervisor.getAllStackInfosLocked();
10806 Binder.restoreCallingIdentity(ident);
10811 public StackInfo getStackInfo(int stackId) {
10812 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10813 long ident = Binder.clearCallingIdentity();
10815 synchronized (this) {
10816 return mStackSupervisor.getStackInfoLocked(stackId);
10819 Binder.restoreCallingIdentity(ident);
10824 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10825 synchronized(this) {
10826 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10831 public void updateDeviceOwner(String packageName) {
10832 final int callingUid = Binder.getCallingUid();
10833 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10834 throw new SecurityException("updateDeviceOwner called from non-system process");
10836 synchronized (this) {
10837 mDeviceOwnerName = packageName;
10842 public void updateLockTaskPackages(int userId, String[] packages) {
10843 final int callingUid = Binder.getCallingUid();
10844 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10845 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10846 "updateLockTaskPackages()");
10848 synchronized (this) {
10849 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10850 Arrays.toString(packages));
10851 mLockTaskPackages.put(userId, packages);
10852 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10857 void startLockTaskModeLocked(TaskRecord task) {
10858 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10859 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10863 // When a task is locked, dismiss the pinned stack if it exists
10864 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10866 if (pinnedStack != null) {
10867 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10870 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10871 // is initiated by system after the pinning request was shown and locked mode is initiated
10872 // by an authorized app directly
10873 final int callingUid = Binder.getCallingUid();
10874 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10875 long ident = Binder.clearCallingIdentity();
10877 if (!isSystemInitiated) {
10878 task.mLockTaskUid = callingUid;
10879 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10880 // startLockTask() called by app and task mode is lockTaskModeDefault.
10881 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10882 StatusBarManagerInternal statusBarManager =
10883 LocalServices.getService(StatusBarManagerInternal.class);
10884 if (statusBarManager != null) {
10885 statusBarManager.showScreenPinningRequest(task.taskId);
10890 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10891 if (stack == null || task != stack.topTask()) {
10892 throw new IllegalArgumentException("Invalid task, not in foreground");
10895 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10897 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10898 ActivityManager.LOCK_TASK_MODE_PINNED :
10899 ActivityManager.LOCK_TASK_MODE_LOCKED,
10900 "startLockTask", true);
10902 Binder.restoreCallingIdentity(ident);
10907 public void startLockTaskModeById(int taskId) {
10908 synchronized (this) {
10909 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10910 if (task != null) {
10911 startLockTaskModeLocked(task);
10917 public void startLockTaskModeByToken(IBinder token) {
10918 synchronized (this) {
10919 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10923 final TaskRecord task = r.getTask();
10924 if (task != null) {
10925 startLockTaskModeLocked(task);
10931 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10932 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10933 // This makes inner call to look as if it was initiated by system.
10934 long ident = Binder.clearCallingIdentity();
10936 synchronized (this) {
10937 startLockTaskModeById(taskId);
10940 Binder.restoreCallingIdentity(ident);
10945 public void stopLockTaskMode() {
10946 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10947 if (lockTask == null) {
10948 // Our work here is done.
10952 final int callingUid = Binder.getCallingUid();
10953 final int lockTaskUid = lockTask.mLockTaskUid;
10954 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10955 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10959 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10960 // It is possible lockTaskMode was started by the system process because
10961 // android:lockTaskMode is set to a locking value in the application manifest
10962 // instead of the app calling startLockTaskMode. In this case
10963 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10964 // {@link TaskRecord.effectiveUid} instead. Also caller with
10965 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10966 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10967 && callingUid != lockTaskUid
10968 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10969 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10970 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10973 long ident = Binder.clearCallingIdentity();
10975 Log.d(TAG, "stopLockTaskMode");
10977 synchronized (this) {
10978 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10979 "stopLockTask", true);
10981 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10983 tm.showInCallScreen(false);
10986 Binder.restoreCallingIdentity(ident);
10991 * This API should be called by SystemUI only when user perform certain action to dismiss
10992 * lock task mode. We should only dismiss pinned lock task mode in this case.
10995 public void stopSystemLockTaskMode() throws RemoteException {
10996 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10997 stopLockTaskMode();
10999 mStackSupervisor.showLockTaskToast();
11004 public boolean isInLockTaskMode() {
11005 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11009 public int getLockTaskModeState() {
11010 synchronized (this) {
11011 return mStackSupervisor.getLockTaskModeState();
11016 public void showLockTaskEscapeMessage(IBinder token) {
11017 synchronized (this) {
11018 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11022 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11027 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11028 throws RemoteException {
11029 synchronized (this) {
11030 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11032 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11036 final long origId = Binder.clearCallingIdentity();
11038 r.setDisablePreviewScreenshots(disable);
11040 Binder.restoreCallingIdentity(origId);
11045 // =========================================================
11046 // CONTENT PROVIDERS
11047 // =========================================================
11049 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11050 List<ProviderInfo> providers = null;
11052 providers = AppGlobals.getPackageManager()
11053 .queryContentProviders(app.processName, app.uid,
11054 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11055 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11057 } catch (RemoteException ex) {
11059 if (DEBUG_MU) Slog.v(TAG_MU,
11060 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11061 int userId = app.userId;
11062 if (providers != null) {
11063 int N = providers.size();
11064 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11065 for (int i=0; i<N; i++) {
11066 // TODO: keep logic in sync with installEncryptionUnawareProviders
11068 (ProviderInfo)providers.get(i);
11069 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11070 cpi.name, cpi.flags);
11071 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11072 // This is a singleton provider, but a user besides the
11073 // default user is asking to initialize a process it runs
11074 // in... well, no, it doesn't actually run in this process,
11075 // it runs in the process of the default user. Get rid of it.
11076 providers.remove(i);
11082 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11083 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11085 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11086 mProviderMap.putProviderByClass(comp, cpr);
11088 if (DEBUG_MU) Slog.v(TAG_MU,
11089 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11090 app.pubProviders.put(cpi.name, cpr);
11091 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11092 // Don't add this if it is a platform component that is marked
11093 // to run in multiple processes, because this is actually
11094 // part of the framework so doesn't make sense to track as a
11095 // separate apk in the process.
11096 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11099 notifyPackageUse(cpi.applicationInfo.packageName,
11100 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11107 * Check if the calling UID has a possible chance at accessing the provider
11108 * at the given authority and user.
11110 public String checkContentProviderAccess(String authority, int userId) {
11111 if (userId == UserHandle.USER_ALL) {
11112 mContext.enforceCallingOrSelfPermission(
11113 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11114 userId = UserHandle.getCallingUserId();
11117 ProviderInfo cpi = null;
11119 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11120 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11121 | PackageManager.MATCH_DISABLED_COMPONENTS
11122 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11123 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11125 } catch (RemoteException ignored) {
11128 return "Failed to find provider " + authority + " for user " + userId
11129 + "; expected to find a valid ContentProvider for this authority";
11132 ProcessRecord r = null;
11133 synchronized (mPidsSelfLocked) {
11134 r = mPidsSelfLocked.get(Binder.getCallingPid());
11137 return "Failed to find PID " + Binder.getCallingPid();
11140 synchronized (this) {
11141 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11146 * Check if {@link ProcessRecord} has a possible chance at accessing the
11147 * given {@link ProviderInfo}. Final permission checking is always done
11148 * in {@link ContentProvider}.
11150 private final String checkContentProviderPermissionLocked(
11151 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11152 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11153 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11154 boolean checkedGrants = false;
11156 // Looking for cross-user grants before enforcing the typical cross-users permissions
11157 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11158 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11159 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11162 checkedGrants = true;
11164 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11165 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11166 if (userId != tmpTargetUserId) {
11167 // When we actually went to determine the final targer user ID, this ended
11168 // up different than our initial check for the authority. This is because
11169 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11170 // SELF. So we need to re-check the grants again.
11171 checkedGrants = false;
11174 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11175 cpi.applicationInfo.uid, cpi.exported)
11176 == PackageManager.PERMISSION_GRANTED) {
11179 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11180 cpi.applicationInfo.uid, cpi.exported)
11181 == PackageManager.PERMISSION_GRANTED) {
11185 PathPermission[] pps = cpi.pathPermissions;
11187 int i = pps.length;
11190 PathPermission pp = pps[i];
11191 String pprperm = pp.getReadPermission();
11192 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11193 cpi.applicationInfo.uid, cpi.exported)
11194 == PackageManager.PERMISSION_GRANTED) {
11197 String ppwperm = pp.getWritePermission();
11198 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11199 cpi.applicationInfo.uid, cpi.exported)
11200 == PackageManager.PERMISSION_GRANTED) {
11205 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11209 final String suffix;
11210 if (!cpi.exported) {
11211 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11212 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11213 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11215 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11217 final String msg = "Permission Denial: opening provider " + cpi.name
11218 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11219 + ", uid=" + callingUid + ")" + suffix;
11225 * Returns if the ContentProvider has granted a uri to callingUid
11227 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11228 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11229 if (perms != null) {
11230 for (int i=perms.size()-1; i>=0; i--) {
11231 GrantUri grantUri = perms.keyAt(i);
11232 if (grantUri.sourceUserId == userId || !checkUser) {
11233 if (matchesProvider(grantUri.uri, cpi)) {
11243 * Returns true if the uri authority is one of the authorities specified in the provider.
11245 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11246 String uriAuth = uri.getAuthority();
11247 String cpiAuth = cpi.authority;
11248 if (cpiAuth.indexOf(';') == -1) {
11249 return cpiAuth.equals(uriAuth);
11251 String[] cpiAuths = cpiAuth.split(";");
11252 int length = cpiAuths.length;
11253 for (int i = 0; i < length; i++) {
11254 if (cpiAuths[i].equals(uriAuth)) return true;
11259 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11260 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11262 for (int i=0; i<r.conProviders.size(); i++) {
11263 ContentProviderConnection conn = r.conProviders.get(i);
11264 if (conn.provider == cpr) {
11265 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11266 "Adding provider requested by "
11267 + r.processName + " from process "
11268 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11269 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11271 conn.stableCount++;
11272 conn.numStableIncs++;
11274 conn.unstableCount++;
11275 conn.numUnstableIncs++;
11280 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11282 conn.stableCount = 1;
11283 conn.numStableIncs = 1;
11285 conn.unstableCount = 1;
11286 conn.numUnstableIncs = 1;
11288 cpr.connections.add(conn);
11289 r.conProviders.add(conn);
11290 startAssociationLocked(r.uid, r.processName, r.curProcState,
11291 cpr.uid, cpr.name, cpr.info.processName);
11294 cpr.addExternalProcessHandleLocked(externalProcessToken);
11298 boolean decProviderCountLocked(ContentProviderConnection conn,
11299 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11300 if (conn != null) {
11301 cpr = conn.provider;
11302 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11303 "Removing provider requested by "
11304 + conn.client.processName + " from process "
11305 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11306 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11308 conn.stableCount--;
11310 conn.unstableCount--;
11312 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11313 cpr.connections.remove(conn);
11314 conn.client.conProviders.remove(conn);
11315 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11316 // The client is more important than last activity -- note the time this
11317 // is happening, so we keep the old provider process around a bit as last
11318 // activity to avoid thrashing it.
11319 if (cpr.proc != null) {
11320 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11323 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11328 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11332 private void checkTime(long startTime, String where) {
11333 long now = SystemClock.uptimeMillis();
11334 if ((now-startTime) > 50) {
11335 // If we are taking more than 50ms, log about it.
11336 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11340 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11342 PROC_SPACE_TERM|PROC_PARENS,
11343 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11346 private final long[] mProcessStateStatsLongs = new long[1];
11348 boolean isProcessAliveLocked(ProcessRecord proc) {
11349 if (proc.procStatFile == null) {
11350 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11352 mProcessStateStatsLongs[0] = 0;
11353 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11354 mProcessStateStatsLongs, null)) {
11355 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11358 final long state = mProcessStateStatsLongs[0];
11359 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11361 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11364 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11365 String name, IBinder token, boolean stable, int userId) {
11366 ContentProviderRecord cpr;
11367 ContentProviderConnection conn = null;
11368 ProviderInfo cpi = null;
11370 synchronized(this) {
11371 long startTime = SystemClock.uptimeMillis();
11373 ProcessRecord r = null;
11374 if (caller != null) {
11375 r = getRecordForAppLocked(caller);
11377 throw new SecurityException(
11378 "Unable to find app for caller " + caller
11379 + " (pid=" + Binder.getCallingPid()
11380 + ") when getting content provider " + name);
11384 boolean checkCrossUser = true;
11386 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11388 // First check if this content provider has been published...
11389 cpr = mProviderMap.getProviderByName(name, userId);
11390 // If that didn't work, check if it exists for user 0 and then
11391 // verify that it's a singleton provider before using it.
11392 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11393 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11396 if (isSingleton(cpi.processName, cpi.applicationInfo,
11397 cpi.name, cpi.flags)
11398 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11399 userId = UserHandle.USER_SYSTEM;
11400 checkCrossUser = false;
11408 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11409 if (providerRunning) {
11412 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11413 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11415 throw new SecurityException(msg);
11417 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11419 if (r != null && cpr.canRunHere(r)) {
11420 // This provider has been published or is in the process
11421 // of being published... but it is also allowed to run
11422 // in the caller's process, so don't make a connection
11423 // and just let the caller instantiate its own instance.
11424 ContentProviderHolder holder = cpr.newHolder(null);
11425 // don't give caller the provider object, it needs
11426 // to make its own.
11427 holder.provider = null;
11430 // Don't expose providers between normal apps and instant apps
11432 if (AppGlobals.getPackageManager()
11433 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11436 } catch (RemoteException e) {
11439 final long origId = Binder.clearCallingIdentity();
11441 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11443 // In this case the provider instance already exists, so we can
11444 // return it right away.
11445 conn = incProviderCountLocked(r, cpr, token, stable);
11446 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11447 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11448 // If this is a perceptible app accessing the provider,
11449 // make sure to count it as being accessed and thus
11450 // back up on the LRU list. This is good because
11451 // content providers are often expensive to start.
11452 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11453 updateLruProcessLocked(cpr.proc, false, null);
11454 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11458 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11459 final int verifiedAdj = cpr.proc.verifiedAdj;
11460 boolean success = updateOomAdjLocked(cpr.proc, true);
11461 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11462 // if the process has been successfully adjusted. So to reduce races with
11463 // it, we will check whether the process still exists. Note that this doesn't
11464 // completely get rid of races with LMK killing the process, but should make
11465 // them much smaller.
11466 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11469 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11470 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11471 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11472 // NOTE: there is still a race here where a signal could be
11473 // pending on the process even though we managed to update its
11474 // adj level. Not sure what to do about this, but at least
11475 // the race is now smaller.
11477 // Uh oh... it looks like the provider's process
11478 // has been killed on us. We need to wait for a new
11479 // process to be started, and make sure its death
11480 // doesn't kill our process.
11481 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11482 + " is crashing; detaching " + r);
11483 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11484 checkTime(startTime, "getContentProviderImpl: before appDied");
11485 appDiedLocked(cpr.proc);
11486 checkTime(startTime, "getContentProviderImpl: after appDied");
11488 // This wasn't the last ref our process had on
11489 // the provider... we have now been killed, bail.
11492 providerRunning = false;
11495 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11498 Binder.restoreCallingIdentity(origId);
11501 if (!providerRunning) {
11503 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11504 cpi = AppGlobals.getPackageManager().
11505 resolveContentProvider(name,
11506 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11507 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11508 } catch (RemoteException ex) {
11513 // If the provider is a singleton AND
11514 // (it's a call within the same user || the provider is a
11516 // Then allow connecting to the singleton provider
11517 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11518 cpi.name, cpi.flags)
11519 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11521 userId = UserHandle.USER_SYSTEM;
11523 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11524 checkTime(startTime, "getContentProviderImpl: got app info for user");
11527 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11528 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11530 throw new SecurityException(msg);
11532 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11534 if (!mProcessesReady
11535 && !cpi.processName.equals("system")) {
11536 // If this content provider does not run in the system
11537 // process, and the system is not yet ready to run other
11538 // processes, then fail fast instead of hanging.
11539 throw new IllegalArgumentException(
11540 "Attempt to launch content provider before system ready");
11543 // Make sure that the user who owns this provider is running. If not,
11544 // we don't want to allow it to run.
11545 if (!mUserController.isUserRunningLocked(userId, 0)) {
11546 Slog.w(TAG, "Unable to launch app "
11547 + cpi.applicationInfo.packageName + "/"
11548 + cpi.applicationInfo.uid + " for provider "
11549 + name + ": user " + userId + " is stopped");
11553 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11554 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11555 cpr = mProviderMap.getProviderByClass(comp, userId);
11556 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11557 final boolean firstClass = cpr == null;
11559 final long ident = Binder.clearCallingIdentity();
11561 // If permissions need a review before any of the app components can run,
11562 // we return no provider and launch a review activity if the calling app
11563 // is in the foreground.
11564 if (mPermissionReviewRequired) {
11565 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11571 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11572 ApplicationInfo ai =
11573 AppGlobals.getPackageManager().
11574 getApplicationInfo(
11575 cpi.applicationInfo.packageName,
11576 STOCK_PM_FLAGS, userId);
11577 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11579 Slog.w(TAG, "No package info for content provider "
11583 ai = getAppInfoForUser(ai, userId);
11584 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11585 } catch (RemoteException ex) {
11586 // pm is in same process, this will never happen.
11588 Binder.restoreCallingIdentity(ident);
11592 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11594 if (r != null && cpr.canRunHere(r)) {
11595 // If this is a multiprocess provider, then just return its
11596 // info and allow the caller to instantiate it. Only do
11597 // this if the provider is the same user as the caller's
11598 // process, or can run as root (so can be in any process).
11599 return cpr.newHolder(null);
11602 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11603 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11604 + cpr.info.name + " callers=" + Debug.getCallers(6));
11606 // This is single process, and our app is now connecting to it.
11607 // See if we are already in the process of launching this
11609 final int N = mLaunchingProviders.size();
11611 for (i = 0; i < N; i++) {
11612 if (mLaunchingProviders.get(i) == cpr) {
11617 // If the provider is not already being launched, then get it
11620 final long origId = Binder.clearCallingIdentity();
11623 // Content provider is now in use, its package can't be stopped.
11625 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11626 AppGlobals.getPackageManager().setPackageStoppedState(
11627 cpr.appInfo.packageName, false, userId);
11628 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11629 } catch (RemoteException e) {
11630 } catch (IllegalArgumentException e) {
11631 Slog.w(TAG, "Failed trying to unstop package "
11632 + cpr.appInfo.packageName + ": " + e);
11635 // Use existing process if already started
11636 checkTime(startTime, "getContentProviderImpl: looking for process record");
11637 ProcessRecord proc = getProcessRecordLocked(
11638 cpi.processName, cpr.appInfo.uid, false);
11639 if (proc != null && proc.thread != null && !proc.killed) {
11640 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11641 "Installing in existing process " + proc);
11642 if (!proc.pubProviders.containsKey(cpi.name)) {
11643 checkTime(startTime, "getContentProviderImpl: scheduling install");
11644 proc.pubProviders.put(cpi.name, cpr);
11646 proc.thread.scheduleInstallProvider(cpi);
11647 } catch (RemoteException e) {
11651 checkTime(startTime, "getContentProviderImpl: before start process");
11652 proc = startProcessLocked(cpi.processName,
11653 cpr.appInfo, false, 0, "content provider",
11654 new ComponentName(cpi.applicationInfo.packageName,
11655 cpi.name), false, false, false);
11656 checkTime(startTime, "getContentProviderImpl: after start process");
11657 if (proc == null) {
11658 Slog.w(TAG, "Unable to launch app "
11659 + cpi.applicationInfo.packageName + "/"
11660 + cpi.applicationInfo.uid + " for provider "
11661 + name + ": process is bad");
11665 cpr.launchingApp = proc;
11666 mLaunchingProviders.add(cpr);
11668 Binder.restoreCallingIdentity(origId);
11672 checkTime(startTime, "getContentProviderImpl: updating data structures");
11674 // Make sure the provider is published (the same provider class
11675 // may be published under multiple names).
11677 mProviderMap.putProviderByClass(comp, cpr);
11680 mProviderMap.putProviderByName(name, cpr);
11681 conn = incProviderCountLocked(r, cpr, token, stable);
11682 if (conn != null) {
11683 conn.waiting = true;
11686 checkTime(startTime, "getContentProviderImpl: done!");
11688 grantEphemeralAccessLocked(userId, null /*intent*/,
11689 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11692 // Wait for the provider to be published...
11693 synchronized (cpr) {
11694 while (cpr.provider == null) {
11695 if (cpr.launchingApp == null) {
11696 Slog.w(TAG, "Unable to launch app "
11697 + cpi.applicationInfo.packageName + "/"
11698 + cpi.applicationInfo.uid + " for provider "
11699 + name + ": launching app became null");
11700 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11701 UserHandle.getUserId(cpi.applicationInfo.uid),
11702 cpi.applicationInfo.packageName,
11703 cpi.applicationInfo.uid, name);
11707 if (DEBUG_MU) Slog.v(TAG_MU,
11708 "Waiting to start provider " + cpr
11709 + " launchingApp=" + cpr.launchingApp);
11710 if (conn != null) {
11711 conn.waiting = true;
11714 } catch (InterruptedException ex) {
11716 if (conn != null) {
11717 conn.waiting = false;
11722 return cpr != null ? cpr.newHolder(conn) : null;
11725 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11726 ProcessRecord r, final int userId) {
11727 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11728 cpi.packageName, userId)) {
11730 final boolean callerForeground = r == null || r.setSchedGroup
11731 != ProcessList.SCHED_GROUP_BACKGROUND;
11733 // Show a permission review UI only for starting from a foreground app
11734 if (!callerForeground) {
11735 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11736 + cpi.packageName + " requires a permissions review");
11740 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11741 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11742 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11743 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11745 if (DEBUG_PERMISSIONS_REVIEW) {
11746 Slog.i(TAG, "u" + userId + " Launching permission review "
11747 + "for package " + cpi.packageName);
11750 final UserHandle userHandle = new UserHandle(userId);
11751 mHandler.post(new Runnable() {
11753 public void run() {
11754 mContext.startActivityAsUser(intent, userHandle);
11764 PackageManagerInternal getPackageManagerInternalLocked() {
11765 if (mPackageManagerInt == null) {
11766 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11768 return mPackageManagerInt;
11772 public final ContentProviderHolder getContentProvider(
11773 IApplicationThread caller, String name, int userId, boolean stable) {
11774 enforceNotIsolatedCaller("getContentProvider");
11775 if (caller == null) {
11776 String msg = "null IApplicationThread when getting content provider "
11779 throw new SecurityException(msg);
11781 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11782 // with cross-user grant.
11783 return getContentProviderImpl(caller, name, null, stable, userId);
11786 public ContentProviderHolder getContentProviderExternal(
11787 String name, int userId, IBinder token) {
11788 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11789 "Do not have permission in call getContentProviderExternal()");
11790 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11791 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11792 return getContentProviderExternalUnchecked(name, token, userId);
11795 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11796 IBinder token, int userId) {
11797 return getContentProviderImpl(null, name, token, true, userId);
11801 * Drop a content provider from a ProcessRecord's bookkeeping
11803 public void removeContentProvider(IBinder connection, boolean stable) {
11804 enforceNotIsolatedCaller("removeContentProvider");
11805 long ident = Binder.clearCallingIdentity();
11807 synchronized (this) {
11808 ContentProviderConnection conn;
11810 conn = (ContentProviderConnection)connection;
11811 } catch (ClassCastException e) {
11812 String msg ="removeContentProvider: " + connection
11813 + " not a ContentProviderConnection";
11815 throw new IllegalArgumentException(msg);
11817 if (conn == null) {
11818 throw new NullPointerException("connection is null");
11820 if (decProviderCountLocked(conn, null, null, stable)) {
11821 updateOomAdjLocked();
11825 Binder.restoreCallingIdentity(ident);
11829 public void removeContentProviderExternal(String name, IBinder token) {
11830 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11831 "Do not have permission in call removeContentProviderExternal()");
11832 int userId = UserHandle.getCallingUserId();
11833 long ident = Binder.clearCallingIdentity();
11835 removeContentProviderExternalUnchecked(name, token, userId);
11837 Binder.restoreCallingIdentity(ident);
11841 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11842 synchronized (this) {
11843 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11845 //remove from mProvidersByClass
11846 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11850 //update content provider record entry info
11851 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11852 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11853 if (localCpr.hasExternalProcessHandles()) {
11854 if (localCpr.removeExternalProcessHandleLocked(token)) {
11855 updateOomAdjLocked();
11857 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11858 + " with no external reference for token: "
11862 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11863 + " with no external references.");
11868 public final void publishContentProviders(IApplicationThread caller,
11869 List<ContentProviderHolder> providers) {
11870 if (providers == null) {
11874 enforceNotIsolatedCaller("publishContentProviders");
11875 synchronized (this) {
11876 final ProcessRecord r = getRecordForAppLocked(caller);
11877 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11879 throw new SecurityException(
11880 "Unable to find app for caller " + caller
11881 + " (pid=" + Binder.getCallingPid()
11882 + ") when publishing content providers");
11885 final long origId = Binder.clearCallingIdentity();
11887 final int N = providers.size();
11888 for (int i = 0; i < N; i++) {
11889 ContentProviderHolder src = providers.get(i);
11890 if (src == null || src.info == null || src.provider == null) {
11893 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11894 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11896 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11897 mProviderMap.putProviderByClass(comp, dst);
11898 String names[] = dst.info.authority.split(";");
11899 for (int j = 0; j < names.length; j++) {
11900 mProviderMap.putProviderByName(names[j], dst);
11903 int launchingCount = mLaunchingProviders.size();
11905 boolean wasInLaunchingProviders = false;
11906 for (j = 0; j < launchingCount; j++) {
11907 if (mLaunchingProviders.get(j) == dst) {
11908 mLaunchingProviders.remove(j);
11909 wasInLaunchingProviders = true;
11914 if (wasInLaunchingProviders) {
11915 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11917 synchronized (dst) {
11918 dst.provider = src.provider;
11922 updateOomAdjLocked(r, true);
11923 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11924 src.info.authority);
11928 Binder.restoreCallingIdentity(origId);
11932 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11933 ContentProviderConnection conn;
11935 conn = (ContentProviderConnection)connection;
11936 } catch (ClassCastException e) {
11937 String msg ="refContentProvider: " + connection
11938 + " not a ContentProviderConnection";
11940 throw new IllegalArgumentException(msg);
11942 if (conn == null) {
11943 throw new NullPointerException("connection is null");
11946 synchronized (this) {
11948 conn.numStableIncs += stable;
11950 stable = conn.stableCount + stable;
11952 throw new IllegalStateException("stableCount < 0: " + stable);
11955 if (unstable > 0) {
11956 conn.numUnstableIncs += unstable;
11958 unstable = conn.unstableCount + unstable;
11959 if (unstable < 0) {
11960 throw new IllegalStateException("unstableCount < 0: " + unstable);
11963 if ((stable+unstable) <= 0) {
11964 throw new IllegalStateException("ref counts can't go to zero here: stable="
11965 + stable + " unstable=" + unstable);
11967 conn.stableCount = stable;
11968 conn.unstableCount = unstable;
11973 public void unstableProviderDied(IBinder connection) {
11974 ContentProviderConnection conn;
11976 conn = (ContentProviderConnection)connection;
11977 } catch (ClassCastException e) {
11978 String msg ="refContentProvider: " + connection
11979 + " not a ContentProviderConnection";
11981 throw new IllegalArgumentException(msg);
11983 if (conn == null) {
11984 throw new NullPointerException("connection is null");
11987 // Safely retrieve the content provider associated with the connection.
11988 IContentProvider provider;
11989 synchronized (this) {
11990 provider = conn.provider.provider;
11993 if (provider == null) {
11994 // Um, yeah, we're way ahead of you.
11998 // Make sure the caller is being honest with us.
11999 if (provider.asBinder().pingBinder()) {
12000 // Er, no, still looks good to us.
12001 synchronized (this) {
12002 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12003 + " says " + conn + " died, but we don't agree");
12008 // Well look at that! It's dead!
12009 synchronized (this) {
12010 if (conn.provider.provider != provider) {
12011 // But something changed... good enough.
12015 ProcessRecord proc = conn.provider.proc;
12016 if (proc == null || proc.thread == null) {
12017 // Seems like the process is already cleaned up.
12021 // As far as we're concerned, this is just like receiving a
12022 // death notification... just a bit prematurely.
12023 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12024 + ") early provider death");
12025 final long ident = Binder.clearCallingIdentity();
12027 appDiedLocked(proc);
12029 Binder.restoreCallingIdentity(ident);
12035 public void appNotRespondingViaProvider(IBinder connection) {
12036 enforceCallingPermission(
12037 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12039 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12040 if (conn == null) {
12041 Slog.w(TAG, "ContentProviderConnection is null");
12045 final ProcessRecord host = conn.provider.proc;
12046 if (host == null) {
12047 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12051 mHandler.post(new Runnable() {
12053 public void run() {
12054 mAppErrors.appNotResponding(host, null, null, false,
12055 "ContentProvider not responding");
12060 public final void installSystemProviders() {
12061 List<ProviderInfo> providers;
12062 synchronized (this) {
12063 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12064 providers = generateApplicationProvidersLocked(app);
12065 if (providers != null) {
12066 for (int i=providers.size()-1; i>=0; i--) {
12067 ProviderInfo pi = (ProviderInfo)providers.get(i);
12068 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12069 Slog.w(TAG, "Not installing system proc provider " + pi.name
12070 + ": not system .apk");
12071 providers.remove(i);
12076 if (providers != null) {
12077 mSystemThread.installSystemProviders(providers);
12080 mConstants.start(mContext.getContentResolver());
12081 mCoreSettingsObserver = new CoreSettingsObserver(this);
12082 mFontScaleSettingObserver = new FontScaleSettingObserver();
12084 // Now that the settings provider is published we can consider sending
12085 // in a rescue party.
12086 RescueParty.onSettingsProviderPublished(mContext);
12088 //mUsageStatsService.monitorPackages();
12091 private void startPersistentApps(int matchFlags) {
12092 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12094 synchronized (this) {
12096 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12097 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12098 for (ApplicationInfo app : apps) {
12099 if (!"android".equals(app.packageName)) {
12100 addAppLocked(app, null, false, null /* ABI override */);
12103 } catch (RemoteException ex) {
12109 * When a user is unlocked, we need to install encryption-unaware providers
12110 * belonging to any running apps.
12112 private void installEncryptionUnawareProviders(int userId) {
12113 // We're only interested in providers that are encryption unaware, and
12114 // we don't care about uninstalled apps, since there's no way they're
12115 // running at this point.
12116 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12118 synchronized (this) {
12119 final int NP = mProcessNames.getMap().size();
12120 for (int ip = 0; ip < NP; ip++) {
12121 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12122 final int NA = apps.size();
12123 for (int ia = 0; ia < NA; ia++) {
12124 final ProcessRecord app = apps.valueAt(ia);
12125 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12127 final int NG = app.pkgList.size();
12128 for (int ig = 0; ig < NG; ig++) {
12130 final String pkgName = app.pkgList.keyAt(ig);
12131 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12132 .getPackageInfo(pkgName, matchFlags, userId);
12133 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12134 for (ProviderInfo pi : pkgInfo.providers) {
12135 // TODO: keep in sync with generateApplicationProvidersLocked
12136 final boolean processMatch = Objects.equals(pi.processName,
12137 app.processName) || pi.multiprocess;
12138 final boolean userMatch = isSingleton(pi.processName,
12139 pi.applicationInfo, pi.name, pi.flags)
12140 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12141 if (processMatch && userMatch) {
12142 Log.v(TAG, "Installing " + pi);
12143 app.thread.scheduleInstallProvider(pi);
12145 Log.v(TAG, "Skipping " + pi);
12149 } catch (RemoteException ignored) {
12158 * Allows apps to retrieve the MIME type of a URI.
12159 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12160 * users, then it does not need permission to access the ContentProvider.
12161 * Either, it needs cross-user uri grants.
12163 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12165 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12166 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12168 public String getProviderMimeType(Uri uri, int userId) {
12169 enforceNotIsolatedCaller("getProviderMimeType");
12170 final String name = uri.getAuthority();
12171 int callingUid = Binder.getCallingUid();
12172 int callingPid = Binder.getCallingPid();
12174 boolean clearedIdentity = false;
12175 synchronized (this) {
12176 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12178 if (canClearIdentity(callingPid, callingUid, userId)) {
12179 clearedIdentity = true;
12180 ident = Binder.clearCallingIdentity();
12182 ContentProviderHolder holder = null;
12184 holder = getContentProviderExternalUnchecked(name, null, userId);
12185 if (holder != null) {
12186 return holder.provider.getType(uri);
12188 } catch (RemoteException e) {
12189 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12191 } catch (Exception e) {
12192 Log.w(TAG, "Exception while determining type of " + uri, e);
12195 // We need to clear the identity to call removeContentProviderExternalUnchecked
12196 if (!clearedIdentity) {
12197 ident = Binder.clearCallingIdentity();
12200 if (holder != null) {
12201 removeContentProviderExternalUnchecked(name, null, userId);
12204 Binder.restoreCallingIdentity(ident);
12211 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12212 if (UserHandle.getUserId(callingUid) == userId) {
12215 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12216 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12217 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12218 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12224 // =========================================================
12225 // GLOBAL MANAGEMENT
12226 // =========================================================
12228 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12229 boolean isolated, int isolatedUid) {
12230 String proc = customProcess != null ? customProcess : info.processName;
12231 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12232 final int userId = UserHandle.getUserId(info.uid);
12233 int uid = info.uid;
12235 if (isolatedUid == 0) {
12236 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12238 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12239 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12240 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12242 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12243 mNextIsolatedProcessUid++;
12244 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12245 // No process for this uid, use it.
12249 if (stepsLeft <= 0) {
12254 // Special case for startIsolatedProcess (internal only), where
12255 // the uid of the isolated process is specified by the caller.
12258 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12260 // Register the isolated UID with this application so BatteryStats knows to
12261 // attribute resource usage to the application.
12263 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12264 // about the process state of the isolated UID *before* it is registered with the
12265 // owning application.
12266 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12268 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12269 if (!mBooted && !mBooting
12270 && userId == UserHandle.USER_SYSTEM
12271 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12272 r.persistent = true;
12273 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12275 addProcessNameLocked(r);
12279 private boolean uidOnBackgroundWhitelist(final int uid) {
12280 final int appId = UserHandle.getAppId(uid);
12281 final int[] whitelist = mBackgroundAppIdWhitelist;
12282 final int N = whitelist.length;
12283 for (int i = 0; i < N; i++) {
12284 if (appId == whitelist[i]) {
12292 public void backgroundWhitelistUid(final int uid) {
12293 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12294 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12297 if (DEBUG_BACKGROUND_CHECK) {
12298 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12300 synchronized (this) {
12301 final int N = mBackgroundAppIdWhitelist.length;
12302 int[] newList = new int[N+1];
12303 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12304 newList[N] = UserHandle.getAppId(uid);
12305 mBackgroundAppIdWhitelist = newList;
12309 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12310 String abiOverride) {
12313 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12320 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12321 updateLruProcessLocked(app, false, null);
12322 updateOomAdjLocked();
12325 // This package really, really can not be stopped.
12327 AppGlobals.getPackageManager().setPackageStoppedState(
12328 info.packageName, false, UserHandle.getUserId(app.uid));
12329 } catch (RemoteException e) {
12330 } catch (IllegalArgumentException e) {
12331 Slog.w(TAG, "Failed trying to unstop package "
12332 + info.packageName + ": " + e);
12335 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12336 app.persistent = true;
12337 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12339 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12340 mPersistentStartingProcesses.add(app);
12341 startProcessLocked(app, "added application",
12342 customProcess != null ? customProcess : app.processName, abiOverride,
12343 null /* entryPoint */, null /* entryPointArgs */);
12349 public void unhandledBack() {
12350 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12351 "unhandledBack()");
12353 synchronized(this) {
12354 final long origId = Binder.clearCallingIdentity();
12356 getFocusedStack().unhandledBackLocked();
12358 Binder.restoreCallingIdentity(origId);
12363 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12364 enforceNotIsolatedCaller("openContentUri");
12365 final int userId = UserHandle.getCallingUserId();
12366 final Uri uri = Uri.parse(uriString);
12367 String name = uri.getAuthority();
12368 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12369 ParcelFileDescriptor pfd = null;
12371 // We record the binder invoker's uid in thread-local storage before
12372 // going to the content provider to open the file. Later, in the code
12373 // that handles all permissions checks, we look for this uid and use
12374 // that rather than the Activity Manager's own uid. The effect is that
12375 // we do the check against the caller's permissions even though it looks
12376 // to the content provider like the Activity Manager itself is making
12378 Binder token = new Binder();
12379 sCallerIdentity.set(new Identity(
12380 token, Binder.getCallingPid(), Binder.getCallingUid()));
12382 pfd = cph.provider.openFile(null, uri, "r", null, token);
12383 } catch (FileNotFoundException e) {
12384 // do nothing; pfd will be returned null
12386 // Ensure that whatever happens, we clean up the identity state
12387 sCallerIdentity.remove();
12388 // Ensure we're done with the provider.
12389 removeContentProviderExternalUnchecked(name, null, userId);
12392 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12397 // Actually is sleeping or shutting down or whatever else in the future
12398 // is an inactive state.
12399 boolean isSleepingOrShuttingDownLocked() {
12400 return isSleepingLocked() || mShuttingDown;
12403 boolean isShuttingDownLocked() {
12404 return mShuttingDown;
12407 boolean isSleepingLocked() {
12411 void onWakefulnessChanged(int wakefulness) {
12412 synchronized(this) {
12413 mWakefulness = wakefulness;
12414 updateSleepIfNeededLocked();
12418 void finishRunningVoiceLocked() {
12419 if (mRunningVoice != null) {
12420 mRunningVoice = null;
12421 mVoiceWakeLock.release();
12422 updateSleepIfNeededLocked();
12426 void startTimeTrackingFocusedActivityLocked() {
12427 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12428 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12429 mCurAppTimeTracker.start(resumedActivity.packageName);
12433 void updateSleepIfNeededLocked() {
12434 final boolean shouldSleep = shouldSleepLocked();
12435 if (mSleeping && !shouldSleep) {
12437 startTimeTrackingFocusedActivityLocked();
12438 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12439 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12440 sendNotifyVrManagerOfSleepState(false);
12441 updateOomAdjLocked();
12442 } else if (!mSleeping && shouldSleep) {
12444 if (mCurAppTimeTracker != null) {
12445 mCurAppTimeTracker.stop();
12447 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12448 mStackSupervisor.goingToSleepLocked();
12449 sendNotifyVrManagerOfSleepState(true);
12450 updateOomAdjLocked();
12452 // Initialize the wake times of all processes.
12453 checkExcessivePowerUsageLocked(false);
12454 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12455 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12456 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12459 // Also update state in a special way for running foreground services UI.
12460 switch (mWakefulness) {
12461 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12462 case PowerManagerInternal.WAKEFULNESS_DREAMING:
12463 case PowerManagerInternal.WAKEFULNESS_DOZING:
12464 mServices.updateScreenStateLocked(false);
12466 case PowerManagerInternal.WAKEFULNESS_AWAKE:
12468 mServices.updateScreenStateLocked(true);
12473 private boolean shouldSleepLocked() {
12474 // Resume applications while running a voice interactor.
12475 if (mRunningVoice != null) {
12479 // TODO: Transform the lock screen state into a sleep token instead.
12480 switch (mWakefulness) {
12481 case PowerManagerInternal.WAKEFULNESS_AWAKE:
12482 case PowerManagerInternal.WAKEFULNESS_DREAMING:
12483 // Pause applications whenever the lock screen is shown or any sleep
12484 // tokens have been acquired.
12485 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12486 case PowerManagerInternal.WAKEFULNESS_DOZING:
12487 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12489 // If we're asleep then pause applications unconditionally.
12494 /** Pokes the task persister. */
12495 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12496 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12500 * Notifies all listeners when the pinned stack animation starts.
12503 public void notifyPinnedStackAnimationStarted() {
12504 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12508 * Notifies all listeners when the pinned stack animation ends.
12511 public void notifyPinnedStackAnimationEnded() {
12512 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12516 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12517 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12521 public boolean shutdown(int timeout) {
12522 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12523 != PackageManager.PERMISSION_GRANTED) {
12524 throw new SecurityException("Requires permission "
12525 + android.Manifest.permission.SHUTDOWN);
12528 boolean timedout = false;
12530 synchronized(this) {
12531 mShuttingDown = true;
12532 updateEventDispatchingLocked();
12533 timedout = mStackSupervisor.shutdownLocked(timeout);
12536 mAppOpsService.shutdown();
12537 if (mUsageStatsService != null) {
12538 mUsageStatsService.prepareShutdown();
12540 mBatteryStatsService.shutdown();
12541 synchronized (this) {
12542 mProcessStats.shutdownLocked();
12543 notifyTaskPersisterLocked(null, true);
12549 public final void activitySlept(IBinder token) {
12550 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12552 final long origId = Binder.clearCallingIdentity();
12554 synchronized (this) {
12555 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12557 mStackSupervisor.activitySleptLocked(r);
12561 Binder.restoreCallingIdentity(origId);
12564 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12565 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12566 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12567 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12568 boolean wasRunningVoice = mRunningVoice != null;
12569 mRunningVoice = session;
12570 if (!wasRunningVoice) {
12571 mVoiceWakeLock.acquire();
12572 updateSleepIfNeededLocked();
12577 private void updateEventDispatchingLocked() {
12578 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12582 public void setLockScreenShown(boolean showing) {
12583 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12584 != PackageManager.PERMISSION_GRANTED) {
12585 throw new SecurityException("Requires permission "
12586 + android.Manifest.permission.DEVICE_POWER);
12589 synchronized(this) {
12590 long ident = Binder.clearCallingIdentity();
12592 mKeyguardController.setKeyguardShown(showing);
12594 Binder.restoreCallingIdentity(ident);
12600 public void notifyLockedProfile(@UserIdInt int userId) {
12602 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12603 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12605 } catch (RemoteException ex) {
12606 throw new SecurityException("Fail to check is caller a privileged app", ex);
12609 synchronized (this) {
12610 final long ident = Binder.clearCallingIdentity();
12612 if (mUserController.shouldConfirmCredentials(userId)) {
12613 if (mKeyguardController.isKeyguardLocked()) {
12614 // Showing launcher to avoid user entering credential twice.
12615 final int currentUserId = mUserController.getCurrentUserIdLocked();
12616 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12618 mStackSupervisor.lockAllProfileTasks(userId);
12621 Binder.restoreCallingIdentity(ident);
12627 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12628 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12629 synchronized (this) {
12630 final long ident = Binder.clearCallingIdentity();
12632 mActivityStarter.startConfirmCredentialIntent(intent, options);
12634 Binder.restoreCallingIdentity(ident);
12640 public void stopAppSwitches() {
12641 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12642 != PackageManager.PERMISSION_GRANTED) {
12643 throw new SecurityException("viewquires permission "
12644 + android.Manifest.permission.STOP_APP_SWITCHES);
12647 synchronized(this) {
12648 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12649 + APP_SWITCH_DELAY_TIME;
12650 mDidAppSwitch = false;
12651 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12652 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12653 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12657 public void resumeAppSwitches() {
12658 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12659 != PackageManager.PERMISSION_GRANTED) {
12660 throw new SecurityException("Requires permission "
12661 + android.Manifest.permission.STOP_APP_SWITCHES);
12664 synchronized(this) {
12665 // Note that we don't execute any pending app switches... we will
12666 // let those wait until either the timeout, or the next start
12667 // activity request.
12668 mAppSwitchesAllowedTime = 0;
12672 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12673 int callingPid, int callingUid, String name) {
12674 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12678 int perm = checkComponentPermission(
12679 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12680 sourceUid, -1, true);
12681 if (perm == PackageManager.PERMISSION_GRANTED) {
12685 // If the actual IPC caller is different from the logical source, then
12686 // also see if they are allowed to control app switches.
12687 if (callingUid != -1 && callingUid != sourceUid) {
12688 perm = checkComponentPermission(
12689 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12690 callingUid, -1, true);
12691 if (perm == PackageManager.PERMISSION_GRANTED) {
12696 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12700 public void setDebugApp(String packageName, boolean waitForDebugger,
12701 boolean persistent) {
12702 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12705 long ident = Binder.clearCallingIdentity();
12707 // Note that this is not really thread safe if there are multiple
12708 // callers into it at the same time, but that's not a situation we
12711 final ContentResolver resolver = mContext.getContentResolver();
12712 Settings.Global.putString(
12713 resolver, Settings.Global.DEBUG_APP,
12715 Settings.Global.putInt(
12716 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12717 waitForDebugger ? 1 : 0);
12720 synchronized (this) {
12722 mOrigDebugApp = mDebugApp;
12723 mOrigWaitForDebugger = mWaitForDebugger;
12725 mDebugApp = packageName;
12726 mWaitForDebugger = waitForDebugger;
12727 mDebugTransient = !persistent;
12728 if (packageName != null) {
12729 forceStopPackageLocked(packageName, -1, false, false, true, true,
12730 false, UserHandle.USER_ALL, "set debug app");
12734 Binder.restoreCallingIdentity(ident);
12738 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12739 synchronized (this) {
12740 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12741 if (!isDebuggable) {
12742 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12743 throw new SecurityException("Process not debuggable: " + app.packageName);
12747 mTrackAllocationApp = processName;
12751 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12752 synchronized (this) {
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 mProfileApp = processName;
12760 mProfileFile = profilerInfo.profileFile;
12761 if (mProfileFd != null) {
12763 mProfileFd.close();
12764 } catch (IOException e) {
12768 mProfileFd = profilerInfo.profileFd;
12769 mSamplingInterval = profilerInfo.samplingInterval;
12770 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12771 mStreamingOutput = profilerInfo.streamingOutput;
12776 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12777 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12778 if (!isDebuggable) {
12779 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12780 throw new SecurityException("Process not debuggable: " + app.packageName);
12783 mNativeDebuggingApp = processName;
12787 public void setAlwaysFinish(boolean enabled) {
12788 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12789 "setAlwaysFinish()");
12791 long ident = Binder.clearCallingIdentity();
12793 Settings.Global.putInt(
12794 mContext.getContentResolver(),
12795 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12797 synchronized (this) {
12798 mAlwaysFinishActivities = enabled;
12801 Binder.restoreCallingIdentity(ident);
12806 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12807 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12808 "setActivityController()");
12809 synchronized (this) {
12810 mController = controller;
12811 mControllerIsAMonkey = imAMonkey;
12812 Watchdog.getInstance().setActivityController(controller);
12817 public void setUserIsMonkey(boolean userIsMonkey) {
12818 synchronized (this) {
12819 synchronized (mPidsSelfLocked) {
12820 final int callingPid = Binder.getCallingPid();
12821 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12822 if (proc == null) {
12823 throw new SecurityException("Unknown process: " + callingPid);
12825 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12826 throw new SecurityException("Only an instrumentation process "
12827 + "with a UiAutomation can call setUserIsMonkey");
12830 mUserIsMonkey = userIsMonkey;
12835 public boolean isUserAMonkey() {
12836 synchronized (this) {
12837 // If there is a controller also implies the user is a monkey.
12838 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12843 * @deprecated This method is only used by a few internal components and it will soon be
12844 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12845 * No new code should be calling it.
12849 public void requestBugReport(int bugreportType) {
12850 String extraOptions = null;
12851 switch (bugreportType) {
12852 case ActivityManager.BUGREPORT_OPTION_FULL:
12853 // Default options.
12855 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12856 extraOptions = "bugreportplus";
12858 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12859 extraOptions = "bugreportremote";
12861 case ActivityManager.BUGREPORT_OPTION_WEAR:
12862 extraOptions = "bugreportwear";
12864 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12865 extraOptions = "bugreporttelephony";
12868 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12871 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12872 if (extraOptions != null) {
12873 SystemProperties.set("dumpstate.options", extraOptions);
12875 SystemProperties.set("ctl.start", "bugreport");
12879 * @deprecated This method is only used by a few internal components and it will soon be
12880 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12881 * No new code should be calling it.
12885 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12887 if (!TextUtils.isEmpty(shareTitle)) {
12888 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12889 String errorStr = "shareTitle should be less than " +
12890 MAX_BUGREPORT_TITLE_SIZE + " characters";
12891 throw new IllegalArgumentException(errorStr);
12893 if (!TextUtils.isEmpty(shareDescription)) {
12896 length = shareDescription.getBytes("UTF-8").length;
12897 } catch (UnsupportedEncodingException e) {
12898 String errorStr = "shareDescription: UnsupportedEncodingException";
12899 throw new IllegalArgumentException(errorStr);
12901 if (length > SystemProperties.PROP_VALUE_MAX) {
12902 String errorStr = "shareTitle should be less than " +
12903 SystemProperties.PROP_VALUE_MAX + " bytes";
12904 throw new IllegalArgumentException(errorStr);
12906 SystemProperties.set("dumpstate.options.description", shareDescription);
12909 SystemProperties.set("dumpstate.options.title", shareTitle);
12913 Slog.d(TAG, "Bugreport notification title " + shareTitle
12914 + " description " + shareDescription);
12915 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12918 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12919 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12922 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12923 if (r != null && (r.instr != null || r.usingWrapper)) {
12924 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12926 return KEY_DISPATCHING_TIMEOUT;
12930 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12931 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12932 != PackageManager.PERMISSION_GRANTED) {
12933 throw new SecurityException("Requires permission "
12934 + android.Manifest.permission.FILTER_EVENTS);
12936 ProcessRecord proc;
12938 synchronized (this) {
12939 synchronized (mPidsSelfLocked) {
12940 proc = mPidsSelfLocked.get(pid);
12942 timeout = getInputDispatchingTimeoutLocked(proc);
12945 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12953 * Handle input dispatching timeouts.
12954 * Returns whether input dispatching should be aborted or not.
12956 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12957 final ActivityRecord activity, final ActivityRecord parent,
12958 final boolean aboveSystem, String reason) {
12959 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12960 != PackageManager.PERMISSION_GRANTED) {
12961 throw new SecurityException("Requires permission "
12962 + android.Manifest.permission.FILTER_EVENTS);
12965 final String annotation;
12966 if (reason == null) {
12967 annotation = "Input dispatching timed out";
12969 annotation = "Input dispatching timed out (" + reason + ")";
12972 if (proc != null) {
12973 synchronized (this) {
12974 if (proc.debugging) {
12978 if (proc.instr != null) {
12979 Bundle info = new Bundle();
12980 info.putString("shortMsg", "keyDispatchingTimedOut");
12981 info.putString("longMsg", annotation);
12982 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12986 mHandler.post(new Runnable() {
12988 public void run() {
12989 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12998 public Bundle getAssistContextExtras(int requestType) {
12999 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13000 null, null, true /* focused */, true /* newSessionId */,
13001 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13005 synchronized (pae) {
13006 while (!pae.haveResult) {
13009 } catch (InterruptedException e) {
13013 synchronized (this) {
13014 buildAssistBundleLocked(pae, pae.result);
13015 mPendingAssistExtras.remove(pae);
13016 mUiHandler.removeCallbacks(pae);
13022 public boolean isAssistDataAllowedOnCurrentActivity() {
13024 synchronized (this) {
13025 final ActivityStack focusedStack = getFocusedStack();
13026 if (focusedStack == null || focusedStack.isAssistantStack()) {
13030 final ActivityRecord activity = focusedStack.topActivity();
13031 if (activity == null) {
13034 userId = activity.userId;
13036 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13037 Context.DEVICE_POLICY_SERVICE);
13038 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13042 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13043 long ident = Binder.clearCallingIdentity();
13045 synchronized (this) {
13046 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13047 ActivityRecord top = getFocusedStack().topActivity();
13048 if (top != caller) {
13049 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13050 + " is not current top " + top);
13053 if (!top.nowVisible) {
13054 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13055 + " is not visible");
13059 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13062 Binder.restoreCallingIdentity(ident);
13067 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13068 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13069 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13070 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13071 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13075 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13076 IBinder activityToken, int flags) {
13077 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13078 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13079 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13082 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13083 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13084 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13086 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13087 "enqueueAssistContext()");
13089 synchronized (this) {
13090 ActivityRecord activity = getFocusedStack().topActivity();
13091 if (activity == null) {
13092 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13095 if (activity.app == null || activity.app.thread == null) {
13096 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13100 if (activityToken != null) {
13101 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13102 if (activity != caller) {
13103 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13104 + " is not current top " + activity);
13109 activity = ActivityRecord.forTokenLocked(activityToken);
13110 if (activity == null) {
13111 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13112 + " couldn't be found");
13117 PendingAssistExtras pae;
13118 Bundle extras = new Bundle();
13119 if (args != null) {
13120 extras.putAll(args);
13122 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13123 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13125 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13127 pae.isHome = activity.isHomeActivity();
13129 // Increment the sessionId if necessary
13130 if (newSessionId) {
13134 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13135 mViSessionId, flags);
13136 mPendingAssistExtras.add(pae);
13137 mUiHandler.postDelayed(pae, timeout);
13138 } catch (RemoteException e) {
13139 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13146 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13147 IResultReceiver receiver;
13148 synchronized (this) {
13149 mPendingAssistExtras.remove(pae);
13150 receiver = pae.receiver;
13152 if (receiver != null) {
13153 // Caller wants result sent back to them.
13154 Bundle sendBundle = new Bundle();
13155 // At least return the receiver extras
13156 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13157 pae.receiverExtras);
13159 pae.receiver.send(0, sendBundle);
13160 } catch (RemoteException e) {
13165 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13166 if (result != null) {
13167 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13169 if (pae.hint != null) {
13170 pae.extras.putBoolean(pae.hint, true);
13174 /** Called from an app when assist data is ready. */
13176 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13177 AssistContent content, Uri referrer) {
13178 PendingAssistExtras pae = (PendingAssistExtras)token;
13179 synchronized (pae) {
13180 pae.result = extras;
13181 pae.structure = structure;
13182 pae.content = content;
13183 if (referrer != null) {
13184 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13186 if (structure != null) {
13187 structure.setHomeActivity(pae.isHome);
13189 pae.haveResult = true;
13191 if (pae.intent == null && pae.receiver == null) {
13192 // Caller is just waiting for the result.
13197 // We are now ready to launch the assist activity.
13198 IResultReceiver sendReceiver = null;
13199 Bundle sendBundle = null;
13200 synchronized (this) {
13201 buildAssistBundleLocked(pae, extras);
13202 boolean exists = mPendingAssistExtras.remove(pae);
13203 mUiHandler.removeCallbacks(pae);
13208 if ((sendReceiver=pae.receiver) != null) {
13209 // Caller wants result sent back to them.
13210 sendBundle = new Bundle();
13211 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13212 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13213 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13214 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13215 pae.receiverExtras);
13218 if (sendReceiver != null) {
13220 sendReceiver.send(0, sendBundle);
13221 } catch (RemoteException e) {
13226 long ident = Binder.clearCallingIdentity();
13228 pae.intent.replaceExtras(pae.extras);
13229 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13230 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13231 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13232 closeSystemDialogs("assist");
13234 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13235 } catch (ActivityNotFoundException e) {
13236 Slog.w(TAG, "No activity to handle assist action.", e);
13239 Binder.restoreCallingIdentity(ident);
13243 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13245 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13246 true /* focused */, true /* newSessionId */, userHandle, args,
13247 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13250 public void registerProcessObserver(IProcessObserver observer) {
13251 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13252 "registerProcessObserver()");
13253 synchronized (this) {
13254 mProcessObservers.register(observer);
13259 public void unregisterProcessObserver(IProcessObserver observer) {
13260 synchronized (this) {
13261 mProcessObservers.unregister(observer);
13266 public int getUidProcessState(int uid, String callingPackage) {
13267 if (!hasUsageStatsPermission(callingPackage)) {
13268 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13269 "getUidProcessState");
13272 synchronized (this) {
13273 UidRecord uidRec = mActiveUids.get(uid);
13274 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13279 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13280 String callingPackage) {
13281 if (!hasUsageStatsPermission(callingPackage)) {
13282 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13283 "registerUidObserver");
13285 synchronized (this) {
13286 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13287 callingPackage, which, cutpoint));
13292 public void unregisterUidObserver(IUidObserver observer) {
13293 synchronized (this) {
13294 mUidObservers.unregister(observer);
13299 public boolean convertFromTranslucent(IBinder token) {
13300 final long origId = Binder.clearCallingIdentity();
13302 synchronized (this) {
13303 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13307 final boolean translucentChanged = r.changeWindowTranslucency(true);
13308 if (translucentChanged) {
13309 r.getStack().releaseBackgroundResources(r);
13310 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13312 mWindowManager.setAppFullscreen(token, true);
13313 return translucentChanged;
13316 Binder.restoreCallingIdentity(origId);
13321 public boolean convertToTranslucent(IBinder token, Bundle options) {
13322 final long origId = Binder.clearCallingIdentity();
13324 synchronized (this) {
13325 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13329 final TaskRecord task = r.getTask();
13330 int index = task.mActivities.lastIndexOf(r);
13332 ActivityRecord under = task.mActivities.get(index - 1);
13333 under.returningOptions = ActivityOptions.fromBundle(options);
13335 final boolean translucentChanged = r.changeWindowTranslucency(false);
13336 if (translucentChanged) {
13337 r.getStack().convertActivityToTranslucent(r);
13339 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13340 mWindowManager.setAppFullscreen(token, false);
13341 return translucentChanged;
13344 Binder.restoreCallingIdentity(origId);
13349 public boolean requestVisibleBehind(IBinder token, boolean visible) {
13350 final long origId = Binder.clearCallingIdentity();
13352 synchronized (this) {
13353 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13355 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13360 Binder.restoreCallingIdentity(origId);
13365 public boolean isBackgroundVisibleBehind(IBinder token) {
13366 final long origId = Binder.clearCallingIdentity();
13368 synchronized (this) {
13369 final ActivityStack stack = ActivityRecord.getStackLocked(token);
13370 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13371 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13372 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13376 Binder.restoreCallingIdentity(origId);
13381 public Bundle getActivityOptions(IBinder token) {
13382 final long origId = Binder.clearCallingIdentity();
13384 synchronized (this) {
13385 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13387 final ActivityOptions activityOptions = r.pendingOptions;
13388 return activityOptions == null ? null : activityOptions.toBundle();
13393 Binder.restoreCallingIdentity(origId);
13398 public void setImmersive(IBinder token, boolean immersive) {
13399 synchronized(this) {
13400 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13402 throw new IllegalArgumentException();
13404 r.immersive = immersive;
13406 // update associated state if we're frontmost
13407 if (r == mStackSupervisor.getResumedActivityLocked()) {
13408 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13409 applyUpdateLockStateLocked(r);
13415 public boolean isImmersive(IBinder token) {
13416 synchronized (this) {
13417 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13419 throw new IllegalArgumentException();
13421 return r.immersive;
13426 public void setVrThread(int tid) {
13427 enforceSystemHasVrFeature();
13428 synchronized (this) {
13429 synchronized (mPidsSelfLocked) {
13430 final int pid = Binder.getCallingPid();
13431 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13432 mVrController.setVrThreadLocked(tid, pid, proc);
13438 public void setPersistentVrThread(int tid) {
13439 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13440 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13441 + Binder.getCallingPid()
13442 + ", uid=" + Binder.getCallingUid()
13443 + " requires " + permission.RESTRICTED_VR_ACCESS;
13445 throw new SecurityException(msg);
13447 enforceSystemHasVrFeature();
13448 synchronized (this) {
13449 synchronized (mPidsSelfLocked) {
13450 final int pid = Binder.getCallingPid();
13451 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13452 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13458 * Schedule the given thread a normal scheduling priority.
13460 * @param newTid the tid of the thread to adjust the scheduling of.
13461 * @param suppressLogs {@code true} if any error logging should be disabled.
13463 * @return {@code true} if this succeeded.
13465 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13467 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13469 } catch (IllegalArgumentException e) {
13470 if (!suppressLogs) {
13471 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13478 * Schedule the given thread an FIFO scheduling priority.
13480 * @param newTid the tid of the thread to adjust the scheduling of.
13481 * @param suppressLogs {@code true} if any error logging should be disabled.
13483 * @return {@code true} if this succeeded.
13485 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13487 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13489 } catch (IllegalArgumentException e) {
13490 if (!suppressLogs) {
13491 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13498 * Check that we have the features required for VR-related API calls, and throw an exception if
13501 private void enforceSystemHasVrFeature() {
13502 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13503 throw new UnsupportedOperationException("VR mode not supported on this device!");
13508 public void setRenderThread(int tid) {
13509 synchronized (this) {
13510 ProcessRecord proc;
13511 int pid = Binder.getCallingPid();
13512 if (pid == Process.myPid()) {
13513 demoteSystemServerRenderThread(tid);
13516 synchronized (mPidsSelfLocked) {
13517 proc = mPidsSelfLocked.get(pid);
13518 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13519 // ensure the tid belongs to the process
13520 if (!isThreadInProcess(pid, tid)) {
13521 throw new IllegalArgumentException(
13522 "Render thread does not belong to process");
13524 proc.renderThreadTid = tid;
13525 if (DEBUG_OOM_ADJ) {
13526 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13528 // promote to FIFO now
13529 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13530 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13531 if (mUseFifoUiScheduling) {
13532 setThreadScheduler(proc.renderThreadTid,
13533 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13535 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13539 if (DEBUG_OOM_ADJ) {
13540 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13541 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13542 mUseFifoUiScheduling);
13550 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13551 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13553 * @param tid the tid of the RenderThread
13555 private void demoteSystemServerRenderThread(int tid) {
13556 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13560 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13561 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13562 throw new UnsupportedOperationException("VR mode not supported on this device!");
13565 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13568 synchronized (this) {
13569 r = ActivityRecord.isInStackLocked(token);
13573 throw new IllegalArgumentException();
13577 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13578 VrManagerInternal.NO_ERROR) {
13582 synchronized(this) {
13583 r.requestedVrComponent = (enabled) ? packageName : null;
13585 // Update associated state if this activity is currently focused
13586 if (r == mStackSupervisor.getResumedActivityLocked()) {
13587 applyUpdateVrModeLocked(r);
13594 public boolean isVrModePackageEnabled(ComponentName packageName) {
13595 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13596 throw new UnsupportedOperationException("VR mode not supported on this device!");
13599 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13601 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13602 VrManagerInternal.NO_ERROR;
13605 public boolean isTopActivityImmersive() {
13606 enforceNotIsolatedCaller("startActivity");
13607 synchronized (this) {
13608 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13609 return (r != null) ? r.immersive : false;
13614 * @return whether the system should disable UI modes incompatible with VR mode.
13616 boolean shouldDisableNonVrUiLocked() {
13617 return mVrController.shouldDisableNonVrUiLocked();
13621 public boolean isTopOfTask(IBinder token) {
13622 synchronized (this) {
13623 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13625 throw new IllegalArgumentException();
13627 return r.getTask().getTopActivity() == r;
13632 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13633 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13634 String msg = "Permission Denial: setHasTopUi() from pid="
13635 + Binder.getCallingPid()
13636 + ", uid=" + Binder.getCallingUid()
13637 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13639 throw new SecurityException(msg);
13641 final int pid = Binder.getCallingPid();
13642 final long origId = Binder.clearCallingIdentity();
13644 synchronized (this) {
13645 boolean changed = false;
13647 synchronized (mPidsSelfLocked) {
13648 pr = mPidsSelfLocked.get(pid);
13650 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13653 if (pr.hasTopUi != hasTopUi) {
13654 if (DEBUG_OOM_ADJ) {
13655 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13657 pr.hasTopUi = hasTopUi;
13662 updateOomAdjLocked(pr, true);
13666 Binder.restoreCallingIdentity(origId);
13670 public final void enterSafeMode() {
13671 synchronized(this) {
13672 // It only makes sense to do this before the system is ready
13673 // and started launching other packages.
13674 if (!mSystemReady) {
13676 AppGlobals.getPackageManager().enterSafeMode();
13677 } catch (RemoteException e) {
13685 public final void showSafeModeOverlay() {
13686 View v = LayoutInflater.from(mContext).inflate(
13687 com.android.internal.R.layout.safe_mode, null);
13688 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13689 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13690 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13691 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13692 lp.gravity = Gravity.BOTTOM | Gravity.START;
13693 lp.format = v.getBackground().getOpacity();
13694 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13695 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13696 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13697 ((WindowManager)mContext.getSystemService(
13698 Context.WINDOW_SERVICE)).addView(v, lp);
13701 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13702 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13705 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13706 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13707 synchronized (stats) {
13708 if (mBatteryStatsService.isOnBattery()) {
13709 mBatteryStatsService.enforceCallingPermission();
13710 int MY_UID = Binder.getCallingUid();
13712 if (sender == null) {
13715 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13717 BatteryStatsImpl.Uid.Pkg pkg =
13718 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13719 sourcePkg != null ? sourcePkg : rec.key.packageName);
13720 pkg.noteWakeupAlarmLocked(tag);
13725 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13726 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13729 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13730 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13731 synchronized (stats) {
13732 mBatteryStatsService.enforceCallingPermission();
13733 int MY_UID = Binder.getCallingUid();
13735 if (sender == null) {
13738 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13740 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13744 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13745 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13748 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13749 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13750 synchronized (stats) {
13751 mBatteryStatsService.enforceCallingPermission();
13752 int MY_UID = Binder.getCallingUid();
13754 if (sender == null) {
13757 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13759 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13763 public boolean killPids(int[] pids, String pReason, boolean secure) {
13764 if (Binder.getCallingUid() != SYSTEM_UID) {
13765 throw new SecurityException("killPids only available to the system");
13767 String reason = (pReason == null) ? "Unknown" : pReason;
13768 // XXX Note: don't acquire main activity lock here, because the window
13769 // manager calls in with its locks held.
13771 boolean killed = false;
13772 synchronized (mPidsSelfLocked) {
13774 for (int i=0; i<pids.length; i++) {
13775 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13776 if (proc != null) {
13777 int type = proc.setAdj;
13778 if (type > worstType) {
13784 // If the worst oom_adj is somewhere in the cached proc LRU range,
13785 // then constrain it so we will kill all cached procs.
13786 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13787 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13788 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13791 // If this is not a secure call, don't let it kill processes that
13793 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13794 worstType = ProcessList.SERVICE_ADJ;
13797 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13798 for (int i=0; i<pids.length; i++) {
13799 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13800 if (proc == null) {
13803 int adj = proc.setAdj;
13804 if (adj >= worstType && !proc.killedByAm) {
13805 proc.kill(reason, true);
13814 public void killUid(int appId, int userId, String reason) {
13815 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13816 synchronized (this) {
13817 final long identity = Binder.clearCallingIdentity();
13819 killPackageProcessesLocked(null, appId, userId,
13820 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13821 reason != null ? reason : "kill uid");
13823 Binder.restoreCallingIdentity(identity);
13829 public boolean killProcessesBelowForeground(String reason) {
13830 if (Binder.getCallingUid() != SYSTEM_UID) {
13831 throw new SecurityException("killProcessesBelowForeground() only available to system");
13834 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13837 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13838 if (Binder.getCallingUid() != SYSTEM_UID) {
13839 throw new SecurityException("killProcessesBelowAdj() only available to system");
13842 boolean killed = false;
13843 synchronized (mPidsSelfLocked) {
13844 final int size = mPidsSelfLocked.size();
13845 for (int i = 0; i < size; i++) {
13846 final int pid = mPidsSelfLocked.keyAt(i);
13847 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13848 if (proc == null) continue;
13850 final int adj = proc.setAdj;
13851 if (adj > belowAdj && !proc.killedByAm) {
13852 proc.kill(reason, true);
13861 public void hang(final IBinder who, boolean allowRestart) {
13862 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13863 != PackageManager.PERMISSION_GRANTED) {
13864 throw new SecurityException("Requires permission "
13865 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13868 final IBinder.DeathRecipient death = new DeathRecipient() {
13870 public void binderDied() {
13871 synchronized (this) {
13878 who.linkToDeath(death, 0);
13879 } catch (RemoteException e) {
13880 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13884 synchronized (this) {
13885 Watchdog.getInstance().setAllowRestart(allowRestart);
13886 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13887 synchronized (death) {
13888 while (who.isBinderAlive()) {
13891 } catch (InterruptedException e) {
13895 Watchdog.getInstance().setAllowRestart(true);
13900 public void restart() {
13901 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13902 != PackageManager.PERMISSION_GRANTED) {
13903 throw new SecurityException("Requires permission "
13904 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13907 Log.i(TAG, "Sending shutdown broadcast...");
13909 BroadcastReceiver br = new BroadcastReceiver() {
13910 @Override public void onReceive(Context context, Intent intent) {
13911 // Now the broadcast is done, finish up the low-level shutdown.
13912 Log.i(TAG, "Shutting down activity manager...");
13914 Log.i(TAG, "Shutdown complete, restarting!");
13915 killProcess(myPid());
13920 // First send the high-level shut down broadcast.
13921 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13922 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13923 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13924 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13925 mContext.sendOrderedBroadcastAsUser(intent,
13926 UserHandle.ALL, null, br, mHandler, 0, null, null);
13928 br.onReceive(mContext, intent);
13931 private long getLowRamTimeSinceIdle(long now) {
13932 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13936 public void performIdleMaintenance() {
13937 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13938 != PackageManager.PERMISSION_GRANTED) {
13939 throw new SecurityException("Requires permission "
13940 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13943 synchronized (this) {
13944 final long now = SystemClock.uptimeMillis();
13945 final long timeSinceLastIdle = now - mLastIdleTime;
13946 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13947 mLastIdleTime = now;
13948 mLowRamTimeSinceLastIdle = 0;
13949 if (mLowRamStartTime != 0) {
13950 mLowRamStartTime = now;
13953 StringBuilder sb = new StringBuilder(128);
13954 sb.append("Idle maintenance over ");
13955 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13956 sb.append(" low RAM for ");
13957 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13958 Slog.i(TAG, sb.toString());
13960 // If at least 1/3 of our time since the last idle period has been spent
13961 // with RAM low, then we want to kill processes.
13962 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13964 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13965 ProcessRecord proc = mLruProcesses.get(i);
13966 if (proc.notCachedSinceIdle) {
13967 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13968 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13969 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13970 if (doKilling && proc.initialIdlePss != 0
13971 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13972 sb = new StringBuilder(128);
13974 sb.append(proc.processName);
13975 sb.append(" in idle maint: pss=");
13976 sb.append(proc.lastPss);
13977 sb.append(", swapPss=");
13978 sb.append(proc.lastSwapPss);
13979 sb.append(", initialPss=");
13980 sb.append(proc.initialIdlePss);
13981 sb.append(", period=");
13982 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13983 sb.append(", lowRamPeriod=");
13984 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13985 Slog.wtfQuiet(TAG, sb.toString());
13986 proc.kill("idle maint (pss " + proc.lastPss
13987 + " from " + proc.initialIdlePss + ")", true);
13990 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13991 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13992 proc.notCachedSinceIdle = true;
13993 proc.initialIdlePss = 0;
13994 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13995 mTestPssMode, isSleepingLocked(), now);
13999 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14000 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14005 public void sendIdleJobTrigger() {
14006 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14007 != PackageManager.PERMISSION_GRANTED) {
14008 throw new SecurityException("Requires permission "
14009 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14012 final long ident = Binder.clearCallingIdentity();
14014 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14015 .setPackage("android")
14016 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14017 broadcastIntent(null, intent, null, null, 0, null, null, null,
14018 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14020 Binder.restoreCallingIdentity(ident);
14024 private void retrieveSettings() {
14025 final ContentResolver resolver = mContext.getContentResolver();
14026 final boolean freeformWindowManagement =
14027 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14028 || Settings.Global.getInt(
14029 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14030 final boolean supportsPictureInPicture =
14031 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14033 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14034 final boolean supportsSplitScreenMultiWindow =
14035 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14036 final boolean supportsMultiDisplay = mContext.getPackageManager()
14037 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14038 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14039 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14040 final boolean alwaysFinishActivities =
14041 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14042 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14043 final boolean forceResizable = Settings.Global.getInt(
14044 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14045 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14046 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14047 final boolean supportsLeanbackOnly =
14048 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14050 // Transfer any global setting for forcing RTL layout, into a System Property
14051 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14053 final Configuration configuration = new Configuration();
14054 Settings.System.getConfiguration(resolver, configuration);
14056 // This will take care of setting the correct layout direction flags
14057 configuration.setLayoutDirection(configuration.locale);
14060 synchronized (this) {
14061 mDebugApp = mOrigDebugApp = debugApp;
14062 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14063 mAlwaysFinishActivities = alwaysFinishActivities;
14064 mSupportsLeanbackOnly = supportsLeanbackOnly;
14065 mForceResizableActivities = forceResizable;
14066 final boolean multiWindowFormEnabled = freeformWindowManagement
14067 || supportsSplitScreenMultiWindow
14068 || supportsPictureInPicture
14069 || supportsMultiDisplay;
14070 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14071 mSupportsMultiWindow = true;
14072 mSupportsFreeformWindowManagement = freeformWindowManagement;
14073 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14074 mSupportsPictureInPicture = supportsPictureInPicture;
14075 mSupportsMultiDisplay = supportsMultiDisplay;
14077 mSupportsMultiWindow = false;
14078 mSupportsFreeformWindowManagement = false;
14079 mSupportsSplitScreenMultiWindow = false;
14080 mSupportsPictureInPicture = false;
14081 mSupportsMultiDisplay = false;
14083 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14084 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14085 // This happens before any activities are started, so we can change global configuration
14087 updateConfigurationLocked(configuration, null, true);
14088 final Configuration globalConfig = getGlobalConfiguration();
14089 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14091 // Load resources only after the current configuration has been set.
14092 final Resources res = mContext.getResources();
14093 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14094 mThumbnailWidth = res.getDimensionPixelSize(
14095 com.android.internal.R.dimen.thumbnail_width);
14096 mThumbnailHeight = res.getDimensionPixelSize(
14097 com.android.internal.R.dimen.thumbnail_height);
14098 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14099 com.android.internal.R.string.config_appsNotReportingCrashes));
14100 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14101 com.android.internal.R.bool.config_customUserSwitchUi);
14102 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14103 mFullscreenThumbnailScale = (float) res
14104 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14105 (float) globalConfig.screenWidthDp;
14107 mFullscreenThumbnailScale = res.getFraction(
14108 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14110 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14114 public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14115 traceLog.traceBegin("PhaseActivityManagerReady");
14116 synchronized(this) {
14117 if (mSystemReady) {
14118 // If we're done calling all the receivers, run the next "boot phase" passed in
14119 // by the SystemServer
14120 if (goingCallback != null) {
14121 goingCallback.run();
14126 mLocalDeviceIdleController
14127 = LocalServices.getService(DeviceIdleController.LocalService.class);
14128 mAssistUtils = new AssistUtils(mContext);
14129 mVrController.onSystemReady();
14130 // Make sure we have the current profile info, since it is needed for security checks.
14131 mUserController.onSystemReady();
14132 mRecentTasks.onSystemReadyLocked();
14133 mAppOpsService.systemReady();
14134 mSystemReady = true;
14137 ArrayList<ProcessRecord> procsToKill = null;
14138 synchronized(mPidsSelfLocked) {
14139 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14140 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14141 if (!isAllowedWhileBooting(proc.info)){
14142 if (procsToKill == null) {
14143 procsToKill = new ArrayList<ProcessRecord>();
14145 procsToKill.add(proc);
14150 synchronized(this) {
14151 if (procsToKill != null) {
14152 for (int i=procsToKill.size()-1; i>=0; i--) {
14153 ProcessRecord proc = procsToKill.get(i);
14154 Slog.i(TAG, "Removing system update proc: " + proc);
14155 removeProcessLocked(proc, true, false, "system update done");
14159 // Now that we have cleaned up any update processes, we
14160 // are ready to start launching real processes and know that
14161 // we won't trample on them any more.
14162 mProcessesReady = true;
14165 Slog.i(TAG, "System now ready");
14166 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14167 SystemClock.uptimeMillis());
14169 synchronized(this) {
14170 // Make sure we have no pre-ready processes sitting around.
14172 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14173 ResolveInfo ri = mContext.getPackageManager()
14174 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14176 CharSequence errorMsg = null;
14178 ActivityInfo ai = ri.activityInfo;
14179 ApplicationInfo app = ai.applicationInfo;
14180 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14181 mTopAction = Intent.ACTION_FACTORY_TEST;
14183 mTopComponent = new ComponentName(app.packageName,
14186 errorMsg = mContext.getResources().getText(
14187 com.android.internal.R.string.factorytest_not_system);
14190 errorMsg = mContext.getResources().getText(
14191 com.android.internal.R.string.factorytest_no_action);
14193 if (errorMsg != null) {
14196 mTopComponent = null;
14197 Message msg = Message.obtain();
14198 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14199 msg.getData().putCharSequence("msg", errorMsg);
14200 mUiHandler.sendMessage(msg);
14205 retrieveSettings();
14206 final int currentUserId;
14207 synchronized (this) {
14208 currentUserId = mUserController.getCurrentUserIdLocked();
14209 readGrantedUriPermissionsLocked();
14212 if (goingCallback != null) goingCallback.run();
14213 traceLog.traceBegin("ActivityManagerStartApps");
14214 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14215 Integer.toString(currentUserId), currentUserId);
14216 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14217 Integer.toString(currentUserId), currentUserId);
14218 mSystemServiceManager.startUser(currentUserId);
14220 synchronized (this) {
14221 // Only start up encryption-aware persistent apps; once user is
14222 // unlocked we'll come back around and start unaware apps
14223 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14225 // Start up initial activity.
14227 // Enable home activity for system user, so that the system can always boot. We don't
14228 // do this when the system user is not setup since the setup wizard should be the one
14229 // to handle home activity in this case.
14230 if (UserManager.isSplitSystemUser() &&
14231 Settings.Secure.getInt(mContext.getContentResolver(),
14232 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14233 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14235 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14236 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14237 UserHandle.USER_SYSTEM);
14238 } catch (RemoteException e) {
14239 throw e.rethrowAsRuntimeException();
14242 startHomeActivityLocked(currentUserId, "systemReady");
14245 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14246 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14247 + " data partition or your device will be unstable.");
14248 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14250 } catch (RemoteException e) {
14253 if (!Build.isBuildConsistent()) {
14254 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14255 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14258 long ident = Binder.clearCallingIdentity();
14260 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14261 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14262 | Intent.FLAG_RECEIVER_FOREGROUND);
14263 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14264 broadcastIntentLocked(null, null, intent,
14265 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14266 null, false, false, MY_PID, SYSTEM_UID,
14268 intent = new Intent(Intent.ACTION_USER_STARTING);
14269 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14270 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14271 broadcastIntentLocked(null, null, intent,
14272 null, new IIntentReceiver.Stub() {
14274 public void performReceive(Intent intent, int resultCode, String data,
14275 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14276 throws RemoteException {
14279 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14280 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14281 } catch (Throwable t) {
14282 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14284 Binder.restoreCallingIdentity(ident);
14286 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14287 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14288 traceLog.traceEnd(); // ActivityManagerStartApps
14289 traceLog.traceEnd(); // PhaseActivityManagerReady
14293 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14294 synchronized (this) {
14295 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14299 void skipCurrentReceiverLocked(ProcessRecord app) {
14300 for (BroadcastQueue queue : mBroadcastQueues) {
14301 queue.skipCurrentReceiverLocked(app);
14306 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14307 * The application process will exit immediately after this call returns.
14308 * @param app object of the crashing app, null for the system server
14309 * @param crashInfo describing the exception
14311 public void handleApplicationCrash(IBinder app,
14312 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14313 ProcessRecord r = findAppProcess(app, "Crash");
14314 final String processName = app == null ? "system_server"
14315 : (r == null ? "unknown" : r.processName);
14317 handleApplicationCrashInner("crash", r, processName, crashInfo);
14320 /* Native crash reporting uses this inner version because it needs to be somewhat
14321 * decoupled from the AM-managed cleanup lifecycle
14323 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14324 ApplicationErrorReport.CrashInfo crashInfo) {
14325 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14326 UserHandle.getUserId(Binder.getCallingUid()), processName,
14327 r == null ? -1 : r.info.flags,
14328 crashInfo.exceptionClassName,
14329 crashInfo.exceptionMessage,
14330 crashInfo.throwFileName,
14331 crashInfo.throwLineNumber);
14333 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14335 mAppErrors.crashApplication(r, crashInfo);
14338 public void handleApplicationStrictModeViolation(
14341 StrictMode.ViolationInfo info) {
14342 ProcessRecord r = findAppProcess(app, "StrictMode");
14347 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14348 Integer stackFingerprint = info.hashCode();
14349 boolean logIt = true;
14350 synchronized (mAlreadyLoggedViolatedStacks) {
14351 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14353 // TODO: sub-sample into EventLog for these, with
14354 // the info.durationMillis? Then we'd get
14355 // the relative pain numbers, without logging all
14356 // the stack traces repeatedly. We'd want to do
14357 // likewise in the client code, which also does
14358 // dup suppression, before the Binder call.
14360 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14361 mAlreadyLoggedViolatedStacks.clear();
14363 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14367 logStrictModeViolationToDropBox(r, info);
14371 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14372 AppErrorResult result = new AppErrorResult();
14373 synchronized (this) {
14374 final long origId = Binder.clearCallingIdentity();
14376 Message msg = Message.obtain();
14377 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14378 HashMap<String, Object> data = new HashMap<String, Object>();
14379 data.put("result", result);
14380 data.put("app", r);
14381 data.put("violationMask", violationMask);
14382 data.put("info", info);
14384 mUiHandler.sendMessage(msg);
14386 Binder.restoreCallingIdentity(origId);
14388 int res = result.get();
14389 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14393 // Depending on the policy in effect, there could be a bunch of
14394 // these in quick succession so we try to batch these together to
14395 // minimize disk writes, number of dropbox entries, and maximize
14396 // compression, by having more fewer, larger records.
14397 private void logStrictModeViolationToDropBox(
14398 ProcessRecord process,
14399 StrictMode.ViolationInfo info) {
14400 if (info == null) {
14403 final boolean isSystemApp = process == null ||
14404 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14405 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14406 final String processName = process == null ? "unknown" : process.processName;
14407 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14408 final DropBoxManager dbox = (DropBoxManager)
14409 mContext.getSystemService(Context.DROPBOX_SERVICE);
14411 // Exit early if the dropbox isn't configured to accept this report type.
14412 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14414 boolean bufferWasEmpty;
14415 boolean needsFlush;
14416 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14417 synchronized (sb) {
14418 bufferWasEmpty = sb.length() == 0;
14419 appendDropBoxProcessHeaders(process, processName, sb);
14420 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14421 sb.append("System-App: ").append(isSystemApp).append("\n");
14422 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14423 if (info.violationNumThisLoop != 0) {
14424 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14426 if (info.numAnimationsRunning != 0) {
14427 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14429 if (info.broadcastIntentAction != null) {
14430 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14432 if (info.durationMillis != -1) {
14433 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14435 if (info.numInstances != -1) {
14436 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14438 if (info.tags != null) {
14439 for (String tag : info.tags) {
14440 sb.append("Span-Tag: ").append(tag).append("\n");
14444 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14445 sb.append(info.crashInfo.stackTrace);
14448 if (info.message != null) {
14449 sb.append(info.message);
14453 // Only buffer up to ~64k. Various logging bits truncate
14455 needsFlush = (sb.length() > 64 * 1024);
14458 // Flush immediately if the buffer's grown too large, or this
14459 // is a non-system app. Non-system apps are isolated with a
14460 // different tag & policy and not batched.
14462 // Batching is useful during internal testing with
14463 // StrictMode settings turned up high. Without batching,
14464 // thousands of separate files could be created on boot.
14465 if (!isSystemApp || needsFlush) {
14466 new Thread("Error dump: " + dropboxTag) {
14468 public void run() {
14470 synchronized (sb) {
14471 report = sb.toString();
14472 sb.delete(0, sb.length());
14475 if (report.length() != 0) {
14476 dbox.addText(dropboxTag, report);
14483 // System app batching:
14484 if (!bufferWasEmpty) {
14485 // An existing dropbox-writing thread is outstanding, so
14486 // we don't need to start it up. The existing thread will
14487 // catch the buffer appends we just did.
14491 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14492 // (After this point, we shouldn't access AMS internal data structures.)
14493 new Thread("Error dump: " + dropboxTag) {
14495 public void run() {
14496 // 5 second sleep to let stacks arrive and be batched together
14498 Thread.sleep(5000); // 5 seconds
14499 } catch (InterruptedException e) {}
14501 String errorReport;
14502 synchronized (mStrictModeBuffer) {
14503 errorReport = mStrictModeBuffer.toString();
14504 if (errorReport.length() == 0) {
14507 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14508 mStrictModeBuffer.trimToSize();
14510 dbox.addText(dropboxTag, errorReport);
14516 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14517 * @param app object of the crashing app, null for the system server
14518 * @param tag reported by the caller
14519 * @param system whether this wtf is coming from the system
14520 * @param crashInfo describing the context of the error
14521 * @return true if the process should exit immediately (WTF is fatal)
14523 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14524 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14525 final int callingUid = Binder.getCallingUid();
14526 final int callingPid = Binder.getCallingPid();
14529 // If this is coming from the system, we could very well have low-level
14530 // system locks held, so we want to do this all asynchronously. And we
14531 // never want this to become fatal, so there is that too.
14532 mHandler.post(new Runnable() {
14533 @Override public void run() {
14534 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14540 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14543 final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14544 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14545 final boolean isSystem = (r == null) || r.persistent;
14547 if (isFatal && !isSystem) {
14548 mAppErrors.crashApplication(r, crashInfo);
14555 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14556 final ApplicationErrorReport.CrashInfo crashInfo) {
14557 final ProcessRecord r = findAppProcess(app, "WTF");
14558 final String processName = app == null ? "system_server"
14559 : (r == null ? "unknown" : r.processName);
14561 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14562 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14564 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14570 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14571 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14573 private ProcessRecord findAppProcess(IBinder app, String reason) {
14578 synchronized (this) {
14579 final int NP = mProcessNames.getMap().size();
14580 for (int ip=0; ip<NP; ip++) {
14581 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14582 final int NA = apps.size();
14583 for (int ia=0; ia<NA; ia++) {
14584 ProcessRecord p = apps.valueAt(ia);
14585 if (p.thread != null && p.thread.asBinder() == app) {
14591 Slog.w(TAG, "Can't find mystery application for " + reason
14592 + " from pid=" + Binder.getCallingPid()
14593 + " uid=" + Binder.getCallingUid() + ": " + app);
14599 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14600 * to append various headers to the dropbox log text.
14602 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14603 StringBuilder sb) {
14604 // Watchdog thread ends up invoking this function (with
14605 // a null ProcessRecord) to add the stack file to dropbox.
14606 // Do not acquire a lock on this (am) in such cases, as it
14607 // could cause a potential deadlock, if and when watchdog
14608 // is invoked due to unavailability of lock on am and it
14609 // would prevent watchdog from killing system_server.
14610 if (process == null) {
14611 sb.append("Process: ").append(processName).append("\n");
14614 // Note: ProcessRecord 'process' is guarded by the service
14615 // instance. (notably process.pkgList, which could otherwise change
14616 // concurrently during execution of this method)
14617 synchronized (this) {
14618 sb.append("Process: ").append(processName).append("\n");
14619 sb.append("PID: ").append(process.pid).append("\n");
14620 int flags = process.info.flags;
14621 IPackageManager pm = AppGlobals.getPackageManager();
14622 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14623 for (int ip=0; ip<process.pkgList.size(); ip++) {
14624 String pkg = process.pkgList.keyAt(ip);
14625 sb.append("Package: ").append(pkg);
14627 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14629 sb.append(" v").append(pi.versionCode);
14630 if (pi.versionName != null) {
14631 sb.append(" (").append(pi.versionName).append(")");
14634 } catch (RemoteException e) {
14635 Slog.e(TAG, "Error getting package info: " + pkg, e);
14642 private static String processClass(ProcessRecord process) {
14643 if (process == null || process.pid == MY_PID) {
14644 return "system_server";
14645 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14646 return "system_app";
14652 private volatile long mWtfClusterStart;
14653 private volatile int mWtfClusterCount;
14656 * Write a description of an error (crash, WTF, ANR) to the drop box.
14657 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14658 * @param process which caused the error, null means the system server
14659 * @param activity which triggered the error, null if unknown
14660 * @param parent activity related to the error, null if unknown
14661 * @param subject line related to the error, null if absent
14662 * @param report in long form describing the error, null if absent
14663 * @param dataFile text file to include in the report, null if none
14664 * @param crashInfo giving an application stack trace, null if absent
14666 public void addErrorToDropBox(String eventType,
14667 ProcessRecord process, String processName, ActivityRecord activity,
14668 ActivityRecord parent, String subject,
14669 final String report, final File dataFile,
14670 final ApplicationErrorReport.CrashInfo crashInfo) {
14671 // NOTE -- this must never acquire the ActivityManagerService lock,
14672 // otherwise the watchdog may be prevented from resetting the system.
14674 // Bail early if not published yet
14675 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14676 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14678 // Exit early if the dropbox isn't configured to accept this report type.
14679 final String dropboxTag = processClass(process) + "_" + eventType;
14680 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14682 // Rate-limit how often we're willing to do the heavy lifting below to
14683 // collect and record logs; currently 5 logs per 10 second period.
14684 final long now = SystemClock.elapsedRealtime();
14685 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14686 mWtfClusterStart = now;
14687 mWtfClusterCount = 1;
14689 if (mWtfClusterCount++ >= 5) return;
14692 final StringBuilder sb = new StringBuilder(1024);
14693 appendDropBoxProcessHeaders(process, processName, sb);
14694 if (process != null) {
14695 sb.append("Foreground: ")
14696 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14699 if (activity != null) {
14700 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14702 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14703 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14705 if (parent != null && parent != activity) {
14706 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14708 if (subject != null) {
14709 sb.append("Subject: ").append(subject).append("\n");
14711 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14712 if (Debug.isDebuggerConnected()) {
14713 sb.append("Debugger: Connected\n");
14717 // Do the rest in a worker thread to avoid blocking the caller on I/O
14718 // (After this point, we shouldn't access AMS internal data structures.)
14719 Thread worker = new Thread("Error dump: " + dropboxTag) {
14721 public void run() {
14722 if (report != null) {
14726 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14727 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14728 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14729 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14731 if (dataFile != null && maxDataFileSize > 0) {
14733 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14734 "\n\n[[TRUNCATED]]"));
14735 } catch (IOException e) {
14736 Slog.e(TAG, "Error reading " + dataFile, e);
14739 if (crashInfo != null && crashInfo.stackTrace != null) {
14740 sb.append(crashInfo.stackTrace);
14746 // Merge several logcat streams, and take the last N lines
14747 InputStreamReader input = null;
14749 java.lang.Process logcat = new ProcessBuilder(
14750 "/system/bin/timeout", "-k", "15s", "10s",
14751 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14752 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14753 .redirectErrorStream(true).start();
14755 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14756 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14757 input = new InputStreamReader(logcat.getInputStream());
14760 char[] buf = new char[8192];
14761 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14762 } catch (IOException e) {
14763 Slog.e(TAG, "Error running logcat", e);
14765 if (input != null) try { input.close(); } catch (IOException e) {}
14769 dbox.addText(dropboxTag, sb.toString());
14773 if (process == null) {
14774 // If process is null, we are being called from some internal code
14775 // and may be about to die -- run this synchronously.
14783 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14784 enforceNotIsolatedCaller("getProcessesInErrorState");
14785 // assume our apps are happy - lazy create the list
14786 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14788 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14789 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14790 int userId = UserHandle.getUserId(Binder.getCallingUid());
14792 synchronized (this) {
14794 // iterate across all processes
14795 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14796 ProcessRecord app = mLruProcesses.get(i);
14797 if (!allUsers && app.userId != userId) {
14800 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14801 // This one's in trouble, so we'll generate a report for it
14802 // crashes are higher priority (in case there's a crash *and* an anr)
14803 ActivityManager.ProcessErrorStateInfo report = null;
14804 if (app.crashing) {
14805 report = app.crashingReport;
14806 } else if (app.notResponding) {
14807 report = app.notRespondingReport;
14810 if (report != null) {
14811 if (errList == null) {
14812 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14814 errList.add(report);
14816 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14817 " crashing = " + app.crashing +
14818 " notResponding = " + app.notResponding);
14827 static int procStateToImportance(int procState, int memAdj,
14828 ActivityManager.RunningAppProcessInfo currApp,
14829 int clientTargetSdk) {
14830 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14831 procState, clientTargetSdk);
14832 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14833 currApp.lru = memAdj;
14840 private void fillInProcMemInfo(ProcessRecord app,
14841 ActivityManager.RunningAppProcessInfo outInfo,
14842 int clientTargetSdk) {
14843 outInfo.pid = app.pid;
14844 outInfo.uid = app.info.uid;
14845 if (mHeavyWeightProcess == app) {
14846 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14848 if (app.persistent) {
14849 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14851 if (app.activities.size() > 0) {
14852 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14854 outInfo.lastTrimLevel = app.trimMemoryLevel;
14855 int adj = app.curAdj;
14856 int procState = app.curProcState;
14857 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14858 outInfo.importanceReasonCode = app.adjTypeCode;
14859 outInfo.processState = app.curProcState;
14863 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14864 enforceNotIsolatedCaller("getRunningAppProcesses");
14866 final int callingUid = Binder.getCallingUid();
14867 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14869 // Lazy instantiation of list
14870 List<ActivityManager.RunningAppProcessInfo> runList = null;
14871 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14872 callingUid) == PackageManager.PERMISSION_GRANTED;
14873 final int userId = UserHandle.getUserId(callingUid);
14874 final boolean allUids = isGetTasksAllowed(
14875 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14877 synchronized (this) {
14878 // Iterate across all processes
14879 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14880 ProcessRecord app = mLruProcesses.get(i);
14881 if ((!allUsers && app.userId != userId)
14882 || (!allUids && app.uid != callingUid)) {
14885 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14886 // Generate process state info for running application
14887 ActivityManager.RunningAppProcessInfo currApp =
14888 new ActivityManager.RunningAppProcessInfo(app.processName,
14889 app.pid, app.getPackageList());
14890 fillInProcMemInfo(app, currApp, clientTargetSdk);
14891 if (app.adjSource instanceof ProcessRecord) {
14892 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14893 currApp.importanceReasonImportance =
14894 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14895 app.adjSourceProcState);
14896 } else if (app.adjSource instanceof ActivityRecord) {
14897 ActivityRecord r = (ActivityRecord)app.adjSource;
14898 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14900 if (app.adjTarget instanceof ComponentName) {
14901 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14903 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14904 // + " lru=" + currApp.lru);
14905 if (runList == null) {
14906 runList = new ArrayList<>();
14908 runList.add(currApp);
14916 public List<ApplicationInfo> getRunningExternalApplications() {
14917 enforceNotIsolatedCaller("getRunningExternalApplications");
14918 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14919 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14920 if (runningApps != null && runningApps.size() > 0) {
14921 Set<String> extList = new HashSet<String>();
14922 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14923 if (app.pkgList != null) {
14924 for (String pkg : app.pkgList) {
14929 IPackageManager pm = AppGlobals.getPackageManager();
14930 for (String pkg : extList) {
14932 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14933 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14936 } catch (RemoteException e) {
14944 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14945 enforceNotIsolatedCaller("getMyMemoryState");
14947 final int callingUid = Binder.getCallingUid();
14948 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14950 synchronized (this) {
14951 ProcessRecord proc;
14952 synchronized (mPidsSelfLocked) {
14953 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14955 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14960 public int getMemoryTrimLevel() {
14961 enforceNotIsolatedCaller("getMyMemoryState");
14962 synchronized (this) {
14963 return mLastMemoryLevel;
14968 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14969 FileDescriptor err, String[] args, ShellCallback callback,
14970 ResultReceiver resultReceiver) {
14971 (new ActivityManagerShellCommand(this, false)).exec(
14972 this, in, out, err, args, callback, resultReceiver);
14976 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14977 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14979 boolean dumpAll = false;
14980 boolean dumpClient = false;
14981 boolean dumpCheckin = false;
14982 boolean dumpCheckinFormat = false;
14983 boolean dumpVisibleStacksOnly = false;
14984 boolean dumpFocusedStackOnly = false;
14985 String dumpPackage = null;
14988 while (opti < args.length) {
14989 String opt = args[opti];
14990 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14994 if ("-a".equals(opt)) {
14996 } else if ("-c".equals(opt)) {
14998 } else if ("-v".equals(opt)) {
14999 dumpVisibleStacksOnly = true;
15000 } else if ("-f".equals(opt)) {
15001 dumpFocusedStackOnly = true;
15002 } else if ("-p".equals(opt)) {
15003 if (opti < args.length) {
15004 dumpPackage = args[opti];
15007 pw.println("Error: -p option requires package argument");
15011 } else if ("--checkin".equals(opt)) {
15012 dumpCheckin = dumpCheckinFormat = true;
15013 } else if ("-C".equals(opt)) {
15014 dumpCheckinFormat = true;
15015 } else if ("-h".equals(opt)) {
15016 ActivityManagerShellCommand.dumpHelp(pw, true);
15019 pw.println("Unknown argument: " + opt + "; use -h for help");
15023 long origId = Binder.clearCallingIdentity();
15024 boolean more = false;
15025 // Is the caller requesting to dump a particular piece of data?
15026 if (opti < args.length) {
15027 String cmd = args[opti];
15029 if ("activities".equals(cmd) || "a".equals(cmd)) {
15030 synchronized (this) {
15031 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15033 } else if ("lastanr".equals(cmd)) {
15034 synchronized (this) {
15035 dumpLastANRLocked(pw);
15037 } else if ("starter".equals(cmd)) {
15038 synchronized (this) {
15039 dumpActivityStarterLocked(pw);
15041 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15042 synchronized (this) {
15043 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15045 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15048 if (opti >= args.length) {
15050 newArgs = EMPTY_STRING_ARRAY;
15052 dumpPackage = args[opti];
15054 newArgs = new String[args.length - opti];
15055 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15056 args.length - opti);
15058 synchronized (this) {
15059 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15061 } else if ("broadcast-stats".equals(cmd)) {
15064 if (opti >= args.length) {
15066 newArgs = EMPTY_STRING_ARRAY;
15068 dumpPackage = args[opti];
15070 newArgs = new String[args.length - opti];
15071 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15072 args.length - opti);
15074 synchronized (this) {
15075 if (dumpCheckinFormat) {
15076 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15079 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15082 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15085 if (opti >= args.length) {
15087 newArgs = EMPTY_STRING_ARRAY;
15089 dumpPackage = args[opti];
15091 newArgs = new String[args.length - opti];
15092 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15093 args.length - opti);
15095 synchronized (this) {
15096 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15098 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15101 if (opti >= args.length) {
15103 newArgs = EMPTY_STRING_ARRAY;
15105 dumpPackage = args[opti];
15107 newArgs = new String[args.length - opti];
15108 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15109 args.length - opti);
15111 synchronized (this) {
15112 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15114 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15115 synchronized (this) {
15116 dumpOomLocked(fd, pw, args, opti, true);
15118 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15119 synchronized (this) {
15120 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15122 } else if ("provider".equals(cmd)) {
15125 if (opti >= args.length) {
15127 newArgs = EMPTY_STRING_ARRAY;
15131 newArgs = new String[args.length - opti];
15132 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15134 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15135 pw.println("No providers match: " + name);
15136 pw.println("Use -h for help.");
15138 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15139 synchronized (this) {
15140 dumpProvidersLocked(fd, pw, args, opti, true, null);
15142 } else if ("service".equals(cmd)) {
15145 if (opti >= args.length) {
15147 newArgs = EMPTY_STRING_ARRAY;
15151 newArgs = new String[args.length - opti];
15152 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15153 args.length - opti);
15155 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15156 pw.println("No services match: " + name);
15157 pw.println("Use -h for help.");
15159 } else if ("package".equals(cmd)) {
15161 if (opti >= args.length) {
15162 pw.println("package: no package name specified");
15163 pw.println("Use -h for help.");
15165 dumpPackage = args[opti];
15167 newArgs = new String[args.length - opti];
15168 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15169 args.length - opti);
15174 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15175 synchronized (this) {
15176 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15178 } else if ("settings".equals(cmd)) {
15179 synchronized (this) {
15180 mConstants.dump(pw);
15182 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15184 ActiveServices.ServiceDumper dumper;
15185 synchronized (this) {
15186 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15189 dumper.dumpWithClient();
15191 synchronized (this) {
15192 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15193 dumpPackage).dumpLocked();
15196 } else if ("locks".equals(cmd)) {
15197 LockGuard.dump(fd, pw, args);
15199 // Dumping a single activity?
15200 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15201 dumpFocusedStackOnly)) {
15202 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15203 int res = shell.exec(this, null, fd, null, args, null,
15204 new ResultReceiver(null));
15206 pw.println("Bad activity command, or no activities match: " + cmd);
15207 pw.println("Use -h for help.");
15212 Binder.restoreCallingIdentity(origId);
15217 // No piece of data specified, dump everything.
15218 if (dumpCheckinFormat) {
15219 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15220 } else if (dumpClient) {
15221 ActiveServices.ServiceDumper sdumper;
15222 synchronized (this) {
15223 mConstants.dump(pw);
15226 pw.println("-------------------------------------------------------------------------------");
15228 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15231 pw.println("-------------------------------------------------------------------------------");
15233 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15236 pw.println("-------------------------------------------------------------------------------");
15238 if (dumpAll || dumpPackage != null) {
15239 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15242 pw.println("-------------------------------------------------------------------------------");
15245 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15248 pw.println("-------------------------------------------------------------------------------");
15250 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15253 pw.println("-------------------------------------------------------------------------------");
15255 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15258 sdumper.dumpWithClient();
15260 synchronized (this) {
15262 pw.println("-------------------------------------------------------------------------------");
15264 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15267 pw.println("-------------------------------------------------------------------------------");
15269 dumpLastANRLocked(pw);
15272 pw.println("-------------------------------------------------------------------------------");
15274 dumpActivityStarterLocked(pw);
15277 pw.println("-------------------------------------------------------------------------------");
15279 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15280 if (mAssociations.size() > 0) {
15283 pw.println("-------------------------------------------------------------------------------");
15285 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15289 pw.println("-------------------------------------------------------------------------------");
15291 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15295 synchronized (this) {
15296 mConstants.dump(pw);
15299 pw.println("-------------------------------------------------------------------------------");
15301 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15304 pw.println("-------------------------------------------------------------------------------");
15306 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15309 pw.println("-------------------------------------------------------------------------------");
15311 if (dumpAll || dumpPackage != null) {
15312 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15315 pw.println("-------------------------------------------------------------------------------");
15318 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15321 pw.println("-------------------------------------------------------------------------------");
15323 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15326 pw.println("-------------------------------------------------------------------------------");
15328 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15332 pw.println("-------------------------------------------------------------------------------");
15334 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15337 pw.println("-------------------------------------------------------------------------------");
15339 dumpLastANRLocked(pw);
15342 pw.println("-------------------------------------------------------------------------------");
15344 dumpActivityStarterLocked(pw);
15347 pw.println("-------------------------------------------------------------------------------");
15349 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15350 if (mAssociations.size() > 0) {
15353 pw.println("-------------------------------------------------------------------------------");
15355 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15359 pw.println("-------------------------------------------------------------------------------");
15361 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15364 Binder.restoreCallingIdentity(origId);
15367 private void dumpLastANRLocked(PrintWriter pw) {
15368 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
15369 if (mLastANRState == null) {
15370 pw.println(" <no ANR has occurred since boot>");
15372 pw.println(mLastANRState);
15376 private void dumpActivityStarterLocked(PrintWriter pw) {
15377 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
15378 mActivityStarter.dump(pw, "");
15381 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15382 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15383 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15384 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15387 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15388 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15389 pw.println(header);
15391 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15393 boolean needSep = printedAnything;
15395 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15396 mStackSupervisor.getResumedActivityLocked(),
15397 dumpPackage, needSep, " ResumedActivity: ");
15399 printedAnything = true;
15403 if (dumpPackage == null) {
15407 printedAnything = true;
15408 mStackSupervisor.dump(pw, " ");
15411 if (!printedAnything) {
15412 pw.println(" (nothing)");
15416 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15417 int opti, boolean dumpAll, String dumpPackage) {
15418 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15420 boolean printedAnything = false;
15422 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15423 boolean printedHeader = false;
15425 final int N = mRecentTasks.size();
15426 for (int i=0; i<N; i++) {
15427 TaskRecord tr = mRecentTasks.get(i);
15428 if (dumpPackage != null) {
15429 if (tr.realActivity == null ||
15430 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15434 if (!printedHeader) {
15435 pw.println(" Recent tasks:");
15436 printedHeader = true;
15437 printedAnything = true;
15439 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15442 mRecentTasks.get(i).dump(pw, " ");
15447 if (!printedAnything) {
15448 pw.println(" (nothing)");
15452 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15453 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15454 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15457 if (dumpPackage != null) {
15458 IPackageManager pm = AppGlobals.getPackageManager();
15460 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15461 } catch (RemoteException e) {
15465 boolean printedAnything = false;
15467 final long now = SystemClock.uptimeMillis();
15469 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15470 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15471 = mAssociations.valueAt(i1);
15472 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15473 SparseArray<ArrayMap<String, Association>> sourceUids
15474 = targetComponents.valueAt(i2);
15475 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15476 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15477 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15478 Association ass = sourceProcesses.valueAt(i4);
15479 if (dumpPackage != null) {
15480 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15481 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15485 printedAnything = true;
15487 pw.print(ass.mTargetProcess);
15489 UserHandle.formatUid(pw, ass.mTargetUid);
15491 pw.print(ass.mSourceProcess);
15493 UserHandle.formatUid(pw, ass.mSourceUid);
15496 pw.print(ass.mTargetComponent.flattenToShortString());
15499 long dur = ass.mTime;
15500 if (ass.mNesting > 0) {
15501 dur += now - ass.mStartTime;
15503 TimeUtils.formatDuration(dur, pw);
15505 pw.print(ass.mCount);
15506 pw.print(" times)");
15508 for (int i=0; i<ass.mStateTimes.length; i++) {
15509 long amt = ass.mStateTimes[i];
15510 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15511 amt += now - ass.mLastStateUptime;
15515 pw.print(ProcessList.makeProcStateString(
15516 i + ActivityManager.MIN_PROCESS_STATE));
15518 TimeUtils.formatDuration(amt, pw);
15519 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15525 if (ass.mNesting > 0) {
15526 pw.print(" Currently active: ");
15527 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15536 if (!printedAnything) {
15537 pw.println(" (nothing)");
15541 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15542 String header, boolean needSep) {
15543 boolean printed = false;
15544 int whichAppId = -1;
15545 if (dumpPackage != null) {
15547 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15549 whichAppId = UserHandle.getAppId(info.uid);
15550 } catch (NameNotFoundException e) {
15551 e.printStackTrace();
15554 for (int i=0; i<uids.size(); i++) {
15555 UidRecord uidRec = uids.valueAt(i);
15556 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15565 pw.println(header);
15568 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15569 pw.print(": "); pw.println(uidRec);
15574 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15575 int opti, boolean dumpAll, String dumpPackage) {
15576 boolean needSep = false;
15577 boolean printedAnything = false;
15580 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15583 final int NP = mProcessNames.getMap().size();
15584 for (int ip=0; ip<NP; ip++) {
15585 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15586 final int NA = procs.size();
15587 for (int ia=0; ia<NA; ia++) {
15588 ProcessRecord r = procs.valueAt(ia);
15589 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15593 pw.println(" All known processes:");
15595 printedAnything = true;
15597 pw.print(r.persistent ? " *PERS*" : " *APP*");
15598 pw.print(" UID "); pw.print(procs.keyAt(ia));
15599 pw.print(" "); pw.println(r);
15601 if (r.persistent) {
15608 if (mIsolatedProcesses.size() > 0) {
15609 boolean printed = false;
15610 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15611 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15612 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15619 pw.println(" Isolated process list (sorted by uid):");
15620 printedAnything = true;
15624 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15629 if (mActiveInstrumentation.size() > 0) {
15630 boolean printed = false;
15631 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15632 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15633 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15634 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15641 pw.println(" Active instrumentation:");
15642 printedAnything = true;
15646 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15652 if (mActiveUids.size() > 0) {
15653 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15654 printedAnything = needSep = true;
15658 if (mValidateUids.size() > 0) {
15659 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15660 printedAnything = needSep = true;
15665 if (mLruProcesses.size() > 0) {
15669 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15670 pw.print(" total, non-act at ");
15671 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15672 pw.print(", non-svc at ");
15673 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15675 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15677 printedAnything = true;
15680 if (dumpAll || dumpPackage != null) {
15681 synchronized (mPidsSelfLocked) {
15682 boolean printed = false;
15683 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15684 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15685 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15689 if (needSep) pw.println();
15691 pw.println(" PID mappings:");
15693 printedAnything = true;
15695 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15696 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15701 if (mImportantProcesses.size() > 0) {
15702 synchronized (mPidsSelfLocked) {
15703 boolean printed = false;
15704 for (int i = 0; i< mImportantProcesses.size(); i++) {
15705 ProcessRecord r = mPidsSelfLocked.get(
15706 mImportantProcesses.valueAt(i).pid);
15707 if (dumpPackage != null && (r == null
15708 || !r.pkgList.containsKey(dumpPackage))) {
15712 if (needSep) pw.println();
15714 pw.println(" Foreground Processes:");
15716 printedAnything = true;
15718 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15719 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15724 if (mPersistentStartingProcesses.size() > 0) {
15725 if (needSep) pw.println();
15727 printedAnything = true;
15728 pw.println(" Persisent processes that are starting:");
15729 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15730 "Starting Norm", "Restarting PERS", dumpPackage);
15733 if (mRemovedProcesses.size() > 0) {
15734 if (needSep) pw.println();
15736 printedAnything = true;
15737 pw.println(" Processes that are being removed:");
15738 dumpProcessList(pw, this, mRemovedProcesses, " ",
15739 "Removed Norm", "Removed PERS", dumpPackage);
15742 if (mProcessesOnHold.size() > 0) {
15743 if (needSep) pw.println();
15745 printedAnything = true;
15746 pw.println(" Processes that are on old until the system is ready:");
15747 dumpProcessList(pw, this, mProcessesOnHold, " ",
15748 "OnHold Norm", "OnHold PERS", dumpPackage);
15751 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15753 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15755 printedAnything = true;
15758 if (dumpPackage == null) {
15761 mUserController.dump(pw, dumpAll);
15763 if (mHomeProcess != null && (dumpPackage == null
15764 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15769 pw.println(" mHomeProcess: " + mHomeProcess);
15771 if (mPreviousProcess != null && (dumpPackage == null
15772 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15777 pw.println(" mPreviousProcess: " + mPreviousProcess);
15780 StringBuilder sb = new StringBuilder(128);
15781 sb.append(" mPreviousProcessVisibleTime: ");
15782 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15785 if (mHeavyWeightProcess != null && (dumpPackage == null
15786 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15791 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15793 if (dumpPackage == null) {
15794 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15795 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15798 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15799 if (mCompatModePackages.getPackages().size() > 0) {
15800 boolean printed = false;
15801 for (Map.Entry<String, Integer> entry
15802 : mCompatModePackages.getPackages().entrySet()) {
15803 String pkg = entry.getKey();
15804 int mode = entry.getValue();
15805 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15809 pw.println(" mScreenCompatPackages:");
15812 pw.print(" "); pw.print(pkg); pw.print(": ");
15813 pw.print(mode); pw.println();
15816 final int NI = mUidObservers.getRegisteredCallbackCount();
15817 boolean printed = false;
15818 for (int i=0; i<NI; i++) {
15819 final UidObserverRegistration reg = (UidObserverRegistration)
15820 mUidObservers.getRegisteredCallbackCookie(i);
15821 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15823 pw.println(" mUidObservers:");
15826 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15827 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15828 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15831 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15834 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15837 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15838 pw.print(" STATE");
15839 pw.print(" (cut="); pw.print(reg.cutpoint);
15843 if (reg.lastProcStates != null) {
15844 final int NJ = reg.lastProcStates.size();
15845 for (int j=0; j<NJ; j++) {
15846 pw.print(" Last ");
15847 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15848 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15853 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15854 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15855 if (mPendingTempWhitelist.size() > 0) {
15856 pw.println(" mPendingTempWhitelist:");
15857 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15858 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15860 UserHandle.formatUid(pw, ptw.targetUid);
15862 TimeUtils.formatDuration(ptw.duration, pw);
15864 pw.println(ptw.tag);
15868 if (dumpPackage == null) {
15869 pw.println(" mWakefulness="
15870 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15871 pw.println(" mSleepTokens=" + mSleepTokens);
15872 pw.println(" mSleeping=" + mSleeping);
15873 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15874 if (mRunningVoice != null) {
15875 pw.println(" mRunningVoice=" + mRunningVoice);
15876 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15879 pw.println(" mVrController=" + mVrController);
15880 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15881 || mOrigWaitForDebugger) {
15882 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15883 || dumpPackage.equals(mOrigDebugApp)) {
15888 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15889 + " mDebugTransient=" + mDebugTransient
15890 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15893 if (mCurAppTimeTracker != null) {
15894 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15896 if (mMemWatchProcesses.getMap().size() > 0) {
15897 pw.println(" Mem watch processes:");
15898 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15899 = mMemWatchProcesses.getMap();
15900 for (int i=0; i<procs.size(); i++) {
15901 final String proc = procs.keyAt(i);
15902 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15903 for (int j=0; j<uids.size(); j++) {
15908 StringBuilder sb = new StringBuilder();
15909 sb.append(" ").append(proc).append('/');
15910 UserHandle.formatUid(sb, uids.keyAt(j));
15911 Pair<Long, String> val = uids.valueAt(j);
15912 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15913 if (val.second != null) {
15914 sb.append(", report to ").append(val.second);
15916 pw.println(sb.toString());
15919 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15920 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15921 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15922 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15924 if (mTrackAllocationApp != null) {
15925 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15930 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15933 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15934 || mProfileFd != null) {
15935 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15940 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15941 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15942 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15943 + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15944 pw.println(" mProfileType=" + mProfileType);
15947 if (mNativeDebuggingApp != null) {
15948 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15953 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
15956 if (dumpPackage == null) {
15957 if (mAlwaysFinishActivities) {
15958 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15960 if (mController != null) {
15961 pw.println(" mController=" + mController
15962 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15965 pw.println(" Total persistent processes: " + numPers);
15966 pw.println(" mProcessesReady=" + mProcessesReady
15967 + " mSystemReady=" + mSystemReady
15968 + " mBooted=" + mBooted
15969 + " mFactoryTest=" + mFactoryTest);
15970 pw.println(" mBooting=" + mBooting
15971 + " mCallFinishBooting=" + mCallFinishBooting
15972 + " mBootAnimationComplete=" + mBootAnimationComplete);
15973 pw.print(" mLastPowerCheckRealtime=");
15974 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15976 pw.print(" mLastPowerCheckUptime=");
15977 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15979 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15980 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15981 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15982 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
15983 + " (" + mLruProcesses.size() + " total)"
15984 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15985 + " mNumServiceProcs=" + mNumServiceProcs
15986 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15987 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
15988 + " mLastMemoryLevel=" + mLastMemoryLevel
15989 + " mLastNumProcesses=" + mLastNumProcesses);
15990 long now = SystemClock.uptimeMillis();
15991 pw.print(" mLastIdleTime=");
15992 TimeUtils.formatDuration(now, mLastIdleTime, pw);
15993 pw.print(" mLowRamSinceLastIdle=");
15994 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15999 if (!printedAnything) {
16000 pw.println(" (nothing)");
16004 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16005 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16006 if (mProcessesToGc.size() > 0) {
16007 boolean printed = false;
16008 long now = SystemClock.uptimeMillis();
16009 for (int i=0; i<mProcessesToGc.size(); i++) {
16010 ProcessRecord proc = mProcessesToGc.get(i);
16011 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16015 if (needSep) pw.println();
16017 pw.println(" Processes that are waiting to GC:");
16020 pw.print(" Process "); pw.println(proc);
16021 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16022 pw.print(", last gced=");
16023 pw.print(now-proc.lastRequestedGc);
16024 pw.print(" ms ago, last lowMem=");
16025 pw.print(now-proc.lastLowMemory);
16026 pw.println(" ms ago");
16033 void printOomLevel(PrintWriter pw, String name, int adj) {
16037 if (adj < 10) pw.print(' ');
16039 if (adj > -10) pw.print(' ');
16045 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16049 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16050 int opti, boolean dumpAll) {
16051 boolean needSep = false;
16053 if (mLruProcesses.size() > 0) {
16054 if (needSep) pw.println();
16056 pw.println(" OOM levels:");
16057 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16058 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16059 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16060 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16061 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16062 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16063 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16064 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16065 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16066 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16067 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16068 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16069 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16070 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16072 if (needSep) pw.println();
16073 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16074 pw.print(" total, non-act at ");
16075 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16076 pw.print(", non-svc at ");
16077 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16079 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16083 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16086 pw.println(" mHomeProcess: " + mHomeProcess);
16087 pw.println(" mPreviousProcess: " + mPreviousProcess);
16088 if (mHeavyWeightProcess != null) {
16089 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16096 * There are three ways to call this:
16097 * - no provider specified: dump all the providers
16098 * - a flattened component name that matched an existing provider was specified as the
16099 * first arg: dump that one provider
16100 * - the first arg isn't the flattened component name of an existing provider:
16101 * dump all providers whose component contains the first arg as a substring
16103 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16104 int opti, boolean dumpAll) {
16105 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16108 static class ItemMatcher {
16109 ArrayList<ComponentName> components;
16110 ArrayList<String> strings;
16111 ArrayList<Integer> objects;
16118 void build(String name) {
16119 ComponentName componentName = ComponentName.unflattenFromString(name);
16120 if (componentName != null) {
16121 if (components == null) {
16122 components = new ArrayList<ComponentName>();
16124 components.add(componentName);
16128 // Not a '/' separated full component name; maybe an object ID?
16130 objectId = Integer.parseInt(name, 16);
16131 if (objects == null) {
16132 objects = new ArrayList<Integer>();
16134 objects.add(objectId);
16136 } catch (RuntimeException e) {
16137 // Not an integer; just do string match.
16138 if (strings == null) {
16139 strings = new ArrayList<String>();
16147 int build(String[] args, int opti) {
16148 for (; opti<args.length; opti++) {
16149 String name = args[opti];
16150 if ("--".equals(name)) {
16158 boolean match(Object object, ComponentName comp) {
16162 if (components != null) {
16163 for (int i=0; i<components.size(); i++) {
16164 if (components.get(i).equals(comp)) {
16169 if (objects != null) {
16170 for (int i=0; i<objects.size(); i++) {
16171 if (System.identityHashCode(object) == objects.get(i)) {
16176 if (strings != null) {
16177 String flat = comp.flattenToString();
16178 for (int i=0; i<strings.size(); i++) {
16179 if (flat.contains(strings.get(i))) {
16189 * There are three things that cmd can be:
16190 * - a flattened component name that matches an existing activity
16191 * - the cmd arg isn't the flattened component name of an existing activity:
16192 * dump all activity whose component contains the cmd as a substring
16193 * - A hex number of the ActivityRecord object instance.
16195 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16196 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16198 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16199 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16200 ArrayList<ActivityRecord> activities;
16202 synchronized (this) {
16203 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16204 dumpFocusedStackOnly);
16207 if (activities.size() <= 0) {
16211 String[] newArgs = new String[args.length - opti];
16212 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16214 TaskRecord lastTask = null;
16215 boolean needSep = false;
16216 for (int i=activities.size()-1; i>=0; i--) {
16217 ActivityRecord r = activities.get(i);
16222 synchronized (this) {
16223 final TaskRecord task = r.getTask();
16224 if (lastTask != task) {
16226 pw.print("TASK "); pw.print(lastTask.affinity);
16227 pw.print(" id="); pw.print(lastTask.taskId);
16228 pw.print(" userId="); pw.println(lastTask.userId);
16230 lastTask.dump(pw, " ");
16234 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16240 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16241 * there is a thread associated with the activity.
16243 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16244 final ActivityRecord r, String[] args, boolean dumpAll) {
16245 String innerPrefix = prefix + " ";
16246 synchronized (this) {
16247 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16248 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16250 if (r.app != null) pw.println(r.app.pid);
16251 else pw.println("(not running)");
16253 r.dump(pw, innerPrefix);
16256 if (r.app != null && r.app.thread != null) {
16257 // flush anything that is already in the PrintWriter since the thread is going
16258 // to write to the file descriptor directly
16261 TransferPipe tp = new TransferPipe();
16263 r.app.thread.dumpActivity(tp.getWriteFd(),
16264 r.appToken, innerPrefix, args);
16269 } catch (IOException e) {
16270 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16271 } catch (RemoteException e) {
16272 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16277 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16278 int opti, boolean dumpAll, String dumpPackage) {
16279 boolean needSep = false;
16280 boolean onlyHistory = false;
16281 boolean printedAnything = false;
16283 if ("history".equals(dumpPackage)) {
16284 if (opti < args.length && "-s".equals(args[opti])) {
16287 onlyHistory = true;
16288 dumpPackage = null;
16291 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16292 if (!onlyHistory && dumpAll) {
16293 if (mRegisteredReceivers.size() > 0) {
16294 boolean printed = false;
16295 Iterator it = mRegisteredReceivers.values().iterator();
16296 while (it.hasNext()) {
16297 ReceiverList r = (ReceiverList)it.next();
16298 if (dumpPackage != null && (r.app == null ||
16299 !dumpPackage.equals(r.app.info.packageName))) {
16303 pw.println(" Registered Receivers:");
16306 printedAnything = true;
16308 pw.print(" * "); pw.println(r);
16313 if (mReceiverResolver.dump(pw, needSep ?
16314 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16315 " ", dumpPackage, false, false)) {
16317 printedAnything = true;
16321 for (BroadcastQueue q : mBroadcastQueues) {
16322 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16323 printedAnything |= needSep;
16328 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16329 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16334 printedAnything = true;
16335 pw.print(" Sticky broadcasts for user ");
16336 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16337 StringBuilder sb = new StringBuilder(128);
16338 for (Map.Entry<String, ArrayList<Intent>> ent
16339 : mStickyBroadcasts.valueAt(user).entrySet()) {
16340 pw.print(" * Sticky action "); pw.print(ent.getKey());
16343 ArrayList<Intent> intents = ent.getValue();
16344 final int N = intents.size();
16345 for (int i=0; i<N; i++) {
16347 sb.append(" Intent: ");
16348 intents.get(i).toShortString(sb, false, true, false, false);
16349 pw.println(sb.toString());
16350 Bundle bundle = intents.get(i).getExtras();
16351 if (bundle != null) {
16353 pw.println(bundle.toString());
16363 if (!onlyHistory && dumpAll) {
16365 for (BroadcastQueue queue : mBroadcastQueues) {
16366 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16367 + queue.mBroadcastsScheduled);
16369 pw.println(" mHandler:");
16370 mHandler.dump(new PrintWriterPrinter(pw), " ");
16372 printedAnything = true;
16375 if (!printedAnything) {
16376 pw.println(" (nothing)");
16380 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16381 int opti, boolean dumpAll, String dumpPackage) {
16382 if (mCurBroadcastStats == null) {
16386 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16387 final long now = SystemClock.elapsedRealtime();
16388 if (mLastBroadcastStats != null) {
16389 pw.print(" Last stats (from ");
16390 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16392 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16394 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16395 - mLastBroadcastStats.mStartUptime, pw);
16396 pw.println(" uptime):");
16397 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16398 pw.println(" (nothing)");
16402 pw.print(" Current stats (from ");
16403 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16404 pw.print(" to now, ");
16405 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16406 - mCurBroadcastStats.mStartUptime, pw);
16407 pw.println(" uptime):");
16408 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16409 pw.println(" (nothing)");
16413 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16414 int opti, boolean fullCheckin, String dumpPackage) {
16415 if (mCurBroadcastStats == null) {
16419 if (mLastBroadcastStats != null) {
16420 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16422 mLastBroadcastStats = null;
16426 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16428 mCurBroadcastStats = null;
16432 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16433 int opti, boolean dumpAll, String dumpPackage) {
16435 boolean printedAnything = false;
16437 ItemMatcher matcher = new ItemMatcher();
16438 matcher.build(args, opti);
16440 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16442 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16443 printedAnything |= needSep;
16445 if (mLaunchingProviders.size() > 0) {
16446 boolean printed = false;
16447 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16448 ContentProviderRecord r = mLaunchingProviders.get(i);
16449 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16453 if (needSep) pw.println();
16455 pw.println(" Launching content providers:");
16457 printedAnything = true;
16459 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16464 if (!printedAnything) {
16465 pw.println(" (nothing)");
16469 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16470 int opti, boolean dumpAll, String dumpPackage) {
16471 boolean needSep = false;
16472 boolean printedAnything = false;
16474 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16476 if (mGrantedUriPermissions.size() > 0) {
16477 boolean printed = false;
16479 if (dumpPackage != null) {
16481 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16482 MATCH_ANY_USER, 0);
16483 } catch (NameNotFoundException e) {
16487 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16488 int uid = mGrantedUriPermissions.keyAt(i);
16489 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16492 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16494 if (needSep) pw.println();
16496 pw.println(" Granted Uri Permissions:");
16498 printedAnything = true;
16500 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16501 for (UriPermission perm : perms.values()) {
16502 pw.print(" "); pw.println(perm);
16504 perm.dump(pw, " ");
16510 if (!printedAnything) {
16511 pw.println(" (nothing)");
16515 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16516 int opti, boolean dumpAll, String dumpPackage) {
16517 boolean printed = false;
16519 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16521 if (mIntentSenderRecords.size() > 0) {
16522 // Organize these by package name, so they are easier to read.
16523 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16524 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16525 final Iterator<WeakReference<PendingIntentRecord>> it
16526 = mIntentSenderRecords.values().iterator();
16527 while (it.hasNext()) {
16528 WeakReference<PendingIntentRecord> ref = it.next();
16529 PendingIntentRecord rec = ref != null ? ref.get() : null;
16534 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16537 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16538 if (list == null) {
16539 list = new ArrayList<>();
16540 byPackage.put(rec.key.packageName, list);
16544 for (int i = 0; i < byPackage.size(); i++) {
16545 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16547 pw.print(" * "); pw.print(byPackage.keyAt(i));
16548 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16549 for (int j = 0; j < intents.size(); j++) {
16550 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16552 intents.get(j).dump(pw, " ");
16556 if (weakRefs.size() > 0) {
16558 pw.println(" * WEAK REFS:");
16559 for (int i = 0; i < weakRefs.size(); i++) {
16560 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16566 pw.println(" (nothing)");
16570 private static final int dumpProcessList(PrintWriter pw,
16571 ActivityManagerService service, List list,
16572 String prefix, String normalLabel, String persistentLabel,
16573 String dumpPackage) {
16575 final int N = list.size()-1;
16576 for (int i=N; i>=0; i--) {
16577 ProcessRecord r = (ProcessRecord)list.get(i);
16578 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16581 pw.println(String.format("%s%s #%2d: %s",
16582 prefix, (r.persistent ? persistentLabel : normalLabel),
16584 if (r.persistent) {
16591 private static final boolean dumpProcessOomList(PrintWriter pw,
16592 ActivityManagerService service, List<ProcessRecord> origList,
16593 String prefix, String normalLabel, String persistentLabel,
16594 boolean inclDetails, String dumpPackage) {
16596 ArrayList<Pair<ProcessRecord, Integer>> list
16597 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16598 for (int i=0; i<origList.size(); i++) {
16599 ProcessRecord r = origList.get(i);
16600 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16603 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16606 if (list.size() <= 0) {
16610 Comparator<Pair<ProcessRecord, Integer>> comparator
16611 = new Comparator<Pair<ProcessRecord, Integer>>() {
16613 public int compare(Pair<ProcessRecord, Integer> object1,
16614 Pair<ProcessRecord, Integer> object2) {
16615 if (object1.first.setAdj != object2.first.setAdj) {
16616 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16618 if (object1.first.setProcState != object2.first.setProcState) {
16619 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16621 if (object1.second.intValue() != object2.second.intValue()) {
16622 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16628 Collections.sort(list, comparator);
16630 final long curRealtime = SystemClock.elapsedRealtime();
16631 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16632 final long curUptime = SystemClock.uptimeMillis();
16633 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16635 for (int i=list.size()-1; i>=0; i--) {
16636 ProcessRecord r = list.get(i).first;
16637 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16639 switch (r.setSchedGroup) {
16640 case ProcessList.SCHED_GROUP_BACKGROUND:
16643 case ProcessList.SCHED_GROUP_DEFAULT:
16646 case ProcessList.SCHED_GROUP_TOP_APP:
16654 if (r.foregroundActivities) {
16656 } else if (r.foregroundServices) {
16661 String procState = ProcessList.makeProcStateString(r.curProcState);
16663 pw.print(r.persistent ? persistentLabel : normalLabel);
16665 int num = (origList.size()-1)-list.get(i).second;
16666 if (num < 10) pw.print(' ');
16671 pw.print(schedGroup);
16673 pw.print(foreground);
16675 pw.print(procState);
16677 if (r.trimMemoryLevel < 10) pw.print(' ');
16678 pw.print(r.trimMemoryLevel);
16680 pw.print(r.toShortString());
16682 pw.print(r.adjType);
16684 if (r.adjSource != null || r.adjTarget != null) {
16687 if (r.adjTarget instanceof ComponentName) {
16688 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16689 } else if (r.adjTarget != null) {
16690 pw.print(r.adjTarget.toString());
16692 pw.print("{null}");
16695 if (r.adjSource instanceof ProcessRecord) {
16697 pw.print(((ProcessRecord)r.adjSource).toShortString());
16699 } else if (r.adjSource != null) {
16700 pw.println(r.adjSource.toString());
16702 pw.println("{null}");
16708 pw.print("oom: max="); pw.print(r.maxAdj);
16709 pw.print(" curRaw="); pw.print(r.curRawAdj);
16710 pw.print(" setRaw="); pw.print(r.setRawAdj);
16711 pw.print(" cur="); pw.print(r.curAdj);
16712 pw.print(" set="); pw.println(r.setAdj);
16715 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16716 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16717 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16718 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16719 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16723 pw.print("cached="); pw.print(r.cached);
16724 pw.print(" empty="); pw.print(r.empty);
16725 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16727 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16728 if (r.lastWakeTime != 0) {
16730 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16731 synchronized (stats) {
16732 wtime = stats.getProcessWakeTime(r.info.uid,
16733 r.pid, curRealtime);
16735 long timeUsed = wtime - r.lastWakeTime;
16738 pw.print("keep awake over ");
16739 TimeUtils.formatDuration(realtimeSince, pw);
16740 pw.print(" used ");
16741 TimeUtils.formatDuration(timeUsed, pw);
16743 pw.print((timeUsed*100)/realtimeSince);
16746 if (r.lastCpuTime != 0) {
16747 long timeUsed = r.curCpuTime - r.lastCpuTime;
16750 pw.print("run cpu over ");
16751 TimeUtils.formatDuration(uptimeSince, pw);
16752 pw.print(" used ");
16753 TimeUtils.formatDuration(timeUsed, pw);
16755 pw.print((timeUsed*100)/uptimeSince);
16764 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16766 ArrayList<ProcessRecord> procs;
16767 synchronized (this) {
16768 if (args != null && args.length > start
16769 && args[start].charAt(0) != '-') {
16770 procs = new ArrayList<ProcessRecord>();
16773 pid = Integer.parseInt(args[start]);
16774 } catch (NumberFormatException e) {
16776 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16777 ProcessRecord proc = mLruProcesses.get(i);
16778 if (proc.pid == pid) {
16780 } else if (allPkgs && proc.pkgList != null
16781 && proc.pkgList.containsKey(args[start])) {
16783 } else if (proc.processName.equals(args[start])) {
16787 if (procs.size() <= 0) {
16791 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16797 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16798 PrintWriter pw, String[] args) {
16799 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16800 if (procs == null) {
16801 pw.println("No process found for: " + args[0]);
16805 long uptime = SystemClock.uptimeMillis();
16806 long realtime = SystemClock.elapsedRealtime();
16807 pw.println("Applications Graphics Acceleration Info:");
16808 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16810 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16811 ProcessRecord r = procs.get(i);
16812 if (r.thread != null) {
16813 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16816 TransferPipe tp = new TransferPipe();
16818 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16823 } catch (IOException e) {
16824 pw.println("Failure while dumping the app: " + r);
16826 } catch (RemoteException e) {
16827 pw.println("Got a RemoteException while dumping the app " + r);
16834 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16835 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16836 if (procs == null) {
16837 pw.println("No process found for: " + args[0]);
16841 pw.println("Applications Database Info:");
16843 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16844 ProcessRecord r = procs.get(i);
16845 if (r.thread != null) {
16846 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16849 TransferPipe tp = new TransferPipe();
16851 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16856 } catch (IOException e) {
16857 pw.println("Failure while dumping the app: " + r);
16859 } catch (RemoteException e) {
16860 pw.println("Got a RemoteException while dumping the app " + r);
16867 final static class MemItem {
16868 final boolean isProc;
16869 final String label;
16870 final String shortLabel;
16872 final long swapPss;
16874 final boolean hasActivities;
16875 ArrayList<MemItem> subitems;
16877 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16878 boolean _hasActivities) {
16881 shortLabel = _shortLabel;
16883 swapPss = _swapPss;
16885 hasActivities = _hasActivities;
16888 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16891 shortLabel = _shortLabel;
16893 swapPss = _swapPss;
16895 hasActivities = false;
16899 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16900 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16901 if (sort && !isCompact) {
16902 Collections.sort(items, new Comparator<MemItem>() {
16904 public int compare(MemItem lhs, MemItem rhs) {
16905 if (lhs.pss < rhs.pss) {
16907 } else if (lhs.pss > rhs.pss) {
16915 for (int i=0; i<items.size(); i++) {
16916 MemItem mi = items.get(i);
16919 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16920 mi.label, stringifyKBSize(mi.swapPss));
16922 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16924 } else if (mi.isProc) {
16925 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16926 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16927 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16928 pw.println(mi.hasActivities ? ",a" : ",e");
16930 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16931 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16933 if (mi.subitems != null) {
16934 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16935 true, isCompact, dumpSwapPss);
16940 // These are in KB.
16941 static final long[] DUMP_MEM_BUCKETS = new long[] {
16942 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16943 120*1024, 160*1024, 200*1024,
16944 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16945 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16948 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16949 boolean stackLike) {
16950 int start = label.lastIndexOf('.');
16951 if (start >= 0) start++;
16953 int end = label.length();
16954 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16955 if (DUMP_MEM_BUCKETS[i] >= memKB) {
16956 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16957 out.append(bucket);
16958 out.append(stackLike ? "MB." : "MB ");
16959 out.append(label, start, end);
16963 out.append(memKB/1024);
16964 out.append(stackLike ? "MB." : "MB ");
16965 out.append(label, start, end);
16968 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16969 ProcessList.NATIVE_ADJ,
16970 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16971 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16972 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16973 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16974 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16975 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16977 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16979 "System", "Persistent", "Persistent Service", "Foreground",
16980 "Visible", "Perceptible",
16981 "Heavy Weight", "Backup",
16982 "A Services", "Home",
16983 "Previous", "B Services", "Cached"
16985 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16987 "sys", "pers", "persvc", "fore",
16990 "servicea", "home",
16991 "prev", "serviceb", "cached"
16994 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16995 long realtime, boolean isCheckinRequest, boolean isCompact) {
16997 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16999 if (isCheckinRequest || isCompact) {
17000 // short checkin version
17001 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17003 pw.println("Applications Memory Usage (in Kilobytes):");
17004 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17008 private static final int KSM_SHARED = 0;
17009 private static final int KSM_SHARING = 1;
17010 private static final int KSM_UNSHARED = 2;
17011 private static final int KSM_VOLATILE = 3;
17013 private final long[] getKsmInfo() {
17014 long[] longOut = new long[4];
17015 final int[] SINGLE_LONG_FORMAT = new int[] {
17016 PROC_SPACE_TERM| PROC_OUT_LONG
17018 long[] longTmp = new long[1];
17019 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17020 SINGLE_LONG_FORMAT, null, longTmp, null);
17021 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17023 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17024 SINGLE_LONG_FORMAT, null, longTmp, null);
17025 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17027 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17028 SINGLE_LONG_FORMAT, null, longTmp, null);
17029 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17031 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17032 SINGLE_LONG_FORMAT, null, longTmp, null);
17033 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17037 private static String stringifySize(long size, int order) {
17038 Locale locale = Locale.US;
17041 return String.format(locale, "%,13d", size);
17043 return String.format(locale, "%,9dK", size / 1024);
17045 return String.format(locale, "%,5dM", size / 1024 / 1024);
17046 case 1024 * 1024 * 1024:
17047 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17049 throw new IllegalArgumentException("Invalid size order");
17053 private static String stringifyKBSize(long size) {
17054 return stringifySize(size * 1024, 1024);
17057 // Update this version number in case you change the 'compact' format
17058 private static final int MEMINFO_COMPACT_VERSION = 1;
17060 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17061 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17062 boolean dumpDetails = false;
17063 boolean dumpFullDetails = false;
17064 boolean dumpDalvik = false;
17065 boolean dumpSummaryOnly = false;
17066 boolean dumpUnreachable = false;
17067 boolean oomOnly = false;
17068 boolean isCompact = false;
17069 boolean localOnly = false;
17070 boolean packages = false;
17071 boolean isCheckinRequest = false;
17072 boolean dumpSwapPss = false;
17075 while (opti < args.length) {
17076 String opt = args[opti];
17077 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17081 if ("-a".equals(opt)) {
17082 dumpDetails = true;
17083 dumpFullDetails = true;
17085 dumpSwapPss = true;
17086 } else if ("-d".equals(opt)) {
17088 } else if ("-c".equals(opt)) {
17090 } else if ("-s".equals(opt)) {
17091 dumpDetails = true;
17092 dumpSummaryOnly = true;
17093 } else if ("-S".equals(opt)) {
17094 dumpSwapPss = true;
17095 } else if ("--unreachable".equals(opt)) {
17096 dumpUnreachable = true;
17097 } else if ("--oom".equals(opt)) {
17099 } else if ("--local".equals(opt)) {
17101 } else if ("--package".equals(opt)) {
17103 } else if ("--checkin".equals(opt)) {
17104 isCheckinRequest = true;
17106 } else if ("-h".equals(opt)) {
17107 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17108 pw.println(" -a: include all available information for each process.");
17109 pw.println(" -d: include dalvik details.");
17110 pw.println(" -c: dump in a compact machine-parseable representation.");
17111 pw.println(" -s: dump only summary of application memory usage.");
17112 pw.println(" -S: dump also SwapPss.");
17113 pw.println(" --oom: only show processes organized by oom adj.");
17114 pw.println(" --local: only collect details locally, don't call process.");
17115 pw.println(" --package: interpret process arg as package, dumping all");
17116 pw.println(" processes that have loaded that package.");
17117 pw.println(" --checkin: dump data for a checkin");
17118 pw.println("If [process] is specified it can be the name or ");
17119 pw.println("pid of a specific process to dump.");
17122 pw.println("Unknown argument: " + opt + "; use -h for help");
17126 long uptime = SystemClock.uptimeMillis();
17127 long realtime = SystemClock.elapsedRealtime();
17128 final long[] tmpLong = new long[1];
17130 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17131 if (procs == null) {
17132 // No Java processes. Maybe they want to print a native process.
17133 if (args != null && args.length > opti
17134 && args[opti].charAt(0) != '-') {
17135 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17136 = new ArrayList<ProcessCpuTracker.Stats>();
17137 updateCpuStatsNow();
17140 findPid = Integer.parseInt(args[opti]);
17141 } catch (NumberFormatException e) {
17143 synchronized (mProcessCpuTracker) {
17144 final int N = mProcessCpuTracker.countStats();
17145 for (int i=0; i<N; i++) {
17146 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17147 if (st.pid == findPid || (st.baseName != null
17148 && st.baseName.equals(args[opti]))) {
17149 nativeProcs.add(st);
17153 if (nativeProcs.size() > 0) {
17154 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17156 Debug.MemoryInfo mi = null;
17157 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17158 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17159 final int pid = r.pid;
17160 if (!isCheckinRequest && dumpDetails) {
17161 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17164 mi = new Debug.MemoryInfo();
17166 if (dumpDetails || (!brief && !oomOnly)) {
17167 Debug.getMemoryInfo(pid, mi);
17169 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17170 mi.dalvikPrivateDirty = (int)tmpLong[0];
17172 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17173 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17174 if (isCheckinRequest) {
17181 pw.println("No process found for: " + args[opti]);
17185 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17186 dumpDetails = true;
17189 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17191 String[] innerArgs = new String[args.length-opti];
17192 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17194 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17195 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17196 long nativePss = 0;
17197 long nativeSwapPss = 0;
17198 long dalvikPss = 0;
17199 long dalvikSwapPss = 0;
17200 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17202 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17205 long otherSwapPss = 0;
17206 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17207 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17209 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17210 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17211 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17212 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17215 long totalSwapPss = 0;
17216 long cachedPss = 0;
17217 long cachedSwapPss = 0;
17218 boolean hasSwapPss = false;
17220 Debug.MemoryInfo mi = null;
17221 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17222 final ProcessRecord r = procs.get(i);
17223 final IApplicationThread thread;
17226 final boolean hasActivities;
17227 synchronized (this) {
17230 oomAdj = r.getSetAdjWithServices();
17231 hasActivities = r.activities.size() > 0;
17233 if (thread != null) {
17234 if (!isCheckinRequest && dumpDetails) {
17235 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17238 mi = new Debug.MemoryInfo();
17240 if (dumpDetails || (!brief && !oomOnly)) {
17241 Debug.getMemoryInfo(pid, mi);
17242 hasSwapPss = mi.hasSwappedOutPss;
17244 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17245 mi.dalvikPrivateDirty = (int)tmpLong[0];
17249 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17250 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17251 if (isCheckinRequest) {
17257 TransferPipe tp = new TransferPipe();
17259 thread.dumpMemInfo(tp.getWriteFd(),
17260 mi, isCheckinRequest, dumpFullDetails,
17261 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17266 } catch (IOException e) {
17267 if (!isCheckinRequest) {
17268 pw.println("Got IoException!");
17271 } catch (RemoteException e) {
17272 if (!isCheckinRequest) {
17273 pw.println("Got RemoteException!");
17280 final long myTotalPss = mi.getTotalPss();
17281 final long myTotalUss = mi.getTotalUss();
17282 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17284 synchronized (this) {
17285 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17286 // Record this for posterity if the process has been stable.
17287 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17291 if (!isCheckinRequest && mi != null) {
17292 totalPss += myTotalPss;
17293 totalSwapPss += myTotalSwapPss;
17294 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17295 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17296 myTotalSwapPss, pid, hasActivities);
17297 procMems.add(pssItem);
17298 procMemsMap.put(pid, pssItem);
17300 nativePss += mi.nativePss;
17301 nativeSwapPss += mi.nativeSwappedOutPss;
17302 dalvikPss += mi.dalvikPss;
17303 dalvikSwapPss += mi.dalvikSwappedOutPss;
17304 for (int j=0; j<dalvikSubitemPss.length; j++) {
17305 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17306 dalvikSubitemSwapPss[j] +=
17307 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17309 otherPss += mi.otherPss;
17310 otherSwapPss += mi.otherSwappedOutPss;
17311 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17312 long mem = mi.getOtherPss(j);
17315 mem = mi.getOtherSwappedOutPss(j);
17316 miscSwapPss[j] += mem;
17317 otherSwapPss -= mem;
17320 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17321 cachedPss += myTotalPss;
17322 cachedSwapPss += myTotalSwapPss;
17325 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17326 if (oomIndex == (oomPss.length - 1)
17327 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17328 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17329 oomPss[oomIndex] += myTotalPss;
17330 oomSwapPss[oomIndex] += myTotalSwapPss;
17331 if (oomProcs[oomIndex] == null) {
17332 oomProcs[oomIndex] = new ArrayList<MemItem>();
17334 oomProcs[oomIndex].add(pssItem);
17342 long nativeProcTotalPss = 0;
17344 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17345 // If we are showing aggregations, also look for native processes to
17346 // include so that our aggregations are more accurate.
17347 updateCpuStatsNow();
17349 synchronized (mProcessCpuTracker) {
17350 final int N = mProcessCpuTracker.countStats();
17351 for (int i=0; i<N; i++) {
17352 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17353 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17355 mi = new Debug.MemoryInfo();
17357 if (!brief && !oomOnly) {
17358 Debug.getMemoryInfo(st.pid, mi);
17360 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17361 mi.nativePrivateDirty = (int)tmpLong[0];
17364 final long myTotalPss = mi.getTotalPss();
17365 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17366 totalPss += myTotalPss;
17367 nativeProcTotalPss += myTotalPss;
17369 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17370 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17371 procMems.add(pssItem);
17373 nativePss += mi.nativePss;
17374 nativeSwapPss += mi.nativeSwappedOutPss;
17375 dalvikPss += mi.dalvikPss;
17376 dalvikSwapPss += mi.dalvikSwappedOutPss;
17377 for (int j=0; j<dalvikSubitemPss.length; j++) {
17378 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17379 dalvikSubitemSwapPss[j] +=
17380 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17382 otherPss += mi.otherPss;
17383 otherSwapPss += mi.otherSwappedOutPss;
17384 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17385 long mem = mi.getOtherPss(j);
17388 mem = mi.getOtherSwappedOutPss(j);
17389 miscSwapPss[j] += mem;
17390 otherSwapPss -= mem;
17392 oomPss[0] += myTotalPss;
17393 oomSwapPss[0] += myTotalSwapPss;
17394 if (oomProcs[0] == null) {
17395 oomProcs[0] = new ArrayList<MemItem>();
17397 oomProcs[0].add(pssItem);
17402 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17404 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17405 final MemItem dalvikItem =
17406 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17407 if (dalvikSubitemPss.length > 0) {
17408 dalvikItem.subitems = new ArrayList<MemItem>();
17409 for (int j=0; j<dalvikSubitemPss.length; j++) {
17410 final String name = Debug.MemoryInfo.getOtherLabel(
17411 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17412 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17413 dalvikSubitemSwapPss[j], j));
17416 catMems.add(dalvikItem);
17417 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17418 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17419 String label = Debug.MemoryInfo.getOtherLabel(j);
17420 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17423 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17424 for (int j=0; j<oomPss.length; j++) {
17425 if (oomPss[j] != 0) {
17426 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17427 : DUMP_MEM_OOM_LABEL[j];
17428 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17429 DUMP_MEM_OOM_ADJ[j]);
17430 item.subitems = oomProcs[j];
17435 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17436 if (!brief && !oomOnly && !isCompact) {
17438 pw.println("Total PSS by process:");
17439 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17443 pw.println("Total PSS by OOM adjustment:");
17445 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17446 if (!brief && !oomOnly) {
17447 PrintWriter out = categoryPw != null ? categoryPw : pw;
17450 out.println("Total PSS by category:");
17452 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17457 MemInfoReader memInfo = new MemInfoReader();
17458 memInfo.readMemInfo();
17459 if (nativeProcTotalPss > 0) {
17460 synchronized (this) {
17461 final long cachedKb = memInfo.getCachedSizeKb();
17462 final long freeKb = memInfo.getFreeSizeKb();
17463 final long zramKb = memInfo.getZramTotalSizeKb();
17464 final long kernelKb = memInfo.getKernelUsedSizeKb();
17465 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17466 kernelKb*1024, nativeProcTotalPss*1024);
17467 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17468 nativeProcTotalPss);
17473 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17474 pw.print(" (status ");
17475 switch (mLastMemoryLevel) {
17476 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17477 pw.println("normal)");
17479 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17480 pw.println("moderate)");
17482 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17483 pw.println("low)");
17485 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17486 pw.println("critical)");
17489 pw.print(mLastMemoryLevel);
17493 pw.print(" Free RAM: ");
17494 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17495 + memInfo.getFreeSizeKb()));
17497 pw.print(stringifyKBSize(cachedPss));
17498 pw.print(" cached pss + ");
17499 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17500 pw.print(" cached kernel + ");
17501 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17502 pw.println(" free)");
17504 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17505 pw.print(cachedPss + memInfo.getCachedSizeKb()
17506 + memInfo.getFreeSizeKb()); pw.print(",");
17507 pw.println(totalPss - cachedPss);
17510 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17511 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17512 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17514 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17515 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17516 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17517 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17518 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17520 pw.print("lostram,"); pw.println(lostRAM);
17523 if (memInfo.getZramTotalSizeKb() != 0) {
17525 pw.print(" ZRAM: ");
17526 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17527 pw.print(" physical used for ");
17528 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17529 - memInfo.getSwapFreeSizeKb()));
17530 pw.print(" in swap (");
17531 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17532 pw.println(" total swap)");
17534 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17535 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17536 pw.println(memInfo.getSwapFreeSizeKb());
17539 final long[] ksm = getKsmInfo();
17541 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17542 || ksm[KSM_VOLATILE] != 0) {
17543 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17544 pw.print(" saved from shared ");
17545 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17546 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17547 pw.print(" unshared; ");
17548 pw.print(stringifyKBSize(
17549 ksm[KSM_VOLATILE])); pw.println(" volatile");
17551 pw.print(" Tuning: ");
17552 pw.print(ActivityManager.staticGetMemoryClass());
17553 pw.print(" (large ");
17554 pw.print(ActivityManager.staticGetLargeMemoryClass());
17555 pw.print("), oom ");
17556 pw.print(stringifySize(
17557 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17558 pw.print(", restore limit ");
17559 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17560 if (ActivityManager.isLowRamDeviceStatic()) {
17561 pw.print(" (low-ram)");
17563 if (ActivityManager.isHighEndGfx()) {
17564 pw.print(" (high-end-gfx)");
17568 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17569 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17570 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17571 pw.print("tuning,");
17572 pw.print(ActivityManager.staticGetMemoryClass());
17574 pw.print(ActivityManager.staticGetLargeMemoryClass());
17576 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17577 if (ActivityManager.isLowRamDeviceStatic()) {
17578 pw.print(",low-ram");
17580 if (ActivityManager.isHighEndGfx()) {
17581 pw.print(",high-end-gfx");
17589 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17590 long memtrack, String name) {
17592 sb.append(ProcessList.makeOomAdjString(oomAdj));
17594 sb.append(ProcessList.makeProcStateString(procState));
17596 ProcessList.appendRamKb(sb, pss);
17599 if (memtrack > 0) {
17601 sb.append(stringifyKBSize(memtrack));
17602 sb.append(" memtrack)");
17606 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17607 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17608 sb.append(" (pid ");
17611 sb.append(mi.adjType);
17613 if (mi.adjReason != null) {
17615 sb.append(mi.adjReason);
17620 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17621 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17622 for (int i=0, N=memInfos.size(); i<N; i++) {
17623 ProcessMemInfo mi = memInfos.get(i);
17624 infoMap.put(mi.pid, mi);
17626 updateCpuStatsNow();
17627 long[] memtrackTmp = new long[1];
17628 final List<ProcessCpuTracker.Stats> stats;
17629 // Get a list of Stats that have vsize > 0
17630 synchronized (mProcessCpuTracker) {
17631 stats = mProcessCpuTracker.getStats((st) -> {
17632 return st.vsize > 0;
17635 final int statsCount = stats.size();
17636 for (int i = 0; i < statsCount; i++) {
17637 ProcessCpuTracker.Stats st = stats.get(i);
17638 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17640 if (infoMap.indexOfKey(st.pid) < 0) {
17641 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17642 ProcessList.NATIVE_ADJ, -1, "native", null);
17644 mi.memtrack = memtrackTmp[0];
17651 long totalMemtrack = 0;
17652 for (int i=0, N=memInfos.size(); i<N; i++) {
17653 ProcessMemInfo mi = memInfos.get(i);
17655 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17656 mi.memtrack = memtrackTmp[0];
17658 totalPss += mi.pss;
17659 totalMemtrack += mi.memtrack;
17661 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17662 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17663 if (lhs.oomAdj != rhs.oomAdj) {
17664 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17666 if (lhs.pss != rhs.pss) {
17667 return lhs.pss < rhs.pss ? 1 : -1;
17673 StringBuilder tag = new StringBuilder(128);
17674 StringBuilder stack = new StringBuilder(128);
17675 tag.append("Low on memory -- ");
17676 appendMemBucket(tag, totalPss, "total", false);
17677 appendMemBucket(stack, totalPss, "total", true);
17679 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17680 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17681 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17683 boolean firstLine = true;
17684 int lastOomAdj = Integer.MIN_VALUE;
17685 long extraNativeRam = 0;
17686 long extraNativeMemtrack = 0;
17687 long cachedPss = 0;
17688 for (int i=0, N=memInfos.size(); i<N; i++) {
17689 ProcessMemInfo mi = memInfos.get(i);
17691 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17692 cachedPss += mi.pss;
17695 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17696 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17697 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17698 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17699 if (lastOomAdj != mi.oomAdj) {
17700 lastOomAdj = mi.oomAdj;
17701 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17704 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17709 stack.append("\n\t at ");
17717 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17718 appendMemBucket(tag, mi.pss, mi.name, false);
17720 appendMemBucket(stack, mi.pss, mi.name, true);
17721 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17722 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17724 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17725 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17726 stack.append(DUMP_MEM_OOM_LABEL[k]);
17728 stack.append(DUMP_MEM_OOM_ADJ[k]);
17735 appendMemInfo(fullNativeBuilder, mi);
17736 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17737 // The short form only has native processes that are >= 512K.
17738 if (mi.pss >= 512) {
17739 appendMemInfo(shortNativeBuilder, mi);
17741 extraNativeRam += mi.pss;
17742 extraNativeMemtrack += mi.memtrack;
17745 // Short form has all other details, but if we have collected RAM
17746 // from smaller native processes let's dump a summary of that.
17747 if (extraNativeRam > 0) {
17748 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17749 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17750 shortNativeBuilder.append('\n');
17751 extraNativeRam = 0;
17753 appendMemInfo(fullJavaBuilder, mi);
17757 fullJavaBuilder.append(" ");
17758 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17759 fullJavaBuilder.append(": TOTAL");
17760 if (totalMemtrack > 0) {
17761 fullJavaBuilder.append(" (");
17762 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17763 fullJavaBuilder.append(" memtrack)");
17766 fullJavaBuilder.append("\n");
17768 MemInfoReader memInfo = new MemInfoReader();
17769 memInfo.readMemInfo();
17770 final long[] infos = memInfo.getRawInfo();
17772 StringBuilder memInfoBuilder = new StringBuilder(1024);
17773 Debug.getMemInfo(infos);
17774 memInfoBuilder.append(" MemInfo: ");
17775 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17776 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17777 memInfoBuilder.append(stringifyKBSize(
17778 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17779 memInfoBuilder.append(stringifyKBSize(
17780 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17781 memInfoBuilder.append(stringifyKBSize(
17782 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17783 memInfoBuilder.append(" ");
17784 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17785 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17786 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17787 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17788 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17789 memInfoBuilder.append(" ZRAM: ");
17790 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17791 memInfoBuilder.append(" RAM, ");
17792 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17793 memInfoBuilder.append(" swap total, ");
17794 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17795 memInfoBuilder.append(" swap free\n");
17797 final long[] ksm = getKsmInfo();
17798 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17799 || ksm[KSM_VOLATILE] != 0) {
17800 memInfoBuilder.append(" KSM: ");
17801 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17802 memInfoBuilder.append(" saved from shared ");
17803 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17804 memInfoBuilder.append("\n ");
17805 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17806 memInfoBuilder.append(" unshared; ");
17807 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17808 memInfoBuilder.append(" volatile\n");
17810 memInfoBuilder.append(" Free RAM: ");
17811 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17812 + memInfo.getFreeSizeKb()));
17813 memInfoBuilder.append("\n");
17814 memInfoBuilder.append(" Used RAM: ");
17815 memInfoBuilder.append(stringifyKBSize(
17816 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17817 memInfoBuilder.append("\n");
17818 memInfoBuilder.append(" Lost RAM: ");
17819 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17820 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17821 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17822 memInfoBuilder.append("\n");
17823 Slog.i(TAG, "Low on memory:");
17824 Slog.i(TAG, shortNativeBuilder.toString());
17825 Slog.i(TAG, fullJavaBuilder.toString());
17826 Slog.i(TAG, memInfoBuilder.toString());
17828 StringBuilder dropBuilder = new StringBuilder(1024);
17830 StringWriter oomSw = new StringWriter();
17831 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17832 StringWriter catSw = new StringWriter();
17833 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17834 String[] emptyArgs = new String[] { };
17835 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17837 String oomString = oomSw.toString();
17839 dropBuilder.append("Low on memory:");
17840 dropBuilder.append(stack);
17841 dropBuilder.append('\n');
17842 dropBuilder.append(fullNativeBuilder);
17843 dropBuilder.append(fullJavaBuilder);
17844 dropBuilder.append('\n');
17845 dropBuilder.append(memInfoBuilder);
17846 dropBuilder.append('\n');
17848 dropBuilder.append(oomString);
17849 dropBuilder.append('\n');
17851 StringWriter catSw = new StringWriter();
17852 synchronized (ActivityManagerService.this) {
17853 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17854 String[] emptyArgs = new String[] { };
17856 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17858 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17859 false, null).dumpLocked();
17861 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17864 dropBuilder.append(catSw.toString());
17865 addErrorToDropBox("lowmem", null, "system_server", null,
17866 null, tag.toString(), dropBuilder.toString(), null, null);
17867 //Slog.i(TAG, "Sent to dropbox:");
17868 //Slog.i(TAG, dropBuilder.toString());
17869 synchronized (ActivityManagerService.this) {
17870 long now = SystemClock.uptimeMillis();
17871 if (mLastMemUsageReportTime < now) {
17872 mLastMemUsageReportTime = now;
17878 * Searches array of arguments for the specified string
17879 * @param args array of argument strings
17880 * @param value value to search for
17881 * @return true if the value is contained in the array
17883 private static boolean scanArgs(String[] args, String value) {
17884 if (args != null) {
17885 for (String arg : args) {
17886 if (value.equals(arg)) {
17894 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17895 ContentProviderRecord cpr, boolean always) {
17896 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17898 if (!inLaunching || always) {
17899 synchronized (cpr) {
17900 cpr.launchingApp = null;
17903 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17904 String names[] = cpr.info.authority.split(";");
17905 for (int j = 0; j < names.length; j++) {
17906 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17910 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17911 ContentProviderConnection conn = cpr.connections.get(i);
17912 if (conn.waiting) {
17913 // If this connection is waiting for the provider, then we don't
17914 // need to mess with its process unless we are always removing
17915 // or for some reason the provider is not currently launching.
17916 if (inLaunching && !always) {
17920 ProcessRecord capp = conn.client;
17922 if (conn.stableCount > 0) {
17923 if (!capp.persistent && capp.thread != null
17925 && capp.pid != MY_PID) {
17926 capp.kill("depends on provider "
17927 + cpr.name.flattenToShortString()
17928 + " in dying proc " + (proc != null ? proc.processName : "??")
17929 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17931 } else if (capp.thread != null && conn.provider.provider != null) {
17933 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17934 } catch (RemoteException e) {
17936 // In the protocol here, we don't expect the client to correctly
17937 // clean up this connection, we'll just remove it.
17938 cpr.connections.remove(i);
17939 if (conn.client.conProviders.remove(conn)) {
17940 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17945 if (inLaunching && always) {
17946 mLaunchingProviders.remove(cpr);
17948 return inLaunching;
17952 * Main code for cleaning up a process when it has gone away. This is
17953 * called both as a result of the process dying, or directly when stopping
17954 * a process when running in single process mode.
17956 * @return Returns true if the given process has been restarted, so the
17957 * app that was passed in must remain on the process lists.
17959 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17960 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17962 removeLruProcessLocked(app);
17963 ProcessList.remove(app.pid);
17966 mProcessesToGc.remove(app);
17967 mPendingPssProcesses.remove(app);
17969 // Dismiss any open dialogs.
17970 if (app.crashDialog != null && !app.forceCrashReport) {
17971 app.crashDialog.dismiss();
17972 app.crashDialog = null;
17974 if (app.anrDialog != null) {
17975 app.anrDialog.dismiss();
17976 app.anrDialog = null;
17978 if (app.waitDialog != null) {
17979 app.waitDialog.dismiss();
17980 app.waitDialog = null;
17983 app.crashing = false;
17984 app.notResponding = false;
17986 app.resetPackageList(mProcessStats);
17987 app.unlinkDeathRecipient();
17988 app.makeInactive(mProcessStats);
17989 app.waitingToKill = null;
17990 app.forcingToImportant = null;
17991 updateProcessForegroundLocked(app, false, false);
17992 app.foregroundActivities = false;
17993 app.hasShownUi = false;
17994 app.treatLikeActivity = false;
17995 app.hasAboveClient = false;
17996 app.hasClientActivities = false;
17998 mServices.killServicesLocked(app, allowRestart);
18000 boolean restart = false;
18002 // Remove published content providers.
18003 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18004 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18005 final boolean always = app.bad || !allowRestart;
18006 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18007 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18008 // We left the provider in the launching list, need to
18013 cpr.provider = null;
18016 app.pubProviders.clear();
18018 // Take care of any launching providers waiting for this process.
18019 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18023 // Unregister from connected content providers.
18024 if (!app.conProviders.isEmpty()) {
18025 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18026 ContentProviderConnection conn = app.conProviders.get(i);
18027 conn.provider.connections.remove(conn);
18028 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18029 conn.provider.name);
18031 app.conProviders.clear();
18034 // At this point there may be remaining entries in mLaunchingProviders
18035 // where we were the only one waiting, so they are no longer of use.
18036 // Look for these and clean up if found.
18037 // XXX Commented out for now. Trying to figure out a way to reproduce
18038 // the actual situation to identify what is actually going on.
18040 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18041 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18042 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18043 synchronized (cpr) {
18044 cpr.launchingApp = null;
18051 skipCurrentReceiverLocked(app);
18053 // Unregister any receivers.
18054 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18055 removeReceiverLocked(app.receivers.valueAt(i));
18057 app.receivers.clear();
18059 // If the app is undergoing backup, tell the backup manager about it
18060 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18061 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18062 + mBackupTarget.appInfo + " died during backup");
18063 mHandler.post(new Runnable() {
18067 IBackupManager bm = IBackupManager.Stub.asInterface(
18068 ServiceManager.getService(Context.BACKUP_SERVICE));
18069 bm.agentDisconnected(app.info.packageName);
18070 } catch (RemoteException e) {
18071 // can't happen; backup manager is local
18077 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18078 ProcessChangeItem item = mPendingProcessChanges.get(i);
18079 if (item.pid == app.pid) {
18080 mPendingProcessChanges.remove(i);
18081 mAvailProcessChanges.add(item);
18084 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18085 null).sendToTarget();
18087 // If the caller is restarting this app, then leave it in its
18088 // current lists and let the caller take care of it.
18093 if (!app.persistent || app.isolated) {
18094 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18095 "Removing non-persistent process during cleanup: " + app);
18096 if (!replacingPid) {
18097 removeProcessNameLocked(app.processName, app.uid, app);
18099 if (mHeavyWeightProcess == app) {
18100 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18101 mHeavyWeightProcess.userId, 0));
18102 mHeavyWeightProcess = null;
18104 } else if (!app.removed) {
18105 // This app is persistent, so we need to keep its record around.
18106 // If it is not already on the pending app list, add it there
18107 // and start a new process for it.
18108 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18109 mPersistentStartingProcesses.add(app);
18113 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18114 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18115 mProcessesOnHold.remove(app);
18117 if (app == mHomeProcess) {
18118 mHomeProcess = null;
18120 if (app == mPreviousProcess) {
18121 mPreviousProcess = null;
18124 if (restart && !app.isolated) {
18125 // We have components that still need to be running in the
18126 // process, so re-launch it.
18128 ProcessList.remove(app.pid);
18130 addProcessNameLocked(app);
18131 startProcessLocked(app, "restart", app.processName);
18133 } else if (app.pid > 0 && app.pid != MY_PID) {
18136 synchronized (mPidsSelfLocked) {
18137 mPidsSelfLocked.remove(app.pid);
18138 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18140 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18141 if (app.isolated) {
18142 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18149 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18150 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18151 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18152 if (cpr.launchingApp == app) {
18159 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18160 // Look through the content providers we are waiting to have launched,
18161 // and if any run in this process then either schedule a restart of
18162 // the process or kill the client waiting for it if this process has
18164 boolean restart = false;
18165 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18166 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18167 if (cpr.launchingApp == app) {
18168 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18171 removeDyingProviderLocked(app, cpr, true);
18178 // =========================================================
18180 // =========================================================
18183 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18185 enforceNotIsolatedCaller("getServices");
18187 final int callingUid = Binder.getCallingUid();
18188 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18189 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18190 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18192 synchronized (this) {
18193 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18194 allowed, canInteractAcrossUsers);
18199 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18200 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18201 synchronized (this) {
18202 return mServices.getRunningServiceControlPanelLocked(name);
18207 public ComponentName startService(IApplicationThread caller, Intent service,
18208 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18209 throws TransactionTooLargeException {
18210 enforceNotIsolatedCaller("startService");
18211 // Refuse possible leaked file descriptors
18212 if (service != null && service.hasFileDescriptors() == true) {
18213 throw new IllegalArgumentException("File descriptors passed in Intent");
18216 if (callingPackage == null) {
18217 throw new IllegalArgumentException("callingPackage cannot be null");
18220 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18221 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18222 synchronized(this) {
18223 final int callingPid = Binder.getCallingPid();
18224 final int callingUid = Binder.getCallingUid();
18225 final long origId = Binder.clearCallingIdentity();
18228 res = mServices.startServiceLocked(caller, service,
18229 resolvedType, callingPid, callingUid,
18230 requireForeground, callingPackage, userId);
18232 Binder.restoreCallingIdentity(origId);
18238 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18239 boolean fgRequired, String callingPackage, int userId)
18240 throws TransactionTooLargeException {
18241 synchronized(this) {
18242 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18243 "startServiceInPackage: " + service + " type=" + resolvedType);
18244 final long origId = Binder.clearCallingIdentity();
18247 res = mServices.startServiceLocked(null, service,
18248 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18250 Binder.restoreCallingIdentity(origId);
18257 public int stopService(IApplicationThread caller, Intent service,
18258 String resolvedType, int userId) {
18259 enforceNotIsolatedCaller("stopService");
18260 // Refuse possible leaked file descriptors
18261 if (service != null && service.hasFileDescriptors() == true) {
18262 throw new IllegalArgumentException("File descriptors passed in Intent");
18265 synchronized(this) {
18266 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18271 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18272 enforceNotIsolatedCaller("peekService");
18273 // Refuse possible leaked file descriptors
18274 if (service != null && service.hasFileDescriptors() == true) {
18275 throw new IllegalArgumentException("File descriptors passed in Intent");
18278 if (callingPackage == null) {
18279 throw new IllegalArgumentException("callingPackage cannot be null");
18282 synchronized(this) {
18283 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18288 public boolean stopServiceToken(ComponentName className, IBinder token,
18290 synchronized(this) {
18291 return mServices.stopServiceTokenLocked(className, token, startId);
18296 public void setServiceForeground(ComponentName className, IBinder token,
18297 int id, Notification notification, int flags) {
18298 synchronized(this) {
18299 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18304 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18305 boolean requireFull, String name, String callerPackage) {
18306 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18307 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18310 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18311 String className, int flags) {
18312 boolean result = false;
18313 // For apps that don't have pre-defined UIDs, check for permission
18314 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18315 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18316 if (ActivityManager.checkUidPermission(
18317 INTERACT_ACROSS_USERS,
18318 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18319 ComponentName comp = new ComponentName(aInfo.packageName, className);
18320 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18321 + " requests FLAG_SINGLE_USER, but app does not hold "
18322 + INTERACT_ACROSS_USERS;
18324 throw new SecurityException(msg);
18326 // Permission passed
18329 } else if ("system".equals(componentProcessName)) {
18331 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18332 // Phone app and persistent apps are allowed to export singleuser providers.
18333 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18334 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18336 if (DEBUG_MU) Slog.v(TAG_MU,
18337 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18338 + Integer.toHexString(flags) + ") = " + result);
18343 * Checks to see if the caller is in the same app as the singleton
18344 * component, or the component is in a special app. It allows special apps
18345 * to export singleton components but prevents exporting singleton
18346 * components for regular apps.
18348 boolean isValidSingletonCall(int callingUid, int componentUid) {
18349 int componentAppId = UserHandle.getAppId(componentUid);
18350 return UserHandle.isSameApp(callingUid, componentUid)
18351 || componentAppId == SYSTEM_UID
18352 || componentAppId == PHONE_UID
18353 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18354 == PackageManager.PERMISSION_GRANTED;
18357 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18358 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18359 int userId) throws TransactionTooLargeException {
18360 enforceNotIsolatedCaller("bindService");
18362 // Refuse possible leaked file descriptors
18363 if (service != null && service.hasFileDescriptors() == true) {
18364 throw new IllegalArgumentException("File descriptors passed in Intent");
18367 if (callingPackage == null) {
18368 throw new IllegalArgumentException("callingPackage cannot be null");
18371 synchronized(this) {
18372 return mServices.bindServiceLocked(caller, token, service,
18373 resolvedType, connection, flags, callingPackage, userId);
18377 public boolean unbindService(IServiceConnection connection) {
18378 synchronized (this) {
18379 return mServices.unbindServiceLocked(connection);
18383 public void publishService(IBinder token, Intent intent, IBinder service) {
18384 // Refuse possible leaked file descriptors
18385 if (intent != null && intent.hasFileDescriptors() == true) {
18386 throw new IllegalArgumentException("File descriptors passed in Intent");
18389 synchronized(this) {
18390 if (!(token instanceof ServiceRecord)) {
18391 throw new IllegalArgumentException("Invalid service token");
18393 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18397 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18398 // Refuse possible leaked file descriptors
18399 if (intent != null && intent.hasFileDescriptors() == true) {
18400 throw new IllegalArgumentException("File descriptors passed in Intent");
18403 synchronized(this) {
18404 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18408 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18409 synchronized(this) {
18410 if (!(token instanceof ServiceRecord)) {
18411 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18412 throw new IllegalArgumentException("Invalid service token");
18414 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18418 // =========================================================
18419 // BACKUP AND RESTORE
18420 // =========================================================
18422 // Cause the target app to be launched if necessary and its backup agent
18423 // instantiated. The backup agent will invoke backupAgentCreated() on the
18424 // activity manager to announce its creation.
18425 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18426 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18427 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18429 IPackageManager pm = AppGlobals.getPackageManager();
18430 ApplicationInfo app = null;
18432 app = pm.getApplicationInfo(packageName, 0, userId);
18433 } catch (RemoteException e) {
18434 // can't happen; package manager is process-local
18437 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18444 synchronized(this) {
18445 // !!! TODO: currently no check here that we're already bound
18446 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18447 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18448 synchronized (stats) {
18449 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18452 // Backup agent is now in use, its package can't be stopped.
18454 AppGlobals.getPackageManager().setPackageStoppedState(
18455 app.packageName, false, UserHandle.getUserId(app.uid));
18456 } catch (RemoteException e) {
18457 } catch (IllegalArgumentException e) {
18458 Slog.w(TAG, "Failed trying to unstop package "
18459 + app.packageName + ": " + e);
18462 BackupRecord r = new BackupRecord(ss, app, backupMode);
18463 ComponentName hostingName =
18464 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18465 ? new ComponentName(app.packageName, app.backupAgentName)
18466 : new ComponentName("android", "FullBackupAgent");
18467 // startProcessLocked() returns existing proc's record if it's already running
18468 ProcessRecord proc = startProcessLocked(app.processName, app,
18469 false, 0, "backup", hostingName, false, false, false);
18470 if (proc == null) {
18471 Slog.e(TAG, "Unable to start backup agent process " + r);
18475 // If the app is a regular app (uid >= 10000) and not the system server or phone
18476 // process, etc, then mark it as being in full backup so that certain calls to the
18477 // process can be blocked. This is not reset to false anywhere because we kill the
18478 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18479 if (UserHandle.isApp(app.uid) &&
18480 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18481 proc.inFullBackup = true;
18484 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18485 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18487 mBackupAppName = app.packageName;
18489 // Try not to kill the process during backup
18490 updateOomAdjLocked(proc, true);
18492 // If the process is already attached, schedule the creation of the backup agent now.
18493 // If it is not yet live, this will be done when it attaches to the framework.
18494 if (proc.thread != null) {
18495 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18497 proc.thread.scheduleCreateBackupAgent(app,
18498 compatibilityInfoForPackageLocked(app), backupMode);
18499 } catch (RemoteException e) {
18500 // Will time out on the backup manager side
18503 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18505 // Invariants: at this point, the target app process exists and the application
18506 // is either already running or in the process of coming up. mBackupTarget and
18507 // mBackupAppName describe the app, so that when it binds back to the AM we
18508 // know that it's scheduled for a backup-agent operation.
18511 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18512 if (oldBackupUid != -1) {
18513 js.removeBackingUpUid(oldBackupUid);
18515 if (newBackupUid != -1) {
18516 js.addBackingUpUid(newBackupUid);
18523 public void clearPendingBackup() {
18524 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18525 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18527 synchronized (this) {
18528 mBackupTarget = null;
18529 mBackupAppName = null;
18532 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18533 js.clearAllBackingUpUids();
18536 // A backup agent has just come up
18537 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18538 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18541 synchronized(this) {
18542 if (!agentPackageName.equals(mBackupAppName)) {
18543 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18548 long oldIdent = Binder.clearCallingIdentity();
18550 IBackupManager bm = IBackupManager.Stub.asInterface(
18551 ServiceManager.getService(Context.BACKUP_SERVICE));
18552 bm.agentConnected(agentPackageName, agent);
18553 } catch (RemoteException e) {
18554 // can't happen; the backup manager service is local
18555 } catch (Exception e) {
18556 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18557 e.printStackTrace();
18559 Binder.restoreCallingIdentity(oldIdent);
18563 // done with this agent
18564 public void unbindBackupAgent(ApplicationInfo appInfo) {
18565 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18566 if (appInfo == null) {
18567 Slog.w(TAG, "unbind backup agent for null app");
18573 synchronized(this) {
18575 if (mBackupAppName == null) {
18576 Slog.w(TAG, "Unbinding backup agent with no active backup");
18580 if (!mBackupAppName.equals(appInfo.packageName)) {
18581 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18585 // Not backing this app up any more; reset its OOM adjustment
18586 final ProcessRecord proc = mBackupTarget.app;
18587 updateOomAdjLocked(proc, true);
18588 proc.inFullBackup = false;
18590 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18592 // If the app crashed during backup, 'thread' will be null here
18593 if (proc.thread != null) {
18595 proc.thread.scheduleDestroyBackupAgent(appInfo,
18596 compatibilityInfoForPackageLocked(appInfo));
18597 } catch (Exception e) {
18598 Slog.e(TAG, "Exception when unbinding backup agent:");
18599 e.printStackTrace();
18603 mBackupTarget = null;
18604 mBackupAppName = null;
18608 if (oldBackupUid != -1) {
18609 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18610 js.removeBackingUpUid(oldBackupUid);
18614 // =========================================================
18616 // =========================================================
18618 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18619 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18622 // Easy case -- we have the app's ProcessRecord.
18623 if (record != null) {
18624 return record.info.isInstantApp();
18626 // Otherwise check with PackageManager.
18627 if (callerPackage == null) {
18628 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18629 throw new IllegalArgumentException("Calling application did not provide package name");
18631 mAppOpsService.checkPackage(uid, callerPackage);
18633 IPackageManager pm = AppGlobals.getPackageManager();
18634 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18635 } catch (RemoteException e) {
18636 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18641 boolean isPendingBroadcastProcessLocked(int pid) {
18642 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18643 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18646 void skipPendingBroadcastLocked(int pid) {
18647 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18648 for (BroadcastQueue queue : mBroadcastQueues) {
18649 queue.skipPendingBroadcastLocked(pid);
18653 // The app just attached; send any pending broadcasts that it should receive
18654 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18655 boolean didSomething = false;
18656 for (BroadcastQueue queue : mBroadcastQueues) {
18657 didSomething |= queue.sendPendingBroadcastsLocked(app);
18659 return didSomething;
18662 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18663 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18665 enforceNotIsolatedCaller("registerReceiver");
18666 ArrayList<Intent> stickyIntents = null;
18667 ProcessRecord callerApp = null;
18668 final boolean visibleToInstantApps
18669 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18672 boolean instantApp;
18673 synchronized(this) {
18674 if (caller != null) {
18675 callerApp = getRecordForAppLocked(caller);
18676 if (callerApp == null) {
18677 throw new SecurityException(
18678 "Unable to find app for caller " + caller
18679 + " (pid=" + Binder.getCallingPid()
18680 + ") when registering receiver " + receiver);
18682 if (callerApp.info.uid != SYSTEM_UID &&
18683 !callerApp.pkgList.containsKey(callerPackage) &&
18684 !"android".equals(callerPackage)) {
18685 throw new SecurityException("Given caller package " + callerPackage
18686 + " is not running in process " + callerApp);
18688 callingUid = callerApp.info.uid;
18689 callingPid = callerApp.pid;
18691 callerPackage = null;
18692 callingUid = Binder.getCallingUid();
18693 callingPid = Binder.getCallingPid();
18696 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18697 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18698 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18700 Iterator<String> actions = filter.actionsIterator();
18701 if (actions == null) {
18702 ArrayList<String> noAction = new ArrayList<String>(1);
18703 noAction.add(null);
18704 actions = noAction.iterator();
18707 // Collect stickies of users
18708 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18709 while (actions.hasNext()) {
18710 String action = actions.next();
18711 for (int id : userIds) {
18712 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18713 if (stickies != null) {
18714 ArrayList<Intent> intents = stickies.get(action);
18715 if (intents != null) {
18716 if (stickyIntents == null) {
18717 stickyIntents = new ArrayList<Intent>();
18719 stickyIntents.addAll(intents);
18726 ArrayList<Intent> allSticky = null;
18727 if (stickyIntents != null) {
18728 final ContentResolver resolver = mContext.getContentResolver();
18729 // Look for any matching sticky broadcasts...
18730 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18731 Intent intent = stickyIntents.get(i);
18732 // Don't provided intents that aren't available to instant apps.
18734 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18737 // If intent has scheme "content", it will need to acccess
18738 // provider that needs to lock mProviderMap in ActivityThread
18739 // and also it may need to wait application response, so we
18740 // cannot lock ActivityManagerService here.
18741 if (filter.match(resolver, intent, true, TAG) >= 0) {
18742 if (allSticky == null) {
18743 allSticky = new ArrayList<Intent>();
18745 allSticky.add(intent);
18750 // The first sticky in the list is returned directly back to the client.
18751 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18752 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18753 if (receiver == null) {
18757 synchronized (this) {
18758 if (callerApp != null && (callerApp.thread == null
18759 || callerApp.thread.asBinder() != caller.asBinder())) {
18760 // Original caller already died
18763 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18765 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18767 if (rl.app != null) {
18768 rl.app.receivers.add(rl);
18771 receiver.asBinder().linkToDeath(rl, 0);
18772 } catch (RemoteException e) {
18775 rl.linkedToDeath = true;
18777 mRegisteredReceivers.put(receiver.asBinder(), rl);
18778 } else if (rl.uid != callingUid) {
18779 throw new IllegalArgumentException(
18780 "Receiver requested to register for uid " + callingUid
18781 + " was previously registered for uid " + rl.uid
18782 + " callerPackage is " + callerPackage);
18783 } else if (rl.pid != callingPid) {
18784 throw new IllegalArgumentException(
18785 "Receiver requested to register for pid " + callingPid
18786 + " was previously registered for pid " + rl.pid
18787 + " callerPackage is " + callerPackage);
18788 } else if (rl.userId != userId) {
18789 throw new IllegalArgumentException(
18790 "Receiver requested to register for user " + userId
18791 + " was previously registered for user " + rl.userId
18792 + " callerPackage is " + callerPackage);
18794 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18795 permission, callingUid, userId, instantApp, visibleToInstantApps);
18797 if (!bf.debugCheck()) {
18798 Slog.w(TAG, "==> For Dynamic broadcast");
18800 mReceiverResolver.addFilter(bf);
18802 // Enqueue broadcasts for all existing stickies that match
18804 if (allSticky != null) {
18805 ArrayList receivers = new ArrayList();
18808 final int stickyCount = allSticky.size();
18809 for (int i = 0; i < stickyCount; i++) {
18810 Intent intent = allSticky.get(i);
18811 BroadcastQueue queue = broadcastQueueForIntent(intent);
18812 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18813 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18814 null, 0, null, null, false, true, true, -1);
18815 queue.enqueueParallelBroadcastLocked(r);
18816 queue.scheduleBroadcastsLocked();
18824 public void unregisterReceiver(IIntentReceiver receiver) {
18825 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18827 final long origId = Binder.clearCallingIdentity();
18829 boolean doTrim = false;
18831 synchronized(this) {
18832 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18834 final BroadcastRecord r = rl.curBroadcast;
18835 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18836 final boolean doNext = r.queue.finishReceiverLocked(
18837 r, r.resultCode, r.resultData, r.resultExtras,
18838 r.resultAbort, false);
18841 r.queue.processNextBroadcast(false);
18845 if (rl.app != null) {
18846 rl.app.receivers.remove(rl);
18848 removeReceiverLocked(rl);
18849 if (rl.linkedToDeath) {
18850 rl.linkedToDeath = false;
18851 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18856 // If we actually concluded any broadcasts, we might now be able
18857 // to trim the recipients' apps from our working set
18859 trimApplications();
18864 Binder.restoreCallingIdentity(origId);
18868 void removeReceiverLocked(ReceiverList rl) {
18869 mRegisteredReceivers.remove(rl.receiver.asBinder());
18870 for (int i = rl.size() - 1; i >= 0; i--) {
18871 mReceiverResolver.removeFilter(rl.get(i));
18875 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18876 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18877 ProcessRecord r = mLruProcesses.get(i);
18878 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18880 r.thread.dispatchPackageBroadcast(cmd, packages);
18881 } catch (RemoteException ex) {
18887 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18888 int callingUid, int[] users) {
18889 // TODO: come back and remove this assumption to triage all broadcasts
18890 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18892 List<ResolveInfo> receivers = null;
18894 HashSet<ComponentName> singleUserReceivers = null;
18895 boolean scannedFirstReceivers = false;
18896 for (int user : users) {
18897 // Skip users that have Shell restrictions, with exception of always permitted
18898 // Shell broadcasts
18899 if (callingUid == SHELL_UID
18900 && mUserController.hasUserRestriction(
18901 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18902 && !isPermittedShellBroadcast(intent)) {
18905 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18906 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18907 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18908 // If this is not the system user, we need to check for
18909 // any receivers that should be filtered out.
18910 for (int i=0; i<newReceivers.size(); i++) {
18911 ResolveInfo ri = newReceivers.get(i);
18912 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18913 newReceivers.remove(i);
18918 if (newReceivers != null && newReceivers.size() == 0) {
18919 newReceivers = null;
18921 if (receivers == null) {
18922 receivers = newReceivers;
18923 } else if (newReceivers != null) {
18924 // We need to concatenate the additional receivers
18925 // found with what we have do far. This would be easy,
18926 // but we also need to de-dup any receivers that are
18928 if (!scannedFirstReceivers) {
18929 // Collect any single user receivers we had already retrieved.
18930 scannedFirstReceivers = true;
18931 for (int i=0; i<receivers.size(); i++) {
18932 ResolveInfo ri = receivers.get(i);
18933 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18934 ComponentName cn = new ComponentName(
18935 ri.activityInfo.packageName, ri.activityInfo.name);
18936 if (singleUserReceivers == null) {
18937 singleUserReceivers = new HashSet<ComponentName>();
18939 singleUserReceivers.add(cn);
18943 // Add the new results to the existing results, tracking
18944 // and de-dupping single user receivers.
18945 for (int i=0; i<newReceivers.size(); i++) {
18946 ResolveInfo ri = newReceivers.get(i);
18947 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18948 ComponentName cn = new ComponentName(
18949 ri.activityInfo.packageName, ri.activityInfo.name);
18950 if (singleUserReceivers == null) {
18951 singleUserReceivers = new HashSet<ComponentName>();
18953 if (!singleUserReceivers.contains(cn)) {
18954 singleUserReceivers.add(cn);
18963 } catch (RemoteException ex) {
18964 // pm is in same process, this will never happen.
18969 private boolean isPermittedShellBroadcast(Intent intent) {
18970 // remote bugreport should always be allowed to be taken
18971 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18974 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18975 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18976 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18977 // Don't yell about broadcasts sent via shell
18981 final String action = intent.getAction();
18982 if (isProtectedBroadcast
18983 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18984 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18985 || Intent.ACTION_MEDIA_BUTTON.equals(action)
18986 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18987 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18988 || Intent.ACTION_MASTER_CLEAR.equals(action)
18989 || Intent.ACTION_FACTORY_RESET.equals(action)
18990 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18991 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18992 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18993 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18994 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18995 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18996 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18997 // Broadcast is either protected, or it's a public action that
18998 // we've relaxed, so it's fine for system internals to send.
19002 // This broadcast may be a problem... but there are often system components that
19003 // want to send an internal broadcast to themselves, which is annoying to have to
19004 // explicitly list each action as a protected broadcast, so we will check for that
19005 // one safe case and allow it: an explicit broadcast, only being received by something
19006 // that has protected itself.
19007 if (receivers != null && receivers.size() > 0
19008 && (intent.getPackage() != null || intent.getComponent() != null)) {
19009 boolean allProtected = true;
19010 for (int i = receivers.size()-1; i >= 0; i--) {
19011 Object target = receivers.get(i);
19012 if (target instanceof ResolveInfo) {
19013 ResolveInfo ri = (ResolveInfo)target;
19014 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19015 allProtected = false;
19019 BroadcastFilter bf = (BroadcastFilter)target;
19020 if (bf.requiredPermission == null) {
19021 allProtected = false;
19026 if (allProtected) {
19032 // The vast majority of broadcasts sent from system internals
19033 // should be protected to avoid security holes, so yell loudly
19034 // to ensure we examine these cases.
19035 if (callerApp != null) {
19036 Log.wtf(TAG, "Sending non-protected broadcast " + action
19037 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19040 Log.wtf(TAG, "Sending non-protected broadcast " + action
19041 + " from system uid " + UserHandle.formatUid(callingUid)
19042 + " pkg " + callerPackage,
19047 final int broadcastIntentLocked(ProcessRecord callerApp,
19048 String callerPackage, Intent intent, String resolvedType,
19049 IIntentReceiver resultTo, int resultCode, String resultData,
19050 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19051 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19052 intent = new Intent(intent);
19054 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19055 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19056 if (callerInstantApp) {
19057 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19060 // By default broadcasts do not go to stopped apps.
19061 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19063 // If we have not finished booting, don't allow this to launch new processes.
19064 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19065 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19068 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19069 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19070 + " ordered=" + ordered + " userid=" + userId);
19071 if ((resultTo != null) && !ordered) {
19072 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19075 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19076 ALLOW_NON_FULL, "broadcast", callerPackage);
19078 // Make sure that the user who is receiving this broadcast is running.
19079 // If not, we will just skip it. Make an exception for shutdown broadcasts
19080 // and upgrade steps.
19082 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19083 if ((callingUid != SYSTEM_UID
19084 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19085 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19086 Slog.w(TAG, "Skipping broadcast of " + intent
19087 + ": user " + userId + " is stopped");
19088 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19092 BroadcastOptions brOptions = null;
19093 if (bOptions != null) {
19094 brOptions = new BroadcastOptions(bOptions);
19095 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19096 // See if the caller is allowed to do this. Note we are checking against
19097 // the actual real caller (not whoever provided the operation as say a
19098 // PendingIntent), because that who is actually supplied the arguments.
19099 if (checkComponentPermission(
19100 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19101 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19102 != PackageManager.PERMISSION_GRANTED) {
19103 String msg = "Permission Denial: " + intent.getAction()
19104 + " broadcast from " + callerPackage + " (pid=" + callingPid
19105 + ", uid=" + callingUid + ")"
19107 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19109 throw new SecurityException(msg);
19114 // Verify that protected broadcasts are only being sent by system code,
19115 // and that system code is only sending protected broadcasts.
19116 final String action = intent.getAction();
19117 final boolean isProtectedBroadcast;
19119 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19120 } catch (RemoteException e) {
19121 Slog.w(TAG, "Remote exception", e);
19122 return ActivityManager.BROADCAST_SUCCESS;
19125 final boolean isCallerSystem;
19126 switch (UserHandle.getAppId(callingUid)) {
19130 case BLUETOOTH_UID:
19132 isCallerSystem = true;
19135 isCallerSystem = (callerApp != null) && callerApp.persistent;
19139 // First line security check before anything else: stop non-system apps from
19140 // sending protected broadcasts.
19141 if (!isCallerSystem) {
19142 if (isProtectedBroadcast) {
19143 String msg = "Permission Denial: not allowed to send broadcast "
19144 + action + " from pid="
19145 + callingPid + ", uid=" + callingUid;
19147 throw new SecurityException(msg);
19149 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19150 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19151 // Special case for compatibility: we don't want apps to send this,
19152 // but historically it has not been protected and apps may be using it
19153 // to poke their own app widget. So, instead of making it protected,
19154 // just limit it to the caller.
19155 if (callerPackage == null) {
19156 String msg = "Permission Denial: not allowed to send broadcast "
19157 + action + " from unknown caller.";
19159 throw new SecurityException(msg);
19160 } else if (intent.getComponent() != null) {
19161 // They are good enough to send to an explicit component... verify
19162 // it is being sent to the calling app.
19163 if (!intent.getComponent().getPackageName().equals(
19165 String msg = "Permission Denial: not allowed to send broadcast "
19167 + intent.getComponent().getPackageName() + " from "
19170 throw new SecurityException(msg);
19173 // Limit broadcast to their own package.
19174 intent.setPackage(callerPackage);
19179 if (action != null) {
19180 if (getBackgroundLaunchBroadcasts().contains(action)) {
19181 if (DEBUG_BACKGROUND_CHECK) {
19182 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19184 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19188 case Intent.ACTION_UID_REMOVED:
19189 case Intent.ACTION_PACKAGE_REMOVED:
19190 case Intent.ACTION_PACKAGE_CHANGED:
19191 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19192 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19193 case Intent.ACTION_PACKAGES_SUSPENDED:
19194 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19195 // Handle special intents: if this broadcast is from the package
19196 // manager about a package being removed, we need to remove all of
19197 // its activities from the history stack.
19198 if (checkComponentPermission(
19199 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19200 callingPid, callingUid, -1, true)
19201 != PackageManager.PERMISSION_GRANTED) {
19202 String msg = "Permission Denial: " + intent.getAction()
19203 + " broadcast from " + callerPackage + " (pid=" + callingPid
19204 + ", uid=" + callingUid + ")"
19206 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19208 throw new SecurityException(msg);
19211 case Intent.ACTION_UID_REMOVED:
19212 final int uid = getUidFromIntent(intent);
19214 mBatteryStatsService.removeUid(uid);
19215 mAppOpsService.uidRemoved(uid);
19218 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19219 // If resources are unavailable just force stop all those packages
19220 // and flush the attribute cache as well.
19222 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19223 if (list != null && list.length > 0) {
19224 for (int i = 0; i < list.length; i++) {
19225 forceStopPackageLocked(list[i], -1, false, true, true,
19226 false, false, userId, "storage unmount");
19228 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19229 sendPackageBroadcastLocked(
19230 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19234 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19235 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19237 case Intent.ACTION_PACKAGE_REMOVED:
19238 case Intent.ACTION_PACKAGE_CHANGED:
19239 Uri data = intent.getData();
19241 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19242 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19243 final boolean replacing =
19244 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19245 final boolean killProcess =
19246 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19247 final boolean fullUninstall = removed && !replacing;
19250 forceStopPackageLocked(ssp, UserHandle.getAppId(
19251 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19252 false, true, true, false, fullUninstall, userId,
19253 removed ? "pkg removed" : "pkg changed");
19255 final int cmd = killProcess
19256 ? ApplicationThreadConstants.PACKAGE_REMOVED
19257 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19258 sendPackageBroadcastLocked(cmd,
19259 new String[] {ssp}, userId);
19260 if (fullUninstall) {
19261 mAppOpsService.packageRemoved(
19262 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19264 // Remove all permissions granted from/to this package
19265 removeUriPermissionsForPackageLocked(ssp, userId, true);
19267 removeTasksByPackageNameLocked(ssp, userId);
19269 mServices.forceStopPackageLocked(ssp, userId);
19271 // Hide the "unsupported display" dialog if necessary.
19272 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19273 mUnsupportedDisplaySizeDialog.getPackageName())) {
19274 mUnsupportedDisplaySizeDialog.dismiss();
19275 mUnsupportedDisplaySizeDialog = null;
19277 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19278 mBatteryStatsService.notePackageUninstalled(ssp);
19282 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19283 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19284 userId, ProcessList.INVALID_ADJ,
19285 false, true, true, false, "change " + ssp);
19287 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19288 intent.getStringArrayExtra(
19289 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19293 case Intent.ACTION_PACKAGES_SUSPENDED:
19294 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19295 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19296 intent.getAction());
19297 final String[] packageNames = intent.getStringArrayExtra(
19298 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19299 final int userHandle = intent.getIntExtra(
19300 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19302 synchronized(ActivityManagerService.this) {
19303 mRecentTasks.onPackagesSuspendedChanged(
19304 packageNames, suspended, userHandle);
19309 case Intent.ACTION_PACKAGE_REPLACED:
19311 final Uri data = intent.getData();
19313 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19314 ApplicationInfo aInfo = null;
19316 aInfo = AppGlobals.getPackageManager()
19317 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19318 } catch (RemoteException ignore) {}
19319 if (aInfo == null) {
19320 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19321 + " ssp=" + ssp + " data=" + data);
19322 return ActivityManager.BROADCAST_SUCCESS;
19324 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19325 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19326 new String[] {ssp}, userId);
19330 case Intent.ACTION_PACKAGE_ADDED:
19332 // Special case for adding a package: by default turn on compatibility mode.
19333 Uri data = intent.getData();
19335 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19336 final boolean replacing =
19337 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19338 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19341 ApplicationInfo ai = AppGlobals.getPackageManager().
19342 getApplicationInfo(ssp, 0, 0);
19343 mBatteryStatsService.notePackageInstalled(ssp,
19344 ai != null ? ai.versionCode : 0);
19345 } catch (RemoteException e) {
19350 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19352 Uri data = intent.getData();
19354 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19355 // Hide the "unsupported display" dialog if necessary.
19356 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19357 mUnsupportedDisplaySizeDialog.getPackageName())) {
19358 mUnsupportedDisplaySizeDialog.dismiss();
19359 mUnsupportedDisplaySizeDialog = null;
19361 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19365 case Intent.ACTION_TIMEZONE_CHANGED:
19366 // If this is the time zone changed action, queue up a message that will reset
19367 // the timezone of all currently running processes. This message will get
19368 // queued up before the broadcast happens.
19369 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19371 case Intent.ACTION_TIME_CHANGED:
19372 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19373 // the tri-state value it may contain and "unknown".
19374 // For convenience we re-use the Intent extra values.
19375 final int NO_EXTRA_VALUE_FOUND = -1;
19376 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19377 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19378 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19379 // Only send a message if the time preference is available.
19380 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19381 Message updateTimePreferenceMsg =
19382 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19383 timeFormatPreferenceMsgValue, 0);
19384 mHandler.sendMessage(updateTimePreferenceMsg);
19386 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19387 synchronized (stats) {
19388 stats.noteCurrentTimeChangedLocked();
19391 case Intent.ACTION_CLEAR_DNS_CACHE:
19392 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19394 case Proxy.PROXY_CHANGE_ACTION:
19395 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19396 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19398 case android.hardware.Camera.ACTION_NEW_PICTURE:
19399 case android.hardware.Camera.ACTION_NEW_VIDEO:
19400 // In N we just turned these off; in O we are turing them back on partly,
19401 // only for registered receivers. This will still address the main problem
19402 // (a spam of apps waking up when a picture is taken putting significant
19403 // memory pressure on the system at a bad point), while still allowing apps
19404 // that are already actively running to know about this happening.
19405 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19407 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19408 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19410 case "com.android.launcher.action.INSTALL_SHORTCUT":
19411 // As of O, we no longer support this broadcasts, even for pre-O apps.
19412 // Apps should now be using ShortcutManager.pinRequestShortcut().
19413 Log.w(TAG, "Broadcast " + action
19414 + " no longer supported. It will not be delivered.");
19415 return ActivityManager.BROADCAST_SUCCESS;
19418 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19419 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19420 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19421 final int uid = getUidFromIntent(intent);
19423 final UidRecord uidRec = mActiveUids.get(uid);
19424 if (uidRec != null) {
19425 uidRec.updateHasInternetPermission();
19431 // Add to the sticky list if requested.
19433 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19434 callingPid, callingUid)
19435 != PackageManager.PERMISSION_GRANTED) {
19436 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19437 + callingPid + ", uid=" + callingUid
19438 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19440 throw new SecurityException(msg);
19442 if (requiredPermissions != null && requiredPermissions.length > 0) {
19443 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19444 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19445 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19447 if (intent.getComponent() != null) {
19448 throw new SecurityException(
19449 "Sticky broadcasts can't target a specific component");
19451 // We use userId directly here, since the "all" target is maintained
19452 // as a separate set of sticky broadcasts.
19453 if (userId != UserHandle.USER_ALL) {
19454 // But first, if this is not a broadcast to all users, then
19455 // make sure it doesn't conflict with an existing broadcast to
19457 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19458 UserHandle.USER_ALL);
19459 if (stickies != null) {
19460 ArrayList<Intent> list = stickies.get(intent.getAction());
19461 if (list != null) {
19462 int N = list.size();
19464 for (i=0; i<N; i++) {
19465 if (intent.filterEquals(list.get(i))) {
19466 throw new IllegalArgumentException(
19467 "Sticky broadcast " + intent + " for user "
19468 + userId + " conflicts with existing global broadcast");
19474 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19475 if (stickies == null) {
19476 stickies = new ArrayMap<>();
19477 mStickyBroadcasts.put(userId, stickies);
19479 ArrayList<Intent> list = stickies.get(intent.getAction());
19480 if (list == null) {
19481 list = new ArrayList<>();
19482 stickies.put(intent.getAction(), list);
19484 final int stickiesCount = list.size();
19486 for (i = 0; i < stickiesCount; i++) {
19487 if (intent.filterEquals(list.get(i))) {
19488 // This sticky already exists, replace it.
19489 list.set(i, new Intent(intent));
19493 if (i >= stickiesCount) {
19494 list.add(new Intent(intent));
19499 if (userId == UserHandle.USER_ALL) {
19500 // Caller wants broadcast to go to all started users.
19501 users = mUserController.getStartedUserArrayLocked();
19503 // Caller wants broadcast to go to one specific user.
19504 users = new int[] {userId};
19507 // Figure out who all will receive this broadcast.
19508 List receivers = null;
19509 List<BroadcastFilter> registeredReceivers = null;
19510 // Need to resolve the intent to interested receivers...
19511 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19513 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19515 if (intent.getComponent() == null) {
19516 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19517 // Query one target user at a time, excluding shell-restricted users
19518 for (int i = 0; i < users.length; i++) {
19519 if (mUserController.hasUserRestriction(
19520 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19523 List<BroadcastFilter> registeredReceiversForUser =
19524 mReceiverResolver.queryIntent(intent,
19525 resolvedType, false /*defaultOnly*/, users[i]);
19526 if (registeredReceivers == null) {
19527 registeredReceivers = registeredReceiversForUser;
19528 } else if (registeredReceiversForUser != null) {
19529 registeredReceivers.addAll(registeredReceiversForUser);
19533 registeredReceivers = mReceiverResolver.queryIntent(intent,
19534 resolvedType, false /*defaultOnly*/, userId);
19538 final boolean replacePending =
19539 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19541 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19542 + " replacePending=" + replacePending);
19544 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19545 if (!ordered && NR > 0) {
19546 // If we are not serializing this broadcast, then send the
19547 // registered receivers separately so they don't wait for the
19548 // components to be launched.
19549 if (isCallerSystem) {
19550 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19551 isProtectedBroadcast, registeredReceivers);
19553 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19554 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19555 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19556 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19557 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19558 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19559 final boolean replaced = replacePending
19560 && (queue.replaceParallelBroadcastLocked(r) != null);
19561 // Note: We assume resultTo is null for non-ordered broadcasts.
19563 queue.enqueueParallelBroadcastLocked(r);
19564 queue.scheduleBroadcastsLocked();
19566 registeredReceivers = null;
19570 // Merge into one list.
19572 if (receivers != null) {
19573 // A special case for PACKAGE_ADDED: do not allow the package
19574 // being added to see this broadcast. This prevents them from
19575 // using this as a back door to get run as soon as they are
19576 // installed. Maybe in the future we want to have a special install
19577 // broadcast or such for apps, but we'd like to deliberately make
19579 String skipPackages[] = null;
19580 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19581 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19582 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19583 Uri data = intent.getData();
19584 if (data != null) {
19585 String pkgName = data.getSchemeSpecificPart();
19586 if (pkgName != null) {
19587 skipPackages = new String[] { pkgName };
19590 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19591 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19593 if (skipPackages != null && (skipPackages.length > 0)) {
19594 for (String skipPackage : skipPackages) {
19595 if (skipPackage != null) {
19596 int NT = receivers.size();
19597 for (int it=0; it<NT; it++) {
19598 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19599 if (curt.activityInfo.packageName.equals(skipPackage)) {
19600 receivers.remove(it);
19609 int NT = receivers != null ? receivers.size() : 0;
19611 ResolveInfo curt = null;
19612 BroadcastFilter curr = null;
19613 while (it < NT && ir < NR) {
19614 if (curt == null) {
19615 curt = (ResolveInfo)receivers.get(it);
19617 if (curr == null) {
19618 curr = registeredReceivers.get(ir);
19620 if (curr.getPriority() >= curt.priority) {
19621 // Insert this broadcast record into the final list.
19622 receivers.add(it, curr);
19628 // Skip to the next ResolveInfo in the final list.
19635 if (receivers == null) {
19636 receivers = new ArrayList();
19638 receivers.add(registeredReceivers.get(ir));
19642 if (isCallerSystem) {
19643 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19644 isProtectedBroadcast, receivers);
19647 if ((receivers != null && receivers.size() > 0)
19648 || resultTo != null) {
19649 BroadcastQueue queue = broadcastQueueForIntent(intent);
19650 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19651 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19652 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19653 resultData, resultExtras, ordered, sticky, false, userId);
19655 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19656 + ": prev had " + queue.mOrderedBroadcasts.size());
19657 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19658 "Enqueueing broadcast " + r.intent.getAction());
19660 final BroadcastRecord oldRecord =
19661 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19662 if (oldRecord != null) {
19663 // Replaced, fire the result-to receiver.
19664 if (oldRecord.resultTo != null) {
19665 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19667 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19669 Activity.RESULT_CANCELED, null, null,
19670 false, false, oldRecord.userId);
19671 } catch (RemoteException e) {
19672 Slog.w(TAG, "Failure ["
19673 + queue.mQueueName + "] sending broadcast result of "
19679 queue.enqueueOrderedBroadcastLocked(r);
19680 queue.scheduleBroadcastsLocked();
19683 // There was nobody interested in the broadcast, but we still want to record
19684 // that it happened.
19685 if (intent.getComponent() == null && intent.getPackage() == null
19686 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19687 // This was an implicit broadcast... let's record it for posterity.
19688 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19692 return ActivityManager.BROADCAST_SUCCESS;
19696 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19698 private int getUidFromIntent(Intent intent) {
19699 if (intent == null) {
19702 final Bundle intentExtras = intent.getExtras();
19703 return intent.hasExtra(Intent.EXTRA_UID)
19704 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19707 final void rotateBroadcastStatsIfNeededLocked() {
19708 final long now = SystemClock.elapsedRealtime();
19709 if (mCurBroadcastStats == null ||
19710 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19711 mLastBroadcastStats = mCurBroadcastStats;
19712 if (mLastBroadcastStats != null) {
19713 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19714 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19716 mCurBroadcastStats = new BroadcastStats();
19720 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19721 int skipCount, long dispatchTime) {
19722 rotateBroadcastStatsIfNeededLocked();
19723 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19726 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19727 rotateBroadcastStatsIfNeededLocked();
19728 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19731 final Intent verifyBroadcastLocked(Intent intent) {
19732 // Refuse possible leaked file descriptors
19733 if (intent != null && intent.hasFileDescriptors() == true) {
19734 throw new IllegalArgumentException("File descriptors passed in Intent");
19737 int flags = intent.getFlags();
19739 if (!mProcessesReady) {
19740 // if the caller really truly claims to know what they're doing, go
19741 // ahead and allow the broadcast without launching any receivers
19742 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19743 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19744 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19745 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19746 + " before boot completion");
19747 throw new IllegalStateException("Cannot broadcast before boot completed");
19751 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19752 throw new IllegalArgumentException(
19753 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19756 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19757 switch (Binder.getCallingUid()) {
19762 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19763 + Binder.getCallingUid());
19764 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19772 public final int broadcastIntent(IApplicationThread caller,
19773 Intent intent, String resolvedType, IIntentReceiver resultTo,
19774 int resultCode, String resultData, Bundle resultExtras,
19775 String[] requiredPermissions, int appOp, Bundle bOptions,
19776 boolean serialized, boolean sticky, int userId) {
19777 enforceNotIsolatedCaller("broadcastIntent");
19778 synchronized(this) {
19779 intent = verifyBroadcastLocked(intent);
19781 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19782 final int callingPid = Binder.getCallingPid();
19783 final int callingUid = Binder.getCallingUid();
19784 final long origId = Binder.clearCallingIdentity();
19785 int res = broadcastIntentLocked(callerApp,
19786 callerApp != null ? callerApp.info.packageName : null,
19787 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19788 requiredPermissions, appOp, bOptions, serialized, sticky,
19789 callingPid, callingUid, userId);
19790 Binder.restoreCallingIdentity(origId);
19796 int broadcastIntentInPackage(String packageName, int uid,
19797 Intent intent, String resolvedType, IIntentReceiver resultTo,
19798 int resultCode, String resultData, Bundle resultExtras,
19799 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19801 synchronized(this) {
19802 intent = verifyBroadcastLocked(intent);
19804 final long origId = Binder.clearCallingIdentity();
19805 String[] requiredPermissions = requiredPermission == null ? null
19806 : new String[] {requiredPermission};
19807 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19808 resultTo, resultCode, resultData, resultExtras,
19809 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19810 sticky, -1, uid, userId);
19811 Binder.restoreCallingIdentity(origId);
19816 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19817 // Refuse possible leaked file descriptors
19818 if (intent != null && intent.hasFileDescriptors() == true) {
19819 throw new IllegalArgumentException("File descriptors passed in Intent");
19822 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19823 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19825 synchronized(this) {
19826 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19827 != PackageManager.PERMISSION_GRANTED) {
19828 String msg = "Permission Denial: unbroadcastIntent() from pid="
19829 + Binder.getCallingPid()
19830 + ", uid=" + Binder.getCallingUid()
19831 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19833 throw new SecurityException(msg);
19835 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19836 if (stickies != null) {
19837 ArrayList<Intent> list = stickies.get(intent.getAction());
19838 if (list != null) {
19839 int N = list.size();
19841 for (i=0; i<N; i++) {
19842 if (intent.filterEquals(list.get(i))) {
19847 if (list.size() <= 0) {
19848 stickies.remove(intent.getAction());
19851 if (stickies.size() <= 0) {
19852 mStickyBroadcasts.remove(userId);
19858 void backgroundServicesFinishedLocked(int userId) {
19859 for (BroadcastQueue queue : mBroadcastQueues) {
19860 queue.backgroundServicesFinishedLocked(userId);
19864 public void finishReceiver(IBinder who, int resultCode, String resultData,
19865 Bundle resultExtras, boolean resultAbort, int flags) {
19866 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19868 // Refuse possible leaked file descriptors
19869 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19870 throw new IllegalArgumentException("File descriptors passed in Bundle");
19873 final long origId = Binder.clearCallingIdentity();
19875 boolean doNext = false;
19878 synchronized(this) {
19879 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19880 ? mFgBroadcastQueue : mBgBroadcastQueue;
19881 r = queue.getMatchingOrderedReceiver(who);
19883 doNext = r.queue.finishReceiverLocked(r, resultCode,
19884 resultData, resultExtras, resultAbort, true);
19889 r.queue.processNextBroadcast(false);
19891 trimApplications();
19893 Binder.restoreCallingIdentity(origId);
19897 // =========================================================
19899 // =========================================================
19901 public boolean startInstrumentation(ComponentName className,
19902 String profileFile, int flags, Bundle arguments,
19903 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19904 int userId, String abiOverride) {
19905 enforceNotIsolatedCaller("startInstrumentation");
19906 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19907 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19908 // Refuse possible leaked file descriptors
19909 if (arguments != null && arguments.hasFileDescriptors()) {
19910 throw new IllegalArgumentException("File descriptors passed in Bundle");
19913 synchronized(this) {
19914 InstrumentationInfo ii = null;
19915 ApplicationInfo ai = null;
19917 ii = mContext.getPackageManager().getInstrumentationInfo(
19918 className, STOCK_PM_FLAGS);
19919 ai = AppGlobals.getPackageManager().getApplicationInfo(
19920 ii.targetPackage, STOCK_PM_FLAGS, userId);
19921 } catch (PackageManager.NameNotFoundException e) {
19922 } catch (RemoteException e) {
19925 reportStartInstrumentationFailureLocked(watcher, className,
19926 "Unable to find instrumentation info for: " + className);
19930 reportStartInstrumentationFailureLocked(watcher, className,
19931 "Unable to find instrumentation target package: " + ii.targetPackage);
19934 if (!ai.hasCode()) {
19935 reportStartInstrumentationFailureLocked(watcher, className,
19936 "Instrumentation target has no code: " + ii.targetPackage);
19940 int match = mContext.getPackageManager().checkSignatures(
19941 ii.targetPackage, ii.packageName);
19942 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19943 String msg = "Permission Denial: starting instrumentation "
19944 + className + " from pid="
19945 + Binder.getCallingPid()
19946 + ", uid=" + Binder.getCallingPid()
19947 + " not allowed because package " + ii.packageName
19948 + " does not have a signature matching the target "
19949 + ii.targetPackage;
19950 reportStartInstrumentationFailureLocked(watcher, className, msg);
19951 throw new SecurityException(msg);
19954 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19955 activeInstr.mClass = className;
19956 String defProcess = ai.processName;;
19957 if (ii.targetProcesses == null) {
19958 activeInstr.mTargetProcesses = new String[]{ai.processName};
19959 } else if (ii.targetProcesses.equals("*")) {
19960 activeInstr.mTargetProcesses = new String[0];
19962 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19963 defProcess = activeInstr.mTargetProcesses[0];
19965 activeInstr.mTargetInfo = ai;
19966 activeInstr.mProfileFile = profileFile;
19967 activeInstr.mArguments = arguments;
19968 activeInstr.mWatcher = watcher;
19969 activeInstr.mUiAutomationConnection = uiAutomationConnection;
19970 activeInstr.mResultClass = className;
19972 final long origId = Binder.clearCallingIdentity();
19973 // Instrumentation can kill and relaunch even persistent processes
19974 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19976 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19977 app.instr = activeInstr;
19978 activeInstr.mFinished = false;
19979 activeInstr.mRunningProcesses.add(app);
19980 if (!mActiveInstrumentation.contains(activeInstr)) {
19981 mActiveInstrumentation.add(activeInstr);
19983 Binder.restoreCallingIdentity(origId);
19990 * Report errors that occur while attempting to start Instrumentation. Always writes the
19991 * error to the logs, but if somebody is watching, send the report there too. This enables
19992 * the "am" command to report errors with more information.
19994 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
19995 * @param cn The component name of the instrumentation.
19996 * @param report The error report.
19998 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19999 ComponentName cn, String report) {
20000 Slog.w(TAG, report);
20001 if (watcher != null) {
20002 Bundle results = new Bundle();
20003 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20004 results.putString("Error", report);
20005 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20009 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20010 if (app.instr == null) {
20011 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20015 if (!app.instr.mFinished && results != null) {
20016 if (app.instr.mCurResults == null) {
20017 app.instr.mCurResults = new Bundle(results);
20019 app.instr.mCurResults.putAll(results);
20024 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20025 int userId = UserHandle.getCallingUserId();
20026 // Refuse possible leaked file descriptors
20027 if (results != null && results.hasFileDescriptors()) {
20028 throw new IllegalArgumentException("File descriptors passed in Intent");
20031 synchronized(this) {
20032 ProcessRecord app = getRecordForAppLocked(target);
20034 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20037 final long origId = Binder.clearCallingIdentity();
20038 addInstrumentationResultsLocked(app, results);
20039 Binder.restoreCallingIdentity(origId);
20043 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20044 if (app.instr == null) {
20045 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20049 if (!app.instr.mFinished) {
20050 if (app.instr.mWatcher != null) {
20051 Bundle finalResults = app.instr.mCurResults;
20052 if (finalResults != null) {
20053 if (app.instr.mCurResults != null && results != null) {
20054 finalResults.putAll(results);
20057 finalResults = results;
20059 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20060 app.instr.mClass, resultCode, finalResults);
20063 // Can't call out of the system process with a lock held, so post a message.
20064 if (app.instr.mUiAutomationConnection != null) {
20065 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20066 app.instr.mUiAutomationConnection).sendToTarget();
20068 app.instr.mFinished = true;
20071 app.instr.removeProcess(app);
20074 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20078 public void finishInstrumentation(IApplicationThread target,
20079 int resultCode, Bundle results) {
20080 int userId = UserHandle.getCallingUserId();
20081 // Refuse possible leaked file descriptors
20082 if (results != null && results.hasFileDescriptors()) {
20083 throw new IllegalArgumentException("File descriptors passed in Intent");
20086 synchronized(this) {
20087 ProcessRecord app = getRecordForAppLocked(target);
20089 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20092 final long origId = Binder.clearCallingIdentity();
20093 finishInstrumentationLocked(app, resultCode, results);
20094 Binder.restoreCallingIdentity(origId);
20098 // =========================================================
20100 // =========================================================
20102 public ConfigurationInfo getDeviceConfigurationInfo() {
20103 ConfigurationInfo config = new ConfigurationInfo();
20104 synchronized (this) {
20105 final Configuration globalConfig = getGlobalConfiguration();
20106 config.reqTouchScreen = globalConfig.touchscreen;
20107 config.reqKeyboardType = globalConfig.keyboard;
20108 config.reqNavigation = globalConfig.navigation;
20109 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20110 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20111 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20113 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20114 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20115 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20117 config.reqGlEsVersion = GL_ES_VERSION;
20122 ActivityStack getFocusedStack() {
20123 return mStackSupervisor.getFocusedStack();
20127 public int getFocusedStackId() throws RemoteException {
20128 ActivityStack focusedStack = getFocusedStack();
20129 if (focusedStack != null) {
20130 return focusedStack.getStackId();
20135 public Configuration getConfiguration() {
20137 synchronized(this) {
20138 ci = new Configuration(getGlobalConfiguration());
20139 ci.userSetLocale = false;
20145 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20146 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20147 synchronized (this) {
20148 mSuppressResizeConfigChanges = suppress;
20153 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20154 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20155 * activity and clearing the task at the same time.
20158 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20159 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20160 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20161 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20163 synchronized (this) {
20164 final long origId = Binder.clearCallingIdentity();
20166 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20168 Binder.restoreCallingIdentity(origId);
20174 public void updatePersistentConfiguration(Configuration values) {
20175 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20176 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20177 if (values == null) {
20178 throw new NullPointerException("Configuration must not be null");
20181 int userId = UserHandle.getCallingUserId();
20183 synchronized(this) {
20184 updatePersistentConfigurationLocked(values, userId);
20188 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20189 final long origId = Binder.clearCallingIdentity();
20191 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20193 Binder.restoreCallingIdentity(origId);
20197 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20198 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20199 FONT_SCALE, 1.0f, userId);
20201 synchronized (this) {
20202 if (getGlobalConfiguration().fontScale == scaleFactor) {
20206 final Configuration configuration
20207 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20208 configuration.fontScale = scaleFactor;
20209 updatePersistentConfigurationLocked(configuration, userId);
20213 private void enforceWriteSettingsPermission(String func) {
20214 int uid = Binder.getCallingUid();
20215 if (uid == ROOT_UID) {
20219 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20220 Settings.getPackageNameForUid(mContext, uid), false)) {
20224 String msg = "Permission Denial: " + func + " from pid="
20225 + Binder.getCallingPid()
20227 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20229 throw new SecurityException(msg);
20233 public boolean updateConfiguration(Configuration values) {
20234 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20236 synchronized(this) {
20237 if (values == null && mWindowManager != null) {
20238 // sentinel: fetch the current configuration from the window manager
20239 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20242 if (mWindowManager != null) {
20243 // Update OOM levels based on display size.
20244 mProcessList.applyDisplaySize(mWindowManager);
20247 final long origId = Binder.clearCallingIdentity();
20249 if (values != null) {
20250 Settings.System.clearConfiguration(values);
20252 updateConfigurationLocked(values, null, false, false /* persistent */,
20253 UserHandle.USER_NULL, false /* deferResume */,
20254 mTmpUpdateConfigurationResult);
20255 return mTmpUpdateConfigurationResult.changes != 0;
20257 Binder.restoreCallingIdentity(origId);
20262 void updateUserConfigurationLocked() {
20263 final Configuration configuration = new Configuration(getGlobalConfiguration());
20264 final int currentUserId = mUserController.getCurrentUserIdLocked();
20265 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20266 currentUserId, Settings.System.canWrite(mContext));
20267 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20268 false /* persistent */, currentUserId, false /* deferResume */);
20271 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20272 boolean initLocale) {
20273 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20276 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20277 boolean initLocale, boolean deferResume) {
20278 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20279 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20280 UserHandle.USER_NULL, deferResume);
20283 // To cache the list of supported system locales
20284 private String[] mSupportedSystemLocales = null;
20286 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20287 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20288 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20289 deferResume, null /* result */);
20293 * Do either or both things: (1) change the current configuration, and (2)
20294 * make sure the given activity is running with the (now) current
20295 * configuration. Returns true if the activity has been left running, or
20296 * false if <var>starting</var> is being destroyed to match the new
20299 * @param userId is only used when persistent parameter is set to true to persist configuration
20300 * for that particular user
20302 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20303 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20304 UpdateConfigurationResult result) {
20306 boolean kept = true;
20308 if (mWindowManager != null) {
20309 mWindowManager.deferSurfaceLayout();
20312 if (values != null) {
20313 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20317 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20319 if (mWindowManager != null) {
20320 mWindowManager.continueSurfaceLayout();
20324 if (result != null) {
20325 result.changes = changes;
20326 result.activityRelaunched = !kept;
20331 /** Update default (global) configuration and notify listeners about changes. */
20332 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20333 boolean persistent, int userId, boolean deferResume) {
20334 mTempConfig.setTo(getGlobalConfiguration());
20335 final int changes = mTempConfig.updateFrom(values);
20336 if (changes == 0) {
20337 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20338 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20339 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20340 // (even if there are no actual changes) to unfreeze the window.
20341 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20345 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20346 "Updating global configuration to: " + values);
20348 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20350 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20351 final LocaleList locales = values.getLocales();
20352 int bestLocaleIndex = 0;
20353 if (locales.size() > 1) {
20354 if (mSupportedSystemLocales == null) {
20355 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20357 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20359 SystemProperties.set("persist.sys.locale",
20360 locales.get(bestLocaleIndex).toLanguageTag());
20361 LocaleList.setDefault(locales, bestLocaleIndex);
20362 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20363 locales.get(bestLocaleIndex)));
20366 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20367 mTempConfig.seq = mConfigurationSeq;
20369 // Update stored global config and notify everyone about the change.
20370 mStackSupervisor.onConfigurationChanged(mTempConfig);
20372 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20373 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20374 mUsageStatsService.reportConfigurationChange(mTempConfig,
20375 mUserController.getCurrentUserIdLocked());
20377 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20378 mShowDialogs = shouldShowDialogs(mTempConfig);
20380 AttributeCache ac = AttributeCache.instance();
20382 ac.updateConfiguration(mTempConfig);
20385 // Make sure all resources in our process are updated right now, so that anyone who is going
20386 // to retrieve resource values after we return will be sure to get the new ones. This is
20387 // especially important during boot, where the first config change needs to guarantee all
20388 // resources have that config before following boot code is executed.
20389 mSystemThread.applyConfigurationToResources(mTempConfig);
20391 // We need another copy of global config because we're scheduling some calls instead of
20392 // running them in place. We need to be sure that object we send will be handled unchanged.
20393 final Configuration configCopy = new Configuration(mTempConfig);
20394 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20395 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20396 msg.obj = configCopy;
20398 mHandler.sendMessage(msg);
20401 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20402 ProcessRecord app = mLruProcesses.get(i);
20404 if (app.thread != null) {
20405 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20406 + app.processName + " new config " + configCopy);
20407 app.thread.scheduleConfigurationChanged(configCopy);
20409 } catch (Exception e) {
20413 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20414 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20415 | Intent.FLAG_RECEIVER_FOREGROUND
20416 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20417 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20418 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20419 UserHandle.USER_ALL);
20420 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20421 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20422 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20423 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20424 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20425 if (initLocale || !mProcessesReady) {
20426 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20428 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20429 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20430 UserHandle.USER_ALL);
20433 // Override configuration of the default display duplicates global config, so we need to
20434 // update it also. This will also notify WindowManager about changes.
20435 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20442 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20443 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20445 synchronized (this) {
20446 // Check if display is initialized in AM.
20447 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20448 // Call might come when display is not yet added or has already been removed.
20449 if (DEBUG_CONFIGURATION) {
20450 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20456 if (values == null && mWindowManager != null) {
20457 // sentinel: fetch the current configuration from the window manager
20458 values = mWindowManager.computeNewConfiguration(displayId);
20461 if (mWindowManager != null) {
20462 // Update OOM levels based on display size.
20463 mProcessList.applyDisplaySize(mWindowManager);
20466 final long origId = Binder.clearCallingIdentity();
20468 if (values != null) {
20469 Settings.System.clearConfiguration(values);
20471 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20472 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20473 return mTmpUpdateConfigurationResult.changes != 0;
20475 Binder.restoreCallingIdentity(origId);
20480 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20481 boolean deferResume, int displayId) {
20482 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20483 displayId, null /* result */);
20487 * Updates override configuration specific for the selected display. If no config is provided,
20488 * new one will be computed in WM based on current display info.
20490 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20491 ActivityRecord starting, boolean deferResume, int displayId,
20492 UpdateConfigurationResult result) {
20494 boolean kept = true;
20496 if (mWindowManager != null) {
20497 mWindowManager.deferSurfaceLayout();
20500 if (values != null) {
20501 if (displayId == DEFAULT_DISPLAY) {
20502 // Override configuration of the default display duplicates global config, so
20503 // we're calling global config update instead for default display. It will also
20504 // apply the correct override config.
20505 changes = updateGlobalConfiguration(values, false /* initLocale */,
20506 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20508 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20512 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20514 if (mWindowManager != null) {
20515 mWindowManager.continueSurfaceLayout();
20519 if (result != null) {
20520 result.changes = changes;
20521 result.activityRelaunched = !kept;
20526 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20528 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20529 final int changes = mTempConfig.updateFrom(values);
20530 if (changes != 0) {
20531 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20532 + mTempConfig + " for displayId=" + displayId);
20533 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20535 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20536 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20537 // Reset the unsupported display size dialog.
20538 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20540 killAllBackgroundProcessesExcept(N,
20541 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20545 // Update the configuration with WM first and check if any of the stacks need to be resized
20546 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20547 // necessary. This way we don't need to relaunch again afterwards in
20548 // ensureActivityConfigurationLocked().
20549 if (mWindowManager != null) {
20550 final int[] resizedStacks =
20551 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20552 if (resizedStacks != null) {
20553 for (int stackId : resizedStacks) {
20554 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20562 /** Applies latest configuration and/or visibility updates if needed. */
20563 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20564 boolean kept = true;
20565 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20566 // mainStack is null during startup.
20567 if (mainStack != null) {
20568 if (changes != 0 && starting == null) {
20569 // If the configuration changed, and the caller is not already
20570 // in the process of starting an activity, then find the top
20571 // activity to check if its configuration needs to change.
20572 starting = mainStack.topRunningActivityLocked();
20575 if (starting != null) {
20576 kept = starting.ensureActivityConfigurationLocked(changes,
20577 false /* preserveWindow */);
20578 // And we need to make sure at this point that all other activities
20579 // are made visible with the correct configuration.
20580 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20581 !PRESERVE_WINDOWS);
20588 /** Helper method that requests bounds from WM and applies them to stack. */
20589 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20590 final Rect newStackBounds = new Rect();
20591 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20592 mStackSupervisor.resizeStackLocked(
20593 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20594 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20595 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20599 * Decide based on the configuration whether we should show the ANR,
20600 * crash, etc dialogs. The idea is that if there is no affordance to
20601 * press the on-screen buttons, or the user experience would be more
20602 * greatly impacted than the crash itself, we shouldn't show the dialog.
20604 * A thought: SystemUI might also want to get told about this, the Power
20605 * dialog / global actions also might want different behaviors.
20607 private static boolean shouldShowDialogs(Configuration config) {
20608 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20609 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20610 && config.navigation == Configuration.NAVIGATION_NONAV);
20611 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20612 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20613 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20614 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20615 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20616 return inputMethodExists && uiModeSupportsDialogs;
20620 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20621 synchronized (this) {
20622 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20623 if (srec != null) {
20624 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20630 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20631 Intent resultData) {
20633 synchronized (this) {
20634 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20636 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20642 public int getLaunchedFromUid(IBinder activityToken) {
20643 ActivityRecord srec;
20644 synchronized (this) {
20645 srec = ActivityRecord.forTokenLocked(activityToken);
20647 if (srec == null) {
20650 return srec.launchedFromUid;
20653 public String getLaunchedFromPackage(IBinder activityToken) {
20654 ActivityRecord srec;
20655 synchronized (this) {
20656 srec = ActivityRecord.forTokenLocked(activityToken);
20658 if (srec == null) {
20661 return srec.launchedFromPackage;
20664 // =========================================================
20665 // LIFETIME MANAGEMENT
20666 // =========================================================
20668 // Returns whether the app is receiving broadcast.
20669 // If receiving, fetch all broadcast queues which the app is
20670 // the current [or imminent] receiver on.
20671 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20672 ArraySet<BroadcastQueue> receivingQueues) {
20673 if (!app.curReceivers.isEmpty()) {
20674 for (BroadcastRecord r : app.curReceivers) {
20675 receivingQueues.add(r.queue);
20680 // It's not the current receiver, but it might be starting up to become one
20681 for (BroadcastQueue queue : mBroadcastQueues) {
20682 final BroadcastRecord r = queue.mPendingBroadcast;
20683 if (r != null && r.curApp == app) {
20684 // found it; report which queue it's in
20685 receivingQueues.add(queue);
20689 return !receivingQueues.isEmpty();
20692 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20693 int targetUid, ComponentName targetComponent, String targetProcess) {
20694 if (!mTrackingAssociations) {
20697 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20698 = mAssociations.get(targetUid);
20699 if (components == null) {
20700 components = new ArrayMap<>();
20701 mAssociations.put(targetUid, components);
20703 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20704 if (sourceUids == null) {
20705 sourceUids = new SparseArray<>();
20706 components.put(targetComponent, sourceUids);
20708 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20709 if (sourceProcesses == null) {
20710 sourceProcesses = new ArrayMap<>();
20711 sourceUids.put(sourceUid, sourceProcesses);
20713 Association ass = sourceProcesses.get(sourceProcess);
20715 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20717 sourceProcesses.put(sourceProcess, ass);
20721 if (ass.mNesting == 1) {
20722 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20723 ass.mLastState = sourceState;
20728 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20729 ComponentName targetComponent) {
20730 if (!mTrackingAssociations) {
20733 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20734 = mAssociations.get(targetUid);
20735 if (components == null) {
20738 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20739 if (sourceUids == null) {
20742 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20743 if (sourceProcesses == null) {
20746 Association ass = sourceProcesses.get(sourceProcess);
20747 if (ass == null || ass.mNesting <= 0) {
20751 if (ass.mNesting == 0) {
20752 long uptime = SystemClock.uptimeMillis();
20753 ass.mTime += uptime - ass.mStartTime;
20754 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20755 += uptime - ass.mLastStateUptime;
20756 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20760 private void noteUidProcessState(final int uid, final int state) {
20761 mBatteryStatsService.noteUidProcessState(uid, state);
20762 if (mTrackingAssociations) {
20763 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20764 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20765 = mAssociations.valueAt(i1);
20766 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20767 SparseArray<ArrayMap<String, Association>> sourceUids
20768 = targetComponents.valueAt(i2);
20769 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20770 if (sourceProcesses != null) {
20771 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20772 Association ass = sourceProcesses.valueAt(i4);
20773 if (ass.mNesting >= 1) {
20774 // currently associated
20775 long uptime = SystemClock.uptimeMillis();
20776 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20777 += uptime - ass.mLastStateUptime;
20778 ass.mLastState = state;
20779 ass.mLastStateUptime = uptime;
20788 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20789 boolean doingAll, long now) {
20790 if (mAdjSeq == app.adjSeq) {
20791 // This adjustment has already been computed.
20792 return app.curRawAdj;
20795 if (app.thread == null) {
20796 app.adjSeq = mAdjSeq;
20797 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20798 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20799 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20802 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20803 app.adjSource = null;
20804 app.adjTarget = null;
20806 app.cached = false;
20808 final int activitiesSize = app.activities.size();
20810 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20811 // The max adjustment doesn't allow this app to be anything
20812 // below foreground, so it is not worth doing work for it.
20813 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20814 app.adjType = "fixed";
20815 app.adjSeq = mAdjSeq;
20816 app.curRawAdj = app.maxAdj;
20817 app.foregroundActivities = false;
20818 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20819 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20820 // System processes can do UI, and when they do we want to have
20821 // them trim their memory after the user leaves the UI. To
20822 // facilitate this, here we need to determine whether or not it
20823 // is currently showing UI.
20824 app.systemNoUi = true;
20825 if (app == TOP_APP) {
20826 app.systemNoUi = false;
20827 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20828 app.adjType = "pers-top-activity";
20829 } else if (app.hasTopUi) {
20830 app.systemNoUi = false;
20831 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20832 app.adjType = "pers-top-ui";
20833 } else if (activitiesSize > 0) {
20834 for (int j = 0; j < activitiesSize; j++) {
20835 final ActivityRecord r = app.activities.get(j);
20837 app.systemNoUi = false;
20841 if (!app.systemNoUi) {
20842 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20844 return (app.curAdj=app.maxAdj);
20847 app.systemNoUi = false;
20849 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20851 // Determine the importance of the process, starting with most
20852 // important to least, and assign an appropriate OOM adjustment.
20856 boolean foregroundActivities = false;
20857 mTmpBroadcastQueue.clear();
20858 if (app == TOP_APP) {
20859 // The last app on the list is the foreground app.
20860 adj = ProcessList.FOREGROUND_APP_ADJ;
20861 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20862 app.adjType = "top-activity";
20863 foregroundActivities = true;
20864 procState = PROCESS_STATE_CUR_TOP;
20865 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20866 } else if (app.instr != null) {
20867 // Don't want to kill running instrumentation.
20868 adj = ProcessList.FOREGROUND_APP_ADJ;
20869 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20870 app.adjType = "instrumentation";
20871 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20872 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20873 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20874 // An app that is currently receiving a broadcast also
20875 // counts as being in the foreground for OOM killer purposes.
20876 // It's placed in a sched group based on the nature of the
20877 // broadcast as reflected by which queue it's active in.
20878 adj = ProcessList.FOREGROUND_APP_ADJ;
20879 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20880 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20881 app.adjType = "broadcast";
20882 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20883 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20884 } else if (app.executingServices.size() > 0) {
20885 // An app that is currently executing a service callback also
20886 // counts as being in the foreground.
20887 adj = ProcessList.FOREGROUND_APP_ADJ;
20888 schedGroup = app.execServicesFg ?
20889 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20890 app.adjType = "exec-service";
20891 procState = ActivityManager.PROCESS_STATE_SERVICE;
20892 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20893 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20895 // As far as we know the process is empty. We may change our mind later.
20896 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20897 // At this point we don't actually know the adjustment. Use the cached adj
20898 // value that the caller wants us to.
20900 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20903 app.adjType = "cch-empty";
20904 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20907 // Examine all activities if not already foreground.
20908 if (!foregroundActivities && activitiesSize > 0) {
20909 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20910 for (int j = 0; j < activitiesSize; j++) {
20911 final ActivityRecord r = app.activities.get(j);
20912 if (r.app != app) {
20913 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20914 + " instead of expected " + app);
20915 if (r.app == null || (r.app.uid == app.uid)) {
20916 // Only fix things up when they look sane
20923 // App has a visible activity; only upgrade adjustment.
20924 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20925 adj = ProcessList.VISIBLE_APP_ADJ;
20926 app.adjType = "vis-activity";
20927 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20929 if (procState > PROCESS_STATE_CUR_TOP) {
20930 procState = PROCESS_STATE_CUR_TOP;
20931 app.adjType = "vis-activity";
20932 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20934 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20935 app.cached = false;
20937 foregroundActivities = true;
20938 final TaskRecord task = r.getTask();
20939 if (task != null && minLayer > 0) {
20940 final int layer = task.mLayerRank;
20941 if (layer >= 0 && minLayer > layer) {
20946 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20947 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20948 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20949 app.adjType = "pause-activity";
20950 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20952 if (procState > PROCESS_STATE_CUR_TOP) {
20953 procState = PROCESS_STATE_CUR_TOP;
20954 app.adjType = "pause-activity";
20955 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20957 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20958 app.cached = false;
20960 foregroundActivities = true;
20961 } else if (r.state == ActivityState.STOPPING) {
20962 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20963 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20964 app.adjType = "stop-activity";
20965 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20967 // For the process state, we will at this point consider the
20968 // process to be cached. It will be cached either as an activity
20969 // or empty depending on whether the activity is finishing. We do
20970 // this so that we can treat the process as cached for purposes of
20971 // memory trimming (determing current memory level, trim command to
20972 // send to process) since there can be an arbitrary number of stopping
20973 // processes and they should soon all go into the cached state.
20974 if (!r.finishing) {
20975 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20976 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20977 app.adjType = "stop-activity";
20978 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20981 app.cached = false;
20983 foregroundActivities = true;
20985 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20986 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20987 app.adjType = "cch-act";
20988 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20992 if (adj == ProcessList.VISIBLE_APP_ADJ) {
20997 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20998 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20999 if (app.foregroundServices) {
21000 // The user is aware of this app, so make it visible.
21001 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21002 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21003 app.cached = false;
21004 app.adjType = "fg-service";
21005 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21006 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21007 } else if (app.hasOverlayUi) {
21008 // The process is display an overlay UI.
21009 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21010 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21011 app.cached = false;
21012 app.adjType = "has-overlay-ui";
21013 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21014 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21018 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21019 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21020 if (app.forcingToImportant != null) {
21021 // This is currently used for toasts... they are not interactive, and
21022 // we don't want them to cause the app to become fully foreground (and
21023 // thus out of background check), so we yes the best background level we can.
21024 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21025 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21026 app.cached = false;
21027 app.adjType = "force-imp";
21028 app.adjSource = app.forcingToImportant;
21029 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21030 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21034 if (app == mHeavyWeightProcess) {
21035 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21036 // We don't want to kill the current heavy-weight process.
21037 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21038 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21039 app.cached = false;
21040 app.adjType = "heavy";
21041 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21043 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21044 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21045 app.adjType = "heavy";
21046 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21050 if (app == mHomeProcess) {
21051 if (adj > ProcessList.HOME_APP_ADJ) {
21052 // This process is hosting what we currently consider to be the
21053 // home app, so we don't want to let it go into the background.
21054 adj = ProcessList.HOME_APP_ADJ;
21055 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21056 app.cached = false;
21057 app.adjType = "home";
21058 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21060 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21061 procState = ActivityManager.PROCESS_STATE_HOME;
21062 app.adjType = "home";
21063 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21067 if (app == mPreviousProcess && app.activities.size() > 0) {
21068 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21069 // This was the previous process that showed UI to the user.
21070 // We want to try to keep it around more aggressively, to give
21071 // a good experience around switching between two apps.
21072 adj = ProcessList.PREVIOUS_APP_ADJ;
21073 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21074 app.cached = false;
21075 app.adjType = "previous";
21076 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21078 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21079 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21080 app.adjType = "previous";
21081 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21085 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21086 + " reason=" + app.adjType);
21088 // By default, we use the computed adjustment. It may be changed if
21089 // there are applications dependent on our services or providers, but
21090 // this gives us a baseline and makes sure we don't get into an
21091 // infinite recursion.
21092 app.adjSeq = mAdjSeq;
21093 app.curRawAdj = adj;
21094 app.hasStartedServices = false;
21096 if (mBackupTarget != null && app == mBackupTarget.app) {
21097 // If possible we want to avoid killing apps while they're being backed up
21098 if (adj > ProcessList.BACKUP_APP_ADJ) {
21099 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21100 adj = ProcessList.BACKUP_APP_ADJ;
21101 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21102 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21104 app.adjType = "backup";
21105 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21106 app.cached = false;
21108 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21109 procState = ActivityManager.PROCESS_STATE_BACKUP;
21110 app.adjType = "backup";
21111 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21115 boolean mayBeTop = false;
21116 String mayBeTopType = null;
21117 Object mayBeTopSource = null;
21118 Object mayBeTopTarget = null;
21120 for (int is = app.services.size()-1;
21121 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21122 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21123 || procState > ActivityManager.PROCESS_STATE_TOP);
21125 ServiceRecord s = app.services.valueAt(is);
21126 if (s.startRequested) {
21127 app.hasStartedServices = true;
21128 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21129 procState = ActivityManager.PROCESS_STATE_SERVICE;
21130 app.adjType = "started-services";
21131 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21133 if (app.hasShownUi && app != mHomeProcess) {
21134 // If this process has shown some UI, let it immediately
21135 // go to the LRU list because it may be pretty heavy with
21136 // UI stuff. We'll tag it with a label just to help
21137 // debug and understand what is going on.
21138 if (adj > ProcessList.SERVICE_ADJ) {
21139 app.adjType = "cch-started-ui-services";
21142 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21143 // This service has seen some activity within
21144 // recent memory, so we will keep its process ahead
21145 // of the background processes.
21146 if (adj > ProcessList.SERVICE_ADJ) {
21147 adj = ProcessList.SERVICE_ADJ;
21148 app.adjType = "started-services";
21149 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21150 app.cached = false;
21153 // If we have let the service slide into the background
21154 // state, still have some text describing what it is doing
21155 // even though the service no longer has an impact.
21156 if (adj > ProcessList.SERVICE_ADJ) {
21157 app.adjType = "cch-started-services";
21162 for (int conni = s.connections.size()-1;
21163 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21164 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21165 || procState > ActivityManager.PROCESS_STATE_TOP);
21167 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21169 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21170 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21171 || procState > ActivityManager.PROCESS_STATE_TOP);
21173 // XXX should compute this based on the max of
21174 // all connected clients.
21175 ConnectionRecord cr = clist.get(i);
21176 if (cr.binding.client == app) {
21177 // Binding to ourself is not interesting.
21181 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21182 ProcessRecord client = cr.binding.client;
21183 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21184 TOP_APP, doingAll, now);
21185 int clientProcState = client.curProcState;
21186 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21187 // If the other app is cached for any reason, for purposes here
21188 // we are going to consider it empty. The specific cached state
21189 // doesn't propagate except under certain conditions.
21190 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21192 String adjType = null;
21193 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21194 // Not doing bind OOM management, so treat
21195 // this guy more like a started service.
21196 if (app.hasShownUi && app != mHomeProcess) {
21197 // If this process has shown some UI, let it immediately
21198 // go to the LRU list because it may be pretty heavy with
21199 // UI stuff. We'll tag it with a label just to help
21200 // debug and understand what is going on.
21201 if (adj > clientAdj) {
21202 adjType = "cch-bound-ui-services";
21204 app.cached = false;
21206 clientProcState = procState;
21208 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21209 // This service has not seen activity within
21210 // recent memory, so allow it to drop to the
21211 // LRU list if there is no other reason to keep
21212 // it around. We'll also tag it with a label just
21213 // to help debug and undertand what is going on.
21214 if (adj > clientAdj) {
21215 adjType = "cch-bound-services";
21221 if (adj > clientAdj) {
21222 // If this process has recently shown UI, and
21223 // the process that is binding to it is less
21224 // important than being visible, then we don't
21225 // care about the binding as much as we care
21226 // about letting this process get into the LRU
21227 // list to be killed and restarted if needed for
21229 if (app.hasShownUi && app != mHomeProcess
21230 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21231 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21232 adjType = "cch-bound-ui-services";
21236 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21237 |Context.BIND_IMPORTANT)) != 0) {
21238 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21239 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21240 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21241 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21242 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21243 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21244 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21245 newAdj = clientAdj;
21247 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21248 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21253 if (!client.cached) {
21254 app.cached = false;
21256 if (adj > newAdj) {
21258 adjType = "service";
21262 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21263 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21264 // This will treat important bound services identically to
21265 // the top app, which may behave differently than generic
21266 // foreground work.
21267 if (client.curSchedGroup > schedGroup) {
21268 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21269 schedGroup = client.curSchedGroup;
21271 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21274 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21275 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21276 // Special handling of clients who are in the top state.
21277 // We *may* want to consider this process to be in the
21278 // top state as well, but only if there is not another
21279 // reason for it to be running. Being on the top is a
21280 // special state, meaning you are specifically running
21281 // for the current top app. If the process is already
21282 // running in the background for some other reason, it
21283 // is more important to continue considering it to be
21284 // in the background state.
21286 mayBeTopType = "service";
21287 mayBeTopSource = cr.binding.client;
21288 mayBeTopTarget = s.name;
21289 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21291 // Special handling for above-top states (persistent
21292 // processes). These should not bring the current process
21293 // into the top state, since they are not on top. Instead
21294 // give them the best state after that.
21295 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21297 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21298 } else if (mWakefulness
21299 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21300 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21303 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21306 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21310 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21311 if (clientProcState <
21312 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21314 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21317 if (clientProcState <
21318 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21320 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21323 if (procState > clientProcState) {
21324 procState = clientProcState;
21325 if (adjType == null) {
21326 adjType = "service";
21329 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21330 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21331 app.pendingUiClean = true;
21333 if (adjType != null) {
21334 app.adjType = adjType;
21335 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21336 .REASON_SERVICE_IN_USE;
21337 app.adjSource = cr.binding.client;
21338 app.adjSourceProcState = clientProcState;
21339 app.adjTarget = s.name;
21340 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21341 + ": " + app + ", due to " + cr.binding.client
21342 + " adj=" + adj + " procState=" + procState);
21345 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21346 app.treatLikeActivity = true;
21348 final ActivityRecord a = cr.activity;
21349 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21350 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21351 (a.visible || a.state == ActivityState.RESUMED ||
21352 a.state == ActivityState.PAUSING)) {
21353 adj = ProcessList.FOREGROUND_APP_ADJ;
21354 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21355 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21356 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21358 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21361 app.cached = false;
21362 app.adjType = "service";
21363 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21364 .REASON_SERVICE_IN_USE;
21366 app.adjSourceProcState = procState;
21367 app.adjTarget = s.name;
21368 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21376 for (int provi = app.pubProviders.size()-1;
21377 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21378 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21379 || procState > ActivityManager.PROCESS_STATE_TOP);
21381 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21382 for (int i = cpr.connections.size()-1;
21383 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21384 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21385 || procState > ActivityManager.PROCESS_STATE_TOP);
21387 ContentProviderConnection conn = cpr.connections.get(i);
21388 ProcessRecord client = conn.client;
21389 if (client == app) {
21390 // Being our own client is not interesting.
21393 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21394 int clientProcState = client.curProcState;
21395 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21396 // If the other app is cached for any reason, for purposes here
21397 // we are going to consider it empty.
21398 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21400 String adjType = null;
21401 if (adj > clientAdj) {
21402 if (app.hasShownUi && app != mHomeProcess
21403 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21404 adjType = "cch-ui-provider";
21406 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21407 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21408 adjType = "provider";
21410 app.cached &= client.cached;
21412 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21413 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21414 // Special handling of clients who are in the top state.
21415 // We *may* want to consider this process to be in the
21416 // top state as well, but only if there is not another
21417 // reason for it to be running. Being on the top is a
21418 // special state, meaning you are specifically running
21419 // for the current top app. If the process is already
21420 // running in the background for some other reason, it
21421 // is more important to continue considering it to be
21422 // in the background state.
21424 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21425 mayBeTopType = adjType = "provider-top";
21426 mayBeTopSource = client;
21427 mayBeTopTarget = cpr.name;
21429 // Special handling for above-top states (persistent
21430 // processes). These should not bring the current process
21431 // into the top state, since they are not on top. Instead
21432 // give them the best state after that.
21434 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21435 if (adjType == null) {
21436 adjType = "provider";
21440 if (procState > clientProcState) {
21441 procState = clientProcState;
21443 if (client.curSchedGroup > schedGroup) {
21444 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21446 if (adjType != null) {
21447 app.adjType = adjType;
21448 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21449 .REASON_PROVIDER_IN_USE;
21450 app.adjSource = client;
21451 app.adjSourceProcState = clientProcState;
21452 app.adjTarget = cpr.name;
21453 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21454 + ": " + app + ", due to " + client
21455 + " adj=" + adj + " procState=" + procState);
21458 // If the provider has external (non-framework) process
21459 // dependencies, ensure that its adjustment is at least
21460 // FOREGROUND_APP_ADJ.
21461 if (cpr.hasExternalProcessHandles()) {
21462 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21463 adj = ProcessList.FOREGROUND_APP_ADJ;
21464 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21465 app.cached = false;
21466 app.adjType = "ext-provider";
21467 app.adjTarget = cpr.name;
21468 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21470 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21471 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21476 if (app.lastProviderTime > 0 &&
21477 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21478 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21479 adj = ProcessList.PREVIOUS_APP_ADJ;
21480 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21481 app.cached = false;
21482 app.adjType = "recent-provider";
21483 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21485 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21486 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21487 app.adjType = "recent-provider";
21488 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21492 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21493 // A client of one of our services or providers is in the top state. We
21494 // *may* want to be in the top state, but not if we are already running in
21495 // the background for some other reason. For the decision here, we are going
21496 // to pick out a few specific states that we want to remain in when a client
21497 // is top (states that tend to be longer-term) and otherwise allow it to go
21498 // to the top state.
21499 switch (procState) {
21500 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21501 // Something else is keeping it at this level, just leave it.
21503 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21504 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21505 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21506 case ActivityManager.PROCESS_STATE_SERVICE:
21507 // These all are longer-term states, so pull them up to the top
21508 // of the background states, but not all the way to the top state.
21509 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21510 app.adjType = mayBeTopType;
21511 app.adjSource = mayBeTopSource;
21512 app.adjTarget = mayBeTopTarget;
21513 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21514 + ": " + app + ", due to " + mayBeTopSource
21515 + " adj=" + adj + " procState=" + procState);
21518 // Otherwise, top is a better choice, so take it.
21519 procState = ActivityManager.PROCESS_STATE_TOP;
21520 app.adjType = mayBeTopType;
21521 app.adjSource = mayBeTopSource;
21522 app.adjTarget = mayBeTopTarget;
21523 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21524 + ": " + app + ", due to " + mayBeTopSource
21525 + " adj=" + adj + " procState=" + procState);
21530 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21531 if (app.hasClientActivities) {
21532 // This is a cached process, but with client activities. Mark it so.
21533 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21534 app.adjType = "cch-client-act";
21535 } else if (app.treatLikeActivity) {
21536 // This is a cached process, but somebody wants us to treat it like it has
21537 // an activity, okay!
21538 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21539 app.adjType = "cch-as-act";
21543 if (adj == ProcessList.SERVICE_ADJ) {
21545 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21546 mNewNumServiceProcs++;
21547 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21548 if (!app.serviceb) {
21549 // This service isn't far enough down on the LRU list to
21550 // normally be a B service, but if we are low on RAM and it
21551 // is large we want to force it down since we would prefer to
21552 // keep launcher over it.
21553 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21554 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21555 app.serviceHighRam = true;
21556 app.serviceb = true;
21557 //Slog.i(TAG, "ADJ " + app + " high ram!");
21559 mNewNumAServiceProcs++;
21560 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21563 app.serviceHighRam = false;
21566 if (app.serviceb) {
21567 adj = ProcessList.SERVICE_B_ADJ;
21571 app.curRawAdj = adj;
21573 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21574 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21575 if (adj > app.maxAdj) {
21577 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21578 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21582 // Do final modification to adj. Everything we do between here and applying
21583 // the final setAdj must be done in this function, because we will also use
21584 // it when computing the final cached adj later. Note that we don't need to
21585 // worry about this for max adj above, since max adj will always be used to
21586 // keep it out of the cached vaues.
21587 app.curAdj = app.modifyRawOomAdj(adj);
21588 app.curSchedGroup = schedGroup;
21589 app.curProcState = procState;
21590 app.foregroundActivities = foregroundActivities;
21592 return app.curRawAdj;
21596 * Record new PSS sample for a process.
21598 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21600 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21602 proc.lastPssTime = now;
21603 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21604 if (DEBUG_PSS) Slog.d(TAG_PSS,
21605 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21606 + " state=" + ProcessList.makeProcStateString(procState));
21607 if (proc.initialIdlePss == 0) {
21608 proc.initialIdlePss = pss;
21610 proc.lastPss = pss;
21611 proc.lastSwapPss = swapPss;
21612 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21613 proc.lastCachedPss = pss;
21614 proc.lastCachedSwapPss = swapPss;
21617 final SparseArray<Pair<Long, String>> watchUids
21618 = mMemWatchProcesses.getMap().get(proc.processName);
21620 if (watchUids != null) {
21621 Pair<Long, String> val = watchUids.get(proc.uid);
21623 val = watchUids.get(0);
21629 if (check != null) {
21630 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21631 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21632 if (!isDebuggable) {
21633 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21634 isDebuggable = true;
21637 if (isDebuggable) {
21638 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21639 final ProcessRecord myProc = proc;
21640 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21641 mMemWatchDumpProcName = proc.processName;
21642 mMemWatchDumpFile = heapdumpFile.toString();
21643 mMemWatchDumpPid = proc.pid;
21644 mMemWatchDumpUid = proc.uid;
21645 BackgroundThread.getHandler().post(new Runnable() {
21647 public void run() {
21648 revokeUriPermission(ActivityThread.currentActivityThread()
21649 .getApplicationThread(),
21650 null, DumpHeapActivity.JAVA_URI,
21651 Intent.FLAG_GRANT_READ_URI_PERMISSION
21652 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21653 UserHandle.myUserId());
21654 ParcelFileDescriptor fd = null;
21656 heapdumpFile.delete();
21657 fd = ParcelFileDescriptor.open(heapdumpFile,
21658 ParcelFileDescriptor.MODE_CREATE |
21659 ParcelFileDescriptor.MODE_TRUNCATE |
21660 ParcelFileDescriptor.MODE_WRITE_ONLY |
21661 ParcelFileDescriptor.MODE_APPEND);
21662 IApplicationThread thread = myProc.thread;
21663 if (thread != null) {
21665 if (DEBUG_PSS) Slog.d(TAG_PSS,
21666 "Requesting dump heap from "
21667 + myProc + " to " + heapdumpFile);
21668 thread.dumpHeap(true, heapdumpFile.toString(), fd);
21669 } catch (RemoteException e) {
21672 } catch (FileNotFoundException e) {
21673 e.printStackTrace();
21678 } catch (IOException e) {
21685 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21686 + ", but debugging not enabled");
21693 * Schedule PSS collection of a process.
21695 void requestPssLocked(ProcessRecord proc, int procState) {
21696 if (mPendingPssProcesses.contains(proc)) {
21699 if (mPendingPssProcesses.size() == 0) {
21700 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21702 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21703 proc.pssProcState = procState;
21704 mPendingPssProcesses.add(proc);
21708 * Schedule PSS collection of all processes.
21710 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21712 if (now < (mLastFullPssTime +
21713 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21714 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21718 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21719 mLastFullPssTime = now;
21720 mFullPssPending = true;
21721 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21722 mPendingPssProcesses.clear();
21723 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21724 ProcessRecord app = mLruProcesses.get(i);
21725 if (app.thread == null
21726 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21729 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21730 app.pssProcState = app.setProcState;
21731 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21732 mTestPssMode, isSleepingLocked(), now);
21733 mPendingPssProcesses.add(app);
21736 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21739 public void setTestPssMode(boolean enabled) {
21740 synchronized (this) {
21741 mTestPssMode = enabled;
21743 // Whenever we enable the mode, we want to take a snapshot all of current
21744 // process mem use.
21745 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21751 * Ask a given process to GC right now.
21753 final void performAppGcLocked(ProcessRecord app) {
21755 app.lastRequestedGc = SystemClock.uptimeMillis();
21756 if (app.thread != null) {
21757 if (app.reportLowMemory) {
21758 app.reportLowMemory = false;
21759 app.thread.scheduleLowMemory();
21761 app.thread.processInBackground();
21764 } catch (Exception e) {
21770 * Returns true if things are idle enough to perform GCs.
21772 private final boolean canGcNowLocked() {
21773 boolean processingBroadcasts = false;
21774 for (BroadcastQueue q : mBroadcastQueues) {
21775 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21776 processingBroadcasts = true;
21779 return !processingBroadcasts
21780 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21784 * Perform GCs on all processes that are waiting for it, but only
21785 * if things are idle.
21787 final void performAppGcsLocked() {
21788 final int N = mProcessesToGc.size();
21792 if (canGcNowLocked()) {
21793 while (mProcessesToGc.size() > 0) {
21794 ProcessRecord proc = mProcessesToGc.remove(0);
21795 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21796 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21797 <= SystemClock.uptimeMillis()) {
21798 // To avoid spamming the system, we will GC processes one
21799 // at a time, waiting a few seconds between each.
21800 performAppGcLocked(proc);
21801 scheduleAppGcsLocked();
21804 // It hasn't been long enough since we last GCed this
21805 // process... put it in the list to wait for its time.
21806 addProcessToGcListLocked(proc);
21812 scheduleAppGcsLocked();
21817 * If all looks good, perform GCs on all processes waiting for them.
21819 final void performAppGcsIfAppropriateLocked() {
21820 if (canGcNowLocked()) {
21821 performAppGcsLocked();
21824 // Still not idle, wait some more.
21825 scheduleAppGcsLocked();
21829 * Schedule the execution of all pending app GCs.
21831 final void scheduleAppGcsLocked() {
21832 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21834 if (mProcessesToGc.size() > 0) {
21835 // Schedule a GC for the time to the next process.
21836 ProcessRecord proc = mProcessesToGc.get(0);
21837 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21839 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21840 long now = SystemClock.uptimeMillis();
21841 if (when < (now+mConstants.GC_TIMEOUT)) {
21842 when = now + mConstants.GC_TIMEOUT;
21844 mHandler.sendMessageAtTime(msg, when);
21849 * Add a process to the array of processes waiting to be GCed. Keeps the
21850 * list in sorted order by the last GC time. The process can't already be
21853 final void addProcessToGcListLocked(ProcessRecord proc) {
21854 boolean added = false;
21855 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21856 if (mProcessesToGc.get(i).lastRequestedGc <
21857 proc.lastRequestedGc) {
21859 mProcessesToGc.add(i+1, proc);
21864 mProcessesToGc.add(0, proc);
21869 * Set up to ask a process to GC itself. This will either do it
21870 * immediately, or put it on the list of processes to gc the next
21871 * time things are idle.
21873 final void scheduleAppGcLocked(ProcessRecord app) {
21874 long now = SystemClock.uptimeMillis();
21875 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21878 if (!mProcessesToGc.contains(app)) {
21879 addProcessToGcListLocked(app);
21880 scheduleAppGcsLocked();
21884 final void checkExcessivePowerUsageLocked(boolean doKills) {
21885 updateCpuStatsNow();
21887 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21888 boolean doWakeKills = doKills;
21889 boolean doCpuKills = doKills;
21890 if (mLastPowerCheckRealtime == 0) {
21891 doWakeKills = false;
21893 if (mLastPowerCheckUptime == 0) {
21894 doCpuKills = false;
21896 if (stats.isScreenOn()) {
21897 doWakeKills = false;
21899 final long curRealtime = SystemClock.elapsedRealtime();
21900 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21901 final long curUptime = SystemClock.uptimeMillis();
21902 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21903 mLastPowerCheckRealtime = curRealtime;
21904 mLastPowerCheckUptime = curUptime;
21905 if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21906 doWakeKills = false;
21908 if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21909 doCpuKills = false;
21911 int i = mLruProcesses.size();
21914 ProcessRecord app = mLruProcesses.get(i);
21915 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21917 synchronized (stats) {
21918 wtime = stats.getProcessWakeTime(app.info.uid,
21919 app.pid, curRealtime);
21921 long wtimeUsed = wtime - app.lastWakeTime;
21922 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21924 StringBuilder sb = new StringBuilder(128);
21925 sb.append("Wake for ");
21926 app.toShortString(sb);
21927 sb.append(": over ");
21928 TimeUtils.formatDuration(realtimeSince, sb);
21929 sb.append(" used ");
21930 TimeUtils.formatDuration(wtimeUsed, sb);
21932 sb.append((wtimeUsed*100)/realtimeSince);
21934 Slog.i(TAG_POWER, sb.toString());
21936 sb.append("CPU for ");
21937 app.toShortString(sb);
21938 sb.append(": over ");
21939 TimeUtils.formatDuration(uptimeSince, sb);
21940 sb.append(" used ");
21941 TimeUtils.formatDuration(cputimeUsed, sb);
21943 sb.append((cputimeUsed*100)/uptimeSince);
21945 Slog.i(TAG_POWER, sb.toString());
21947 // If a process has held a wake lock for more
21948 // than 50% of the time during this period,
21949 // that sounds bad. Kill!
21950 if (doWakeKills && realtimeSince > 0
21951 && ((wtimeUsed*100)/realtimeSince) >= 50) {
21952 synchronized (stats) {
21953 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21954 realtimeSince, wtimeUsed);
21956 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21957 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21958 } else if (doCpuKills && uptimeSince > 0
21959 && ((cputimeUsed*100)/uptimeSince) >= 25) {
21960 synchronized (stats) {
21961 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21962 uptimeSince, cputimeUsed);
21964 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21965 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21967 app.lastWakeTime = wtime;
21968 app.lastCpuTime = app.curCpuTime;
21974 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21976 boolean success = true;
21978 if (app.curRawAdj != app.setRawAdj) {
21979 app.setRawAdj = app.curRawAdj;
21984 if (app.curAdj != app.setAdj) {
21985 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21986 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21987 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21989 app.setAdj = app.curAdj;
21990 app.verifiedAdj = ProcessList.INVALID_ADJ;
21993 if (app.setSchedGroup != app.curSchedGroup) {
21994 int oldSchedGroup = app.setSchedGroup;
21995 app.setSchedGroup = app.curSchedGroup;
21996 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21997 "Setting sched group of " + app.processName
21998 + " to " + app.curSchedGroup);
21999 if (app.waitingToKill != null && app.curReceivers.isEmpty()
22000 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22001 app.kill(app.waitingToKill, true);
22005 switch (app.curSchedGroup) {
22006 case ProcessList.SCHED_GROUP_BACKGROUND:
22007 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22009 case ProcessList.SCHED_GROUP_TOP_APP:
22010 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22011 processGroup = THREAD_GROUP_TOP_APP;
22014 processGroup = THREAD_GROUP_DEFAULT;
22017 long oldId = Binder.clearCallingIdentity();
22019 setProcessGroup(app.pid, processGroup);
22020 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22021 // do nothing if we already switched to RT
22022 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22023 mVrController.onTopProcChangedLocked(app);
22024 if (mUseFifoUiScheduling) {
22025 // Switch UI pipeline for app to SCHED_FIFO
22026 app.savedPriority = Process.getThreadPriority(app.pid);
22027 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22028 if (app.renderThreadTid != 0) {
22029 scheduleAsFifoPriority(app.renderThreadTid,
22030 /* suppressLogs */true);
22031 if (DEBUG_OOM_ADJ) {
22032 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22033 app.renderThreadTid + ") to FIFO");
22036 if (DEBUG_OOM_ADJ) {
22037 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22041 // Boost priority for top app UI and render threads
22042 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22043 if (app.renderThreadTid != 0) {
22045 setThreadPriority(app.renderThreadTid,
22046 TOP_APP_PRIORITY_BOOST);
22047 } catch (IllegalArgumentException e) {
22048 // thread died, ignore
22053 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22054 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22055 mVrController.onTopProcChangedLocked(app);
22056 if (mUseFifoUiScheduling) {
22057 // Reset UI pipeline to SCHED_OTHER
22058 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22059 setThreadPriority(app.pid, app.savedPriority);
22060 if (app.renderThreadTid != 0) {
22061 setThreadScheduler(app.renderThreadTid,
22063 setThreadPriority(app.renderThreadTid, -4);
22066 // Reset priority for top app UI and render threads
22067 setThreadPriority(app.pid, 0);
22068 if (app.renderThreadTid != 0) {
22069 setThreadPriority(app.renderThreadTid, 0);
22073 } catch (Exception e) {
22075 Slog.w(TAG, "Failed setting process group of " + app.pid
22076 + " to " + app.curSchedGroup);
22077 Slog.w(TAG, "at location", e);
22080 Binder.restoreCallingIdentity(oldId);
22084 if (app.repForegroundActivities != app.foregroundActivities) {
22085 app.repForegroundActivities = app.foregroundActivities;
22086 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22088 if (app.repProcState != app.curProcState) {
22089 app.repProcState = app.curProcState;
22090 if (app.thread != null) {
22093 //RuntimeException h = new RuntimeException("here");
22094 Slog.i(TAG, "Sending new process state " + app.repProcState
22095 + " to " + app /*, h*/);
22097 app.thread.setProcessState(app.repProcState);
22098 } catch (RemoteException e) {
22102 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22103 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22104 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22105 // Experimental code to more aggressively collect pss while
22106 // running test... the problem is that this tends to collect
22107 // the data right when a process is transitioning between process
22108 // states, which well tend to give noisy data.
22109 long start = SystemClock.uptimeMillis();
22110 long pss = Debug.getPss(app.pid, mTmpLong, null);
22111 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22112 mPendingPssProcesses.remove(app);
22113 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22114 + " to " + app.curProcState + ": "
22115 + (SystemClock.uptimeMillis()-start) + "ms");
22117 app.lastStateTime = now;
22118 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22119 mTestPssMode, isSleepingLocked(), now);
22120 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22121 + ProcessList.makeProcStateString(app.setProcState) + " to "
22122 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22123 + (app.nextPssTime-now) + ": " + app);
22125 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22126 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22128 requestPssLocked(app, app.setProcState);
22129 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22130 mTestPssMode, isSleepingLocked(), now);
22131 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22132 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22134 if (app.setProcState != app.curProcState) {
22135 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22136 "Proc state change of " + app.processName
22137 + " to " + app.curProcState);
22138 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22139 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22140 if (setImportant && !curImportant) {
22141 // This app is no longer something we consider important enough to allow to
22142 // use arbitrary amounts of battery power. Note
22143 // its current wake lock time to later know to kill it if
22144 // it is not behaving well.
22145 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22146 synchronized (stats) {
22147 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
22148 app.pid, nowElapsed);
22150 app.lastCpuTime = app.curCpuTime;
22153 // Inform UsageStats of important process state change
22154 // Must be called before updating setProcState
22155 maybeUpdateUsageStatsLocked(app, nowElapsed);
22157 app.setProcState = app.curProcState;
22158 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22159 app.notCachedSinceIdle = false;
22162 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22164 app.procStateChanged = true;
22166 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22167 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22168 // For apps that sit around for a long time in the interactive state, we need
22169 // to report this at least once a day so they don't go idle.
22170 maybeUpdateUsageStatsLocked(app, nowElapsed);
22173 if (changes != 0) {
22174 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22175 "Changes in " + app + ": " + changes);
22176 int i = mPendingProcessChanges.size()-1;
22177 ProcessChangeItem item = null;
22179 item = mPendingProcessChanges.get(i);
22180 if (item.pid == app.pid) {
22181 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22182 "Re-using existing item: " + item);
22188 // No existing item in pending changes; need a new one.
22189 final int NA = mAvailProcessChanges.size();
22191 item = mAvailProcessChanges.remove(NA-1);
22192 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22193 "Retrieving available item: " + item);
22195 item = new ProcessChangeItem();
22196 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22197 "Allocating new item: " + item);
22200 item.pid = app.pid;
22201 item.uid = app.info.uid;
22202 if (mPendingProcessChanges.size() == 0) {
22203 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22204 "*** Enqueueing dispatch processes changed!");
22205 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22207 mPendingProcessChanges.add(item);
22209 item.changes |= changes;
22210 item.foregroundActivities = app.repForegroundActivities;
22211 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22212 "Item " + Integer.toHexString(System.identityHashCode(item))
22213 + " " + app.toShortString() + ": changes=" + item.changes
22214 + " foreground=" + item.foregroundActivities
22215 + " type=" + app.adjType + " source=" + app.adjSource
22216 + " target=" + app.adjTarget);
22222 private boolean isEphemeralLocked(int uid) {
22223 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22224 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22227 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22232 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22233 final UidRecord.ChangeItem pendingChange;
22234 if (uidRec == null || uidRec.pendingChange == null) {
22235 if (mPendingUidChanges.size() == 0) {
22236 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22237 "*** Enqueueing dispatch uid changed!");
22238 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22240 final int NA = mAvailUidChanges.size();
22242 pendingChange = mAvailUidChanges.remove(NA-1);
22243 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22244 "Retrieving available item: " + pendingChange);
22246 pendingChange = new UidRecord.ChangeItem();
22247 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22248 "Allocating new item: " + pendingChange);
22250 if (uidRec != null) {
22251 uidRec.pendingChange = pendingChange;
22252 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
22253 // If this uid is going away, and we haven't yet reported it is gone,
22255 change = UidRecord.CHANGE_GONE_IDLE;
22257 } else if (uid < 0) {
22258 throw new IllegalArgumentException("No UidRecord or uid");
22260 pendingChange.uidRecord = uidRec;
22261 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22262 mPendingUidChanges.add(pendingChange);
22264 pendingChange = uidRec.pendingChange;
22265 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
22266 change = UidRecord.CHANGE_GONE_IDLE;
22269 pendingChange.change = change;
22270 pendingChange.processState = uidRec != null
22271 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22272 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22273 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22274 if (uidRec != null) {
22275 uidRec.updateLastDispatchedProcStateSeq(change);
22278 // Directly update the power manager, since we sit on top of it and it is critical
22279 // it be kept in sync (so wake locks will be held as soon as appropriate).
22280 if (mLocalPowerManager != null) {
22282 case UidRecord.CHANGE_GONE:
22283 case UidRecord.CHANGE_GONE_IDLE:
22284 mLocalPowerManager.uidGone(pendingChange.uid);
22286 case UidRecord.CHANGE_IDLE:
22287 mLocalPowerManager.uidIdle(pendingChange.uid);
22289 case UidRecord.CHANGE_ACTIVE:
22290 mLocalPowerManager.uidActive(pendingChange.uid);
22293 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22294 pendingChange.processState);
22300 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22301 String authority) {
22302 if (app == null) return;
22303 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22304 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22305 if (userState == null) return;
22306 final long now = SystemClock.elapsedRealtime();
22307 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22308 if (lastReported == null || lastReported < now - 60 * 1000L) {
22309 if (mSystemReady) {
22310 // Cannot touch the user stats if not system ready
22311 mUsageStatsService.reportContentProviderUsage(
22312 authority, providerPkgName, app.userId);
22314 userState.mProviderLastReportedFg.put(authority, now);
22319 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22320 if (DEBUG_USAGE_STATS) {
22321 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22322 + "] state changes: old = " + app.setProcState + ", new = "
22323 + app.curProcState);
22325 if (mUsageStatsService == null) {
22328 boolean isInteraction;
22329 // To avoid some abuse patterns, we are going to be careful about what we consider
22330 // to be an app interaction. Being the top activity doesn't count while the display
22331 // is sleeping, nor do short foreground services.
22332 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22333 isInteraction = true;
22334 app.fgInteractionTime = 0;
22335 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22336 if (app.fgInteractionTime == 0) {
22337 app.fgInteractionTime = nowElapsed;
22338 isInteraction = false;
22340 isInteraction = nowElapsed > app.fgInteractionTime
22341 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22344 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22345 app.fgInteractionTime = 0;
22347 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22348 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22349 app.interactionEventTime = nowElapsed;
22350 String[] packages = app.getPackageList();
22351 if (packages != null) {
22352 for (int i = 0; i < packages.length; i++) {
22353 mUsageStatsService.reportEvent(packages[i], app.userId,
22354 UsageEvents.Event.SYSTEM_INTERACTION);
22358 app.reportedInteraction = isInteraction;
22359 if (!isInteraction) {
22360 app.interactionEventTime = 0;
22364 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22365 if (proc.thread != null) {
22366 if (proc.baseProcessTracker != null) {
22367 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22372 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22373 ProcessRecord TOP_APP, boolean doingAll, long now) {
22374 if (app.thread == null) {
22378 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22380 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22383 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22385 if (isForeground != proc.foregroundServices) {
22386 proc.foregroundServices = isForeground;
22387 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22389 if (isForeground) {
22390 if (curProcs == null) {
22391 curProcs = new ArrayList<ProcessRecord>();
22392 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22394 if (!curProcs.contains(proc)) {
22395 curProcs.add(proc);
22396 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22397 proc.info.packageName, proc.info.uid);
22400 if (curProcs != null) {
22401 if (curProcs.remove(proc)) {
22402 mBatteryStatsService.noteEvent(
22403 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22404 proc.info.packageName, proc.info.uid);
22405 if (curProcs.size() <= 0) {
22406 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22412 updateOomAdjLocked();
22417 private final ActivityRecord resumedAppLocked() {
22418 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22422 pkg = act.packageName;
22423 uid = act.info.applicationInfo.uid;
22428 // Has the UID or resumed package name changed?
22429 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22430 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22431 if (mCurResumedPackage != null) {
22432 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22433 mCurResumedPackage, mCurResumedUid);
22435 mCurResumedPackage = pkg;
22436 mCurResumedUid = uid;
22437 if (mCurResumedPackage != null) {
22438 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22439 mCurResumedPackage, mCurResumedUid);
22446 * Update OomAdj for a specific process.
22447 * @param app The process to update
22448 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22449 * if necessary, or skip.
22450 * @return whether updateOomAdjLocked(app) was successful.
22452 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22453 final ActivityRecord TOP_ACT = resumedAppLocked();
22454 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22455 final boolean wasCached = app.cached;
22459 // This is the desired cached adjusment we want to tell it to use.
22460 // If our app is currently cached, we know it, and that is it. Otherwise,
22461 // we don't know it yet, and it needs to now be cached we will then
22462 // need to do a complete oom adj.
22463 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22464 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22465 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22466 SystemClock.uptimeMillis());
22468 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22469 // Changed to/from cached state, so apps after it in the LRU
22470 // list may also be changed.
22471 updateOomAdjLocked();
22476 final void updateOomAdjLocked() {
22477 final ActivityRecord TOP_ACT = resumedAppLocked();
22478 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22479 final long now = SystemClock.uptimeMillis();
22480 final long nowElapsed = SystemClock.elapsedRealtime();
22481 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22482 final int N = mLruProcesses.size();
22485 RuntimeException e = new RuntimeException();
22486 e.fillInStackTrace();
22487 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22490 // Reset state in all uid records.
22491 for (int i=mActiveUids.size()-1; i>=0; i--) {
22492 final UidRecord uidRec = mActiveUids.valueAt(i);
22493 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22494 "Starting update of " + uidRec);
22498 mStackSupervisor.rankTaskLayersIfNeeded();
22501 mNewNumServiceProcs = 0;
22502 mNewNumAServiceProcs = 0;
22504 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22505 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22507 // Let's determine how many processes we have running vs.
22508 // how many slots we have for background processes; we may want
22509 // to put multiple processes in a slot of there are enough of
22511 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22512 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22513 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22514 if (numEmptyProcs > cachedProcessLimit) {
22515 // If there are more empty processes than our limit on cached
22516 // processes, then use the cached process limit for the factor.
22517 // This ensures that the really old empty processes get pushed
22518 // down to the bottom, so if we are running low on memory we will
22519 // have a better chance at keeping around more cached processes
22520 // instead of a gazillion empty processes.
22521 numEmptyProcs = cachedProcessLimit;
22523 int emptyFactor = numEmptyProcs/numSlots;
22524 if (emptyFactor < 1) emptyFactor = 1;
22525 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22526 if (cachedFactor < 1) cachedFactor = 1;
22527 int stepCached = 0;
22531 int numTrimming = 0;
22533 mNumNonCachedProcs = 0;
22534 mNumCachedHiddenProcs = 0;
22536 // First update the OOM adjustment for each of the
22537 // application processes based on their current state.
22538 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22539 int nextCachedAdj = curCachedAdj+1;
22540 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22541 int nextEmptyAdj = curEmptyAdj+2;
22542 for (int i=N-1; i>=0; i--) {
22543 ProcessRecord app = mLruProcesses.get(i);
22544 if (!app.killedByAm && app.thread != null) {
22545 app.procStateChanged = false;
22546 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22548 // If we haven't yet assigned the final cached adj
22549 // to the process, do that now.
22550 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22551 switch (app.curProcState) {
22552 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22553 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22554 // This process is a cached process holding activities...
22555 // assign it the next cached value for that type, and then
22556 // step that cached level.
22557 app.curRawAdj = curCachedAdj;
22558 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22559 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22560 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22562 if (curCachedAdj != nextCachedAdj) {
22564 if (stepCached >= cachedFactor) {
22566 curCachedAdj = nextCachedAdj;
22567 nextCachedAdj += 2;
22568 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22569 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22575 // For everything else, assign next empty cached process
22576 // level and bump that up. Note that this means that
22577 // long-running services that have dropped down to the
22578 // cached level will be treated as empty (since their process
22579 // state is still as a service), which is what we want.
22580 app.curRawAdj = curEmptyAdj;
22581 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22582 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22583 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22585 if (curEmptyAdj != nextEmptyAdj) {
22587 if (stepEmpty >= emptyFactor) {
22589 curEmptyAdj = nextEmptyAdj;
22591 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22592 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22600 applyOomAdjLocked(app, true, now, nowElapsed);
22602 // Count the number of process types.
22603 switch (app.curProcState) {
22604 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22605 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22606 mNumCachedHiddenProcs++;
22608 if (numCached > cachedProcessLimit) {
22609 app.kill("cached #" + numCached, true);
22612 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22613 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22614 && app.lastActivityTime < oldTime) {
22615 app.kill("empty for "
22616 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22617 / 1000) + "s", true);
22620 if (numEmpty > emptyProcessLimit) {
22621 app.kill("empty #" + numEmpty, true);
22626 mNumNonCachedProcs++;
22630 if (app.isolated && app.services.size() <= 0) {
22631 // If this is an isolated process, and there are no
22632 // services running in it, then the process is no longer
22633 // needed. We agressively kill these because we can by
22634 // definition not re-use the same process again, and it is
22635 // good to avoid having whatever code was running in them
22636 // left sitting around after no longer needed.
22637 app.kill("isolated not needed", true);
22639 // Keeping this process, update its uid.
22640 final UidRecord uidRec = app.uidRecord;
22641 if (uidRec != null) {
22642 uidRec.ephemeral = app.info.isInstantApp();
22643 if (uidRec.curProcState > app.curProcState) {
22644 uidRec.curProcState = app.curProcState;
22646 if (app.foregroundServices) {
22647 uidRec.foregroundServices = true;
22652 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22653 && !app.killedByAm) {
22659 incrementProcStateSeqAndNotifyAppsLocked();
22661 mNumServiceProcs = mNewNumServiceProcs;
22663 // Now determine the memory trimming level of background processes.
22664 // Unfortunately we need to start at the back of the list to do this
22665 // properly. We only do this if the number of background apps we
22666 // are managing to keep around is less than half the maximum we desire;
22667 // if we are keeping a good number around, we'll let them use whatever
22668 // memory they want.
22669 final int numCachedAndEmpty = numCached + numEmpty;
22671 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22672 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22673 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22674 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22675 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22676 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22678 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22681 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22683 // We always allow the memory level to go up (better). We only allow it to go
22684 // down if we are in a state where that is allowed, *and* the total number of processes
22685 // has gone down since last time.
22686 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22687 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22688 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22689 if (memFactor > mLastMemoryLevel) {
22690 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22691 memFactor = mLastMemoryLevel;
22692 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22695 if (memFactor != mLastMemoryLevel) {
22696 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22698 mLastMemoryLevel = memFactor;
22699 mLastNumProcesses = mLruProcesses.size();
22700 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22701 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22702 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22703 if (mLowRamStartTime == 0) {
22704 mLowRamStartTime = now;
22708 switch (memFactor) {
22709 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22710 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22712 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22713 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22716 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22719 int factor = numTrimming/3;
22721 if (mHomeProcess != null) minFactor++;
22722 if (mPreviousProcess != null) minFactor++;
22723 if (factor < minFactor) factor = minFactor;
22724 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22725 for (int i=N-1; i>=0; i--) {
22726 ProcessRecord app = mLruProcesses.get(i);
22727 if (allChanged || app.procStateChanged) {
22728 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22729 app.procStateChanged = false;
22731 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22732 && !app.killedByAm) {
22733 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22735 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22736 "Trimming memory of " + app.processName + " to " + curLevel);
22737 app.thread.scheduleTrimMemory(curLevel);
22738 } catch (RemoteException e) {
22741 // For now we won't do this; our memory trimming seems
22742 // to be good enough at this point that destroying
22743 // activities causes more harm than good.
22744 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22745 && app != mHomeProcess && app != mPreviousProcess) {
22746 // Need to do this on its own message because the stack may not
22747 // be in a consistent state at this point.
22748 // For these apps we will also finish their activities
22749 // to help them free memory.
22750 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22754 app.trimMemoryLevel = curLevel;
22756 if (step >= factor) {
22758 switch (curLevel) {
22759 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22760 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22762 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22763 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22767 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22768 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22769 && app.thread != null) {
22771 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22772 "Trimming memory of heavy-weight " + app.processName
22773 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22774 app.thread.scheduleTrimMemory(
22775 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22776 } catch (RemoteException e) {
22779 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22781 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22782 || app.systemNoUi) && app.pendingUiClean) {
22783 // If this application is now in the background and it
22784 // had done UI, then give it the special trim level to
22785 // have it free UI resources.
22786 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22787 if (app.trimMemoryLevel < level && app.thread != null) {
22789 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22790 "Trimming memory of bg-ui " + app.processName
22792 app.thread.scheduleTrimMemory(level);
22793 } catch (RemoteException e) {
22796 app.pendingUiClean = false;
22798 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22800 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22801 "Trimming memory of fg " + app.processName
22802 + " to " + fgTrimLevel);
22803 app.thread.scheduleTrimMemory(fgTrimLevel);
22804 } catch (RemoteException e) {
22807 app.trimMemoryLevel = fgTrimLevel;
22811 if (mLowRamStartTime != 0) {
22812 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22813 mLowRamStartTime = 0;
22815 for (int i=N-1; i>=0; i--) {
22816 ProcessRecord app = mLruProcesses.get(i);
22817 if (allChanged || app.procStateChanged) {
22818 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22819 app.procStateChanged = false;
22821 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22822 || app.systemNoUi) && app.pendingUiClean) {
22823 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22824 && app.thread != null) {
22826 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22827 "Trimming memory of ui hidden " + app.processName
22828 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22829 app.thread.scheduleTrimMemory(
22830 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22831 } catch (RemoteException e) {
22834 app.pendingUiClean = false;
22836 app.trimMemoryLevel = 0;
22840 if (mAlwaysFinishActivities) {
22841 // Need to do this on its own message because the stack may not
22842 // be in a consistent state at this point.
22843 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22847 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22850 // Update from any uid changes.
22851 if (mLocalPowerManager != null) {
22852 mLocalPowerManager.startUidChanges();
22854 for (int i=mActiveUids.size()-1; i>=0; i--) {
22855 final UidRecord uidRec = mActiveUids.valueAt(i);
22856 int uidChange = UidRecord.CHANGE_PROCSTATE;
22857 if (uidRec.setProcState != uidRec.curProcState
22858 || uidRec.setWhitelist != uidRec.curWhitelist) {
22859 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22860 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22861 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22862 + " to " + uidRec.curWhitelist);
22863 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22864 && !uidRec.curWhitelist) {
22865 // UID is now in the background (and not on the temp whitelist). Was it
22866 // previously in the foreground (or on the temp whitelist)?
22867 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22868 || uidRec.setWhitelist) {
22869 uidRec.lastBackgroundTime = nowElapsed;
22870 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22871 // Note: the background settle time is in elapsed realtime, while
22872 // the handler time base is uptime. All this means is that we may
22873 // stop background uids later than we had intended, but that only
22874 // happens because the device was sleeping so we are okay anyway.
22875 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22876 mConstants.BACKGROUND_SETTLE_TIME);
22881 uidChange = UidRecord.CHANGE_ACTIVE;
22882 EventLogTags.writeAmUidActive(uidRec.uid);
22883 uidRec.idle = false;
22885 uidRec.lastBackgroundTime = 0;
22887 uidRec.setProcState = uidRec.curProcState;
22888 uidRec.setWhitelist = uidRec.curWhitelist;
22889 enqueueUidChangeLocked(uidRec, -1, uidChange);
22890 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22891 if (uidRec.foregroundServices) {
22892 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22896 if (mLocalPowerManager != null) {
22897 mLocalPowerManager.finishUidChanges();
22900 if (mProcessStats.shouldWriteNowLocked(now)) {
22901 mHandler.post(new Runnable() {
22902 @Override public void run() {
22903 synchronized (ActivityManagerService.this) {
22904 mProcessStats.writeStateAsyncLocked();
22910 if (DEBUG_OOM_ADJ) {
22911 final long duration = SystemClock.uptimeMillis() - now;
22913 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22914 new RuntimeException("here").fillInStackTrace());
22916 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22922 public void makePackageIdle(String packageName, int userId) {
22923 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22924 != PackageManager.PERMISSION_GRANTED) {
22925 String msg = "Permission Denial: makePackageIdle() from pid="
22926 + Binder.getCallingPid()
22927 + ", uid=" + Binder.getCallingUid()
22928 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22930 throw new SecurityException(msg);
22932 final int callingPid = Binder.getCallingPid();
22933 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22934 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22935 long callingId = Binder.clearCallingIdentity();
22936 synchronized(this) {
22938 IPackageManager pm = AppGlobals.getPackageManager();
22941 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22942 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22943 } catch (RemoteException e) {
22945 if (pkgUid == -1) {
22946 throw new IllegalArgumentException("Unknown package name " + packageName);
22949 if (mLocalPowerManager != null) {
22950 mLocalPowerManager.startUidChanges();
22952 final int appId = UserHandle.getAppId(pkgUid);
22953 final int N = mActiveUids.size();
22954 for (int i=N-1; i>=0; i--) {
22955 final UidRecord uidRec = mActiveUids.valueAt(i);
22956 final long bgTime = uidRec.lastBackgroundTime;
22957 if (bgTime > 0 && !uidRec.idle) {
22958 if (UserHandle.getAppId(uidRec.uid) == appId) {
22959 if (userId == UserHandle.USER_ALL ||
22960 userId == UserHandle.getUserId(uidRec.uid)) {
22961 EventLogTags.writeAmUidIdle(uidRec.uid);
22962 uidRec.idle = true;
22963 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22964 + " from package " + packageName + " user " + userId);
22965 doStopUidLocked(uidRec.uid, uidRec);
22971 if (mLocalPowerManager != null) {
22972 mLocalPowerManager.finishUidChanges();
22974 Binder.restoreCallingIdentity(callingId);
22979 final void idleUids() {
22980 synchronized (this) {
22981 final int N = mActiveUids.size();
22985 final long nowElapsed = SystemClock.elapsedRealtime();
22986 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22988 if (mLocalPowerManager != null) {
22989 mLocalPowerManager.startUidChanges();
22991 for (int i=N-1; i>=0; i--) {
22992 final UidRecord uidRec = mActiveUids.valueAt(i);
22993 final long bgTime = uidRec.lastBackgroundTime;
22994 if (bgTime > 0 && !uidRec.idle) {
22995 if (bgTime <= maxBgTime) {
22996 EventLogTags.writeAmUidIdle(uidRec.uid);
22997 uidRec.idle = true;
22998 doStopUidLocked(uidRec.uid, uidRec);
23000 if (nextTime == 0 || nextTime > bgTime) {
23006 if (mLocalPowerManager != null) {
23007 mLocalPowerManager.finishUidChanges();
23009 if (nextTime > 0) {
23010 mHandler.removeMessages(IDLE_UIDS_MSG);
23011 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23012 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23018 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23019 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23020 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23024 void incrementProcStateSeqAndNotifyAppsLocked() {
23025 if (mWaitForNetworkTimeoutMs <= 0) {
23028 // Used for identifying which uids need to block for network.
23029 ArrayList<Integer> blockingUids = null;
23030 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23031 final UidRecord uidRec = mActiveUids.valueAt(i);
23032 // If the network is not restricted for uid, then nothing to do here.
23033 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23036 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23039 // If process state is not changed, then there's nothing to do.
23040 if (uidRec.setProcState == uidRec.curProcState) {
23043 final int blockState = getBlockStateForUid(uidRec);
23044 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23045 // there's nothing the app needs to do in this scenario.
23046 if (blockState == NETWORK_STATE_NO_CHANGE) {
23049 synchronized (uidRec.networkStateLock) {
23050 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23051 if (blockState == NETWORK_STATE_BLOCK) {
23052 if (blockingUids == null) {
23053 blockingUids = new ArrayList<>();
23055 blockingUids.add(uidRec.uid);
23057 if (DEBUG_NETWORK) {
23058 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23059 + " threads for uid: " + uidRec);
23061 if (uidRec.waitingForNetwork) {
23062 uidRec.networkStateLock.notifyAll();
23068 // There are no uids that need to block, so nothing more to do.
23069 if (blockingUids == null) {
23073 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23074 final ProcessRecord app = mLruProcesses.get(i);
23075 if (!blockingUids.contains(app.uid)) {
23078 if (!app.killedByAm && app.thread != null) {
23079 final UidRecord uidRec = mActiveUids.get(app.uid);
23081 if (DEBUG_NETWORK) {
23082 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23085 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23086 } catch (RemoteException ignored) {
23093 * Checks if the uid is coming from background to foreground or vice versa and returns
23094 * appropriate block state based on this.
23096 * @return blockState based on whether the uid is coming from background to foreground or
23097 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23098 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23099 * {@link #NETWORK_STATE_NO_CHANGE}.
23102 int getBlockStateForUid(UidRecord uidRec) {
23103 // Denotes whether uid's process state is currently allowed network access.
23104 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23105 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23106 // Denotes whether uid's process state was previously allowed network access.
23107 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23108 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23110 // When the uid is coming to foreground, AMS should inform the app thread that it should
23111 // block for the network rules to get updated before launching an activity.
23112 if (!wasAllowed && isAllowed) {
23113 return NETWORK_STATE_BLOCK;
23115 // When the uid is going to background, AMS should inform the app thread that if an
23116 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23117 if (wasAllowed && !isAllowed) {
23118 return NETWORK_STATE_UNBLOCK;
23120 return NETWORK_STATE_NO_CHANGE;
23123 final void runInBackgroundDisabled(int uid) {
23124 synchronized (this) {
23125 UidRecord uidRec = mActiveUids.get(uid);
23126 if (uidRec != null) {
23127 // This uid is actually running... should it be considered background now?
23129 doStopUidLocked(uidRec.uid, uidRec);
23132 // This uid isn't actually running... still send a report about it being "stopped".
23133 doStopUidLocked(uid, null);
23138 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23139 mServices.stopInBackgroundLocked(uid);
23140 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23144 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23146 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23147 long duration, String tag) {
23148 if (DEBUG_WHITELISTS) {
23149 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23150 + targetUid + ", " + duration + ")");
23153 synchronized (mPidsSelfLocked) {
23154 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23156 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23160 if (!pr.whitelistManager) {
23161 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23162 != PackageManager.PERMISSION_GRANTED) {
23163 if (DEBUG_WHITELISTS) {
23164 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23165 + ": pid " + callerPid + " is not allowed");
23172 tempWhitelistUidLocked(targetUid, duration, tag);
23176 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23178 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23179 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23180 setUidTempWhitelistStateLocked(targetUid, true);
23181 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23184 void pushTempWhitelist() {
23186 final PendingTempWhitelist[] list;
23188 // First copy out the pending changes... we need to leave them in the map for now,
23189 // in case someone needs to check what is coming up while we don't have the lock held.
23190 synchronized(this) {
23191 N = mPendingTempWhitelist.size();
23192 list = new PendingTempWhitelist[N];
23193 for (int i = 0; i < N; i++) {
23194 list[i] = mPendingTempWhitelist.valueAt(i);
23198 // Now safely dispatch changes to device idle controller.
23199 for (int i = 0; i < N; i++) {
23200 PendingTempWhitelist ptw = list[i];
23201 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23202 ptw.duration, true, ptw.tag);
23205 // And now we can safely remove them from the map.
23206 synchronized(this) {
23207 for (int i = 0; i < N; i++) {
23208 PendingTempWhitelist ptw = list[i];
23209 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23210 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23211 mPendingTempWhitelist.removeAt(index);
23217 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23218 boolean changed = false;
23219 for (int i=mActiveUids.size()-1; i>=0; i--) {
23220 final UidRecord uidRec = mActiveUids.valueAt(i);
23221 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23222 uidRec.curWhitelist = onWhitelist;
23227 updateOomAdjLocked();
23231 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23232 boolean changed = false;
23233 final UidRecord uidRec = mActiveUids.get(uid);
23234 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23235 uidRec.curWhitelist = onWhitelist;
23236 updateOomAdjLocked();
23240 final void trimApplications() {
23241 synchronized (this) {
23244 // First remove any unused application processes whose package
23245 // has been removed.
23246 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23247 final ProcessRecord app = mRemovedProcesses.get(i);
23248 if (app.activities.size() == 0
23249 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23251 TAG, "Exiting empty application process "
23252 + app.toShortString() + " ("
23253 + (app.thread != null ? app.thread.asBinder() : null)
23255 if (app.pid > 0 && app.pid != MY_PID) {
23256 app.kill("empty", false);
23259 app.thread.scheduleExit();
23260 } catch (Exception e) {
23261 // Ignore exceptions.
23264 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23265 mRemovedProcesses.remove(i);
23267 if (app.persistent) {
23268 addAppLocked(app.info, null, false, null /* ABI override */);
23273 // Now update the oom adj for all processes.
23274 updateOomAdjLocked();
23278 /** This method sends the specified signal to each of the persistent apps */
23279 public void signalPersistentProcesses(int sig) throws RemoteException {
23280 if (sig != SIGNAL_USR1) {
23281 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23284 synchronized (this) {
23285 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23286 != PackageManager.PERMISSION_GRANTED) {
23287 throw new SecurityException("Requires permission "
23288 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23291 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23292 ProcessRecord r = mLruProcesses.get(i);
23293 if (r.thread != null && r.persistent) {
23294 sendSignal(r.pid, sig);
23300 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23301 if (proc == null || proc == mProfileProc) {
23302 proc = mProfileProc;
23303 profileType = mProfileType;
23304 clearProfilerLocked();
23306 if (proc == null) {
23310 proc.thread.profilerControl(false, null, profileType);
23311 } catch (RemoteException e) {
23312 throw new IllegalStateException("Process disappeared");
23316 private void clearProfilerLocked() {
23317 if (mProfileFd != null) {
23319 mProfileFd.close();
23320 } catch (IOException e) {
23323 mProfileApp = null;
23324 mProfileProc = null;
23325 mProfileFile = null;
23327 mAutoStopProfiler = false;
23328 mStreamingOutput = false;
23329 mSamplingInterval = 0;
23332 public boolean profileControl(String process, int userId, boolean start,
23333 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23336 synchronized (this) {
23337 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23338 // its own permission.
23339 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23340 != PackageManager.PERMISSION_GRANTED) {
23341 throw new SecurityException("Requires permission "
23342 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23345 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23346 throw new IllegalArgumentException("null profile info or fd");
23349 ProcessRecord proc = null;
23350 if (process != null) {
23351 proc = findProcessLocked(process, userId, "profileControl");
23354 if (start && (proc == null || proc.thread == null)) {
23355 throw new IllegalArgumentException("Unknown process: " + process);
23359 stopProfilerLocked(null, 0);
23360 setProfileApp(proc.info, proc.processName, profilerInfo);
23361 mProfileProc = proc;
23362 mProfileType = profileType;
23363 ParcelFileDescriptor fd = profilerInfo.profileFd;
23366 } catch (IOException e) {
23369 profilerInfo.profileFd = fd;
23370 proc.thread.profilerControl(start, profilerInfo, profileType);
23373 mProfileFd.close();
23374 } catch (IOException e) {
23378 stopProfilerLocked(proc, profileType);
23379 if (profilerInfo != null && profilerInfo.profileFd != null) {
23381 profilerInfo.profileFd.close();
23382 } catch (IOException e) {
23389 } catch (RemoteException e) {
23390 throw new IllegalStateException("Process disappeared");
23392 if (profilerInfo != null && profilerInfo.profileFd != null) {
23394 profilerInfo.profileFd.close();
23395 } catch (IOException e) {
23401 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23402 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23403 userId, true, ALLOW_FULL_ONLY, callName, null);
23404 ProcessRecord proc = null;
23406 int pid = Integer.parseInt(process);
23407 synchronized (mPidsSelfLocked) {
23408 proc = mPidsSelfLocked.get(pid);
23410 } catch (NumberFormatException e) {
23413 if (proc == null) {
23414 ArrayMap<String, SparseArray<ProcessRecord>> all
23415 = mProcessNames.getMap();
23416 SparseArray<ProcessRecord> procs = all.get(process);
23417 if (procs != null && procs.size() > 0) {
23418 proc = procs.valueAt(0);
23419 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23420 for (int i=1; i<procs.size(); i++) {
23421 ProcessRecord thisProc = procs.valueAt(i);
23422 if (thisProc.userId == userId) {
23434 public boolean dumpHeap(String process, int userId, boolean managed,
23435 String path, ParcelFileDescriptor fd) throws RemoteException {
23438 synchronized (this) {
23439 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23440 // its own permission (same as profileControl).
23441 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23442 != PackageManager.PERMISSION_GRANTED) {
23443 throw new SecurityException("Requires permission "
23444 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23448 throw new IllegalArgumentException("null fd");
23451 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23452 if (proc == null || proc.thread == null) {
23453 throw new IllegalArgumentException("Unknown process: " + process);
23456 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23457 if (!isDebuggable) {
23458 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23459 throw new SecurityException("Process not debuggable: " + proc);
23463 proc.thread.dumpHeap(managed, path, fd);
23467 } catch (RemoteException e) {
23468 throw new IllegalStateException("Process disappeared");
23473 } catch (IOException e) {
23480 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23481 String reportPackage) {
23482 if (processName != null) {
23483 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23484 "setDumpHeapDebugLimit()");
23486 synchronized (mPidsSelfLocked) {
23487 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23488 if (proc == null) {
23489 throw new SecurityException("No process found for calling pid "
23490 + Binder.getCallingPid());
23492 if (!Build.IS_DEBUGGABLE
23493 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23494 throw new SecurityException("Not running a debuggable build");
23496 processName = proc.processName;
23498 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23499 throw new SecurityException("Package " + reportPackage + " is not running in "
23504 synchronized (this) {
23505 if (maxMemSize > 0) {
23506 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23509 mMemWatchProcesses.remove(processName, uid);
23511 mMemWatchProcesses.getMap().remove(processName);
23518 public void dumpHeapFinished(String path) {
23519 synchronized (this) {
23520 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23521 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23522 + " does not match last pid " + mMemWatchDumpPid);
23525 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23526 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23527 + " does not match last path " + mMemWatchDumpFile);
23530 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23531 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23535 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23536 public void monitor() {
23537 synchronized (this) { }
23540 void onCoreSettingsChange(Bundle settings) {
23541 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23542 ProcessRecord processRecord = mLruProcesses.get(i);
23544 if (processRecord.thread != null) {
23545 processRecord.thread.setCoreSettings(settings);
23547 } catch (RemoteException re) {
23553 // Multi-user methods
23556 * Start user, if its not already running, but don't bring it to foreground.
23559 public boolean startUserInBackground(final int userId) {
23560 return mUserController.startUser(userId, /* foreground */ false);
23564 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23565 return mUserController.unlockUser(userId, token, secret, listener);
23569 public boolean switchUser(final int targetUserId) {
23570 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23572 UserInfo targetUserInfo;
23573 synchronized (this) {
23574 currentUserId = mUserController.getCurrentUserIdLocked();
23575 targetUserInfo = mUserController.getUserInfo(targetUserId);
23576 if (targetUserId == currentUserId) {
23577 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23580 if (targetUserInfo == null) {
23581 Slog.w(TAG, "No user info for user #" + targetUserId);
23584 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23585 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23586 + " when device is in demo mode");
23589 if (!targetUserInfo.supportsSwitchTo()) {
23590 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23593 if (targetUserInfo.isManagedProfile()) {
23594 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23597 mUserController.setTargetUserIdLocked(targetUserId);
23599 if (mUserController.mUserSwitchUiEnabled) {
23600 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23601 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23602 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23603 mUiHandler.sendMessage(mHandler.obtainMessage(
23604 START_USER_SWITCH_UI_MSG, userNames));
23606 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23607 mHandler.sendMessage(mHandler.obtainMessage(
23608 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23613 void scheduleStartProfilesLocked() {
23614 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23615 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23616 DateUtils.SECOND_IN_MILLIS);
23621 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23622 return mUserController.stopUser(userId, force, callback);
23626 public UserInfo getCurrentUser() {
23627 return mUserController.getCurrentUser();
23630 String getStartedUserState(int userId) {
23631 synchronized (this) {
23632 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23633 return UserState.stateToString(userState.state);
23638 public boolean isUserRunning(int userId, int flags) {
23639 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23640 && checkCallingPermission(INTERACT_ACROSS_USERS)
23641 != PackageManager.PERMISSION_GRANTED) {
23642 String msg = "Permission Denial: isUserRunning() from pid="
23643 + Binder.getCallingPid()
23644 + ", uid=" + Binder.getCallingUid()
23645 + " requires " + INTERACT_ACROSS_USERS;
23647 throw new SecurityException(msg);
23649 synchronized (this) {
23650 return mUserController.isUserRunningLocked(userId, flags);
23655 public int[] getRunningUserIds() {
23656 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23657 != PackageManager.PERMISSION_GRANTED) {
23658 String msg = "Permission Denial: isUserRunning() from pid="
23659 + Binder.getCallingPid()
23660 + ", uid=" + Binder.getCallingUid()
23661 + " requires " + INTERACT_ACROSS_USERS;
23663 throw new SecurityException(msg);
23665 synchronized (this) {
23666 return mUserController.getStartedUserArrayLocked();
23671 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23672 mUserController.registerUserSwitchObserver(observer, name);
23676 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23677 mUserController.unregisterUserSwitchObserver(observer);
23680 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23681 if (info == null) return null;
23682 ApplicationInfo newInfo = new ApplicationInfo(info);
23683 newInfo.initForUser(userId);
23687 public boolean isUserStopped(int userId) {
23688 synchronized (this) {
23689 return mUserController.getStartedUserStateLocked(userId) == null;
23693 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23695 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23699 ActivityInfo info = new ActivityInfo(aInfo);
23700 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23704 private boolean processSanityChecksLocked(ProcessRecord process) {
23705 if (process == null || process.thread == null) {
23709 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23710 if (!isDebuggable) {
23711 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23719 public boolean startBinderTracking() throws RemoteException {
23720 synchronized (this) {
23721 mBinderTransactionTrackingEnabled = true;
23722 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23723 // permission (same as profileControl).
23724 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23725 != PackageManager.PERMISSION_GRANTED) {
23726 throw new SecurityException("Requires permission "
23727 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23730 for (int i = 0; i < mLruProcesses.size(); i++) {
23731 ProcessRecord process = mLruProcesses.get(i);
23732 if (!processSanityChecksLocked(process)) {
23736 process.thread.startBinderTracking();
23737 } catch (RemoteException e) {
23738 Log.v(TAG, "Process disappared");
23745 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23747 synchronized (this) {
23748 mBinderTransactionTrackingEnabled = false;
23749 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23750 // permission (same as profileControl).
23751 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23752 != PackageManager.PERMISSION_GRANTED) {
23753 throw new SecurityException("Requires permission "
23754 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23758 throw new IllegalArgumentException("null fd");
23761 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23762 pw.println("Binder transaction traces for all processes.\n");
23763 for (ProcessRecord process : mLruProcesses) {
23764 if (!processSanityChecksLocked(process)) {
23768 pw.println("Traces for process: " + process.processName);
23771 TransferPipe tp = new TransferPipe();
23773 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23774 tp.go(fd.getFileDescriptor());
23778 } catch (IOException e) {
23779 pw.println("Failure while dumping IPC traces from " + process +
23780 ". Exception: " + e);
23782 } catch (RemoteException e) {
23783 pw.println("Got a RemoteException while dumping IPC traces from " +
23784 process + ". Exception: " + e);
23795 } catch (IOException e) {
23802 final class LocalService extends ActivityManagerInternal {
23804 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23805 int targetUserId) {
23806 synchronized (ActivityManagerService.this) {
23807 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23808 targetPkg, intent, null, targetUserId);
23813 public String checkContentProviderAccess(String authority, int userId) {
23814 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23818 public void onWakefulnessChanged(int wakefulness) {
23819 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23823 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23824 String processName, String abiOverride, int uid, Runnable crashHandler) {
23825 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23826 processName, abiOverride, uid, crashHandler);
23830 public SleepToken acquireSleepToken(String tag) {
23831 Preconditions.checkNotNull(tag);
23833 synchronized (ActivityManagerService.this) {
23834 SleepTokenImpl token = new SleepTokenImpl(tag);
23835 mSleepTokens.add(token);
23836 updateSleepIfNeededLocked();
23842 public ComponentName getHomeActivityForUser(int userId) {
23843 synchronized (ActivityManagerService.this) {
23844 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23845 return homeActivity == null ? null : homeActivity.realActivity;
23850 public void onUserRemoved(int userId) {
23851 synchronized (ActivityManagerService.this) {
23852 ActivityManagerService.this.onUserStoppedLocked(userId);
23857 public void onLocalVoiceInteractionStarted(IBinder activity,
23858 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23859 synchronized (ActivityManagerService.this) {
23860 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23861 voiceSession, voiceInteractor);
23866 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23867 synchronized (ActivityManagerService.this) {
23868 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23869 reasons, timestamp);
23874 public void notifyAppTransitionFinished() {
23875 synchronized (ActivityManagerService.this) {
23876 mStackSupervisor.notifyAppTransitionDone();
23881 public void notifyAppTransitionCancelled() {
23882 synchronized (ActivityManagerService.this) {
23883 mStackSupervisor.notifyAppTransitionDone();
23888 public List<IBinder> getTopVisibleActivities() {
23889 synchronized (ActivityManagerService.this) {
23890 return mStackSupervisor.getTopVisibleActivities();
23895 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23896 synchronized (ActivityManagerService.this) {
23897 mStackSupervisor.setDockedStackMinimized(minimized);
23902 public void killForegroundAppsForUser(int userHandle) {
23903 synchronized (ActivityManagerService.this) {
23904 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23905 final int NP = mProcessNames.getMap().size();
23906 for (int ip = 0; ip < NP; ip++) {
23907 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23908 final int NA = apps.size();
23909 for (int ia = 0; ia < NA; ia++) {
23910 final ProcessRecord app = apps.valueAt(ia);
23911 if (app.persistent) {
23912 // We don't kill persistent processes.
23917 } else if (app.userId == userHandle && app.foregroundActivities) {
23918 app.removed = true;
23924 final int N = procs.size();
23925 for (int i = 0; i < N; i++) {
23926 removeProcessLocked(procs.get(i), false, true, "kill all fg");
23932 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23934 if (!(target instanceof PendingIntentRecord)) {
23935 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23938 synchronized (ActivityManagerService.this) {
23939 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23944 public void setDeviceIdleWhitelist(int[] appids) {
23945 synchronized (ActivityManagerService.this) {
23946 mDeviceIdleWhitelist = appids;
23951 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23952 synchronized (ActivityManagerService.this) {
23953 mDeviceIdleTempWhitelist = appids;
23954 setAppIdTempWhitelistStateLocked(changingAppId, adding);
23959 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23961 Preconditions.checkNotNull(values, "Configuration must not be null");
23962 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23963 synchronized (ActivityManagerService.this) {
23964 updateConfigurationLocked(values, null, false, true, userId,
23965 false /* deferResume */);
23970 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23972 Preconditions.checkNotNull(intents, "intents");
23973 final String[] resolvedTypes = new String[intents.length];
23974 for (int i = 0; i < intents.length; i++) {
23975 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23978 // UID of the package on user userId.
23979 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23980 // packageUid may not be initialized.
23981 int packageUid = 0;
23983 packageUid = AppGlobals.getPackageManager().getPackageUid(
23984 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23985 } catch (RemoteException e) {
23986 // Shouldn't happen.
23989 synchronized (ActivityManagerService.this) {
23990 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23991 /*resultTo*/ null, bOptions, userId);
23996 public int getUidProcessState(int uid) {
23997 return getUidState(uid);
24001 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24002 synchronized (ActivityManagerService.this) {
24004 // We might change the visibilities here, so prepare an empty app transition which
24005 // might be overridden later if we actually change visibilities.
24006 final boolean wasTransitionSet =
24007 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24008 if (!wasTransitionSet) {
24009 mWindowManager.prepareAppTransition(TRANSIT_NONE,
24010 false /* alwaysKeepCurrent */);
24012 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24014 // If there was a transition set already we don't want to interfere with it as we
24015 // might be starting it too early.
24016 if (!wasTransitionSet) {
24017 mWindowManager.executeAppTransition();
24020 if (callback != null) {
24026 public boolean isSystemReady() {
24027 // no need to synchronize(this) just to read & return the value
24028 return mSystemReady;
24032 public void notifyKeyguardTrustedChanged() {
24033 synchronized (ActivityManagerService.this) {
24034 if (mKeyguardController.isKeyguardShowing()) {
24035 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24041 * Sets if the given pid has an overlay UI or not.
24043 * @param pid The pid we are setting overlay UI for.
24044 * @param hasOverlayUi True if the process has overlay UI.
24045 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24048 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24049 synchronized (ActivityManagerService.this) {
24050 final ProcessRecord pr;
24051 synchronized (mPidsSelfLocked) {
24052 pr = mPidsSelfLocked.get(pid);
24054 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24058 if (pr.hasOverlayUi == hasOverlayUi) {
24061 pr.hasOverlayUi = hasOverlayUi;
24062 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24063 updateOomAdjLocked(pr, true);
24068 * Called after the network policy rules are updated by
24069 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24070 * and {@param procStateSeq}.
24073 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24074 if (DEBUG_NETWORK) {
24075 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24076 + uid + " seq: " + procStateSeq);
24079 synchronized (ActivityManagerService.this) {
24080 record = mActiveUids.get(uid);
24081 if (record == null) {
24082 if (DEBUG_NETWORK) {
24083 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24084 + " procStateSeq: " + procStateSeq);
24089 synchronized (record.networkStateLock) {
24090 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24091 if (DEBUG_NETWORK) {
24092 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24093 + " been handled for uid: " + uid);
24097 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24098 if (record.curProcStateSeq > procStateSeq) {
24099 if (DEBUG_NETWORK) {
24100 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24101 + ", curProcstateSeq: " + record.curProcStateSeq
24102 + ", procStateSeq: " + procStateSeq);
24106 if (record.waitingForNetwork) {
24107 if (DEBUG_NETWORK) {
24108 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24109 + ", procStateSeq: " + procStateSeq);
24111 record.networkStateLock.notifyAll();
24117 * Called after virtual display Id is updated by
24118 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24119 * {@param vrVr2dDisplayId}.
24122 public void setVr2dDisplayId(int vr2dDisplayId) {
24124 Slog.d(TAG, "setVr2dDisplayId called for: " +
24127 synchronized (ActivityManagerService.this) {
24128 mVr2dDisplayId = vr2dDisplayId;
24133 public void saveANRState(String reason) {
24134 synchronized (ActivityManagerService.this) {
24135 final StringWriter sw = new StringWriter();
24136 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24137 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24138 if (reason != null) {
24139 pw.println(" Reason: " + reason);
24142 mActivityStarter.dump(pw, " ");
24144 pw.println("-------------------------------------------------------------------------------");
24145 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24146 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24151 mLastANRState = sw.toString();
24156 public void clearSavedANRState() {
24157 synchronized (ActivityManagerService.this) {
24158 mLastANRState = null;
24163 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24164 if (packageName == null) return false;
24166 synchronized (ActivityManagerService.this) {
24167 for (int i = 0; i < mLruProcesses.size(); i++) {
24168 final ProcessRecord processRecord = mLruProcesses.get(i);
24169 if (processRecord.uid == uid) {
24170 for (int j = 0; j < processRecord.activities.size(); j++) {
24171 final ActivityRecord activityRecord = processRecord.activities.get(j);
24172 if (packageName.equals(activityRecord.packageName)) {
24184 * Called by app main thread to wait for the network policy rules to get updated.
24186 * @param procStateSeq The sequence number indicating the process state change that the main
24187 * thread is interested in.
24190 public void waitForNetworkStateUpdate(long procStateSeq) {
24191 final int callingUid = Binder.getCallingUid();
24192 if (DEBUG_NETWORK) {
24193 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24196 synchronized (this) {
24197 record = mActiveUids.get(callingUid);
24198 if (record == null) {
24202 synchronized (record.networkStateLock) {
24203 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24204 if (DEBUG_NETWORK) {
24205 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24206 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24207 + " lastProcStateSeqDispatchedToObservers: "
24208 + record.lastDispatchedProcStateSeq);
24212 if (record.curProcStateSeq > procStateSeq) {
24213 if (DEBUG_NETWORK) {
24214 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24215 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24216 + ", procStateSeq: " + procStateSeq);
24220 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24221 if (DEBUG_NETWORK) {
24222 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24223 + procStateSeq + ", so no need to wait. Uid: "
24224 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24225 + record.lastNetworkUpdatedProcStateSeq);
24230 if (DEBUG_NETWORK) {
24231 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24232 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24234 final long startTime = SystemClock.uptimeMillis();
24235 record.waitingForNetwork = true;
24236 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24237 record.waitingForNetwork = false;
24238 final long totalTime = SystemClock.uptimeMillis() - startTime;
24239 if (totalTime >= mWaitForNetworkTimeoutMs) {
24240 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24241 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24242 + procStateSeq + " UidRec: " + record
24243 + " validateUidRec: " + mValidateUids.get(callingUid));
24245 } catch (InterruptedException e) {
24246 Thread.currentThread().interrupt();
24251 public void waitForBroadcastIdle(PrintWriter pw) {
24252 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24254 boolean idle = true;
24255 synchronized (this) {
24256 for (BroadcastQueue queue : mBroadcastQueues) {
24257 if (!queue.isIdle()) {
24258 final String msg = "Waiting for queue " + queue + " to become idle...";
24268 final String msg = "All broadcast queues are idle!";
24274 SystemClock.sleep(1000);
24280 * Return the user id of the last resumed activity.
24283 public @UserIdInt int getLastResumedActivityUserId() {
24284 enforceCallingPermission(
24285 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24286 synchronized (this) {
24287 if (mLastResumedActivity == null) {
24288 return mUserController.getCurrentUserIdLocked();
24290 return mLastResumedActivity.userId;
24294 private final class SleepTokenImpl extends SleepToken {
24295 private final String mTag;
24296 private final long mAcquireTime;
24298 public SleepTokenImpl(String tag) {
24300 mAcquireTime = SystemClock.uptimeMillis();
24304 public void release() {
24305 synchronized (ActivityManagerService.this) {
24306 if (mSleepTokens.remove(this)) {
24307 updateSleepIfNeededLocked();
24313 public String toString() {
24314 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
24319 * An implementation of IAppTask, that allows an app to manage its own tasks via
24320 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24321 * only the process that calls getAppTasks() can call the AppTask methods.
24323 class AppTaskImpl extends IAppTask.Stub {
24324 private int mTaskId;
24325 private int mCallingUid;
24327 public AppTaskImpl(int taskId, int callingUid) {
24329 mCallingUid = callingUid;
24332 private void checkCaller() {
24333 if (mCallingUid != Binder.getCallingUid()) {
24334 throw new SecurityException("Caller " + mCallingUid
24335 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24340 public void finishAndRemoveTask() {
24343 synchronized (ActivityManagerService.this) {
24344 long origId = Binder.clearCallingIdentity();
24346 // We remove the task from recents to preserve backwards
24347 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24348 REMOVE_FROM_RECENTS)) {
24349 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24352 Binder.restoreCallingIdentity(origId);
24358 public ActivityManager.RecentTaskInfo getTaskInfo() {
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 return createRecentTaskInfoFromTaskRecord(tr);
24370 Binder.restoreCallingIdentity(origId);
24376 public void moveToFront() {
24378 // Will bring task to front if it already has a root activity.
24379 final long origId = Binder.clearCallingIdentity();
24381 synchronized (this) {
24382 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24385 Binder.restoreCallingIdentity(origId);
24390 public int startActivity(IBinder whoThread, String callingPackage,
24391 Intent intent, String resolvedType, Bundle bOptions) {
24394 int callingUser = UserHandle.getCallingUserId();
24396 IApplicationThread appThread;
24397 synchronized (ActivityManagerService.this) {
24398 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24400 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24402 appThread = IApplicationThread.Stub.asInterface(whoThread);
24403 if (appThread == null) {
24404 throw new IllegalArgumentException("Bad app thread " + appThread);
24407 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24408 resolvedType, null, null, null, null, 0, 0, null, null,
24409 null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
24413 public void setExcludeFromRecents(boolean exclude) {
24416 synchronized (ActivityManagerService.this) {
24417 long origId = Binder.clearCallingIdentity();
24419 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24421 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24423 Intent intent = tr.getBaseIntent();
24425 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24427 intent.setFlags(intent.getFlags()
24428 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24431 Binder.restoreCallingIdentity(origId);
24438 * Kill processes for the user with id userId and that depend on the package named packageName
24441 public void killPackageDependents(String packageName, int userId) {
24442 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24443 if (packageName == null) {
24444 throw new NullPointerException(
24445 "Cannot kill the dependents of a package without its name.");
24448 long callingId = Binder.clearCallingIdentity();
24449 IPackageManager pm = AppGlobals.getPackageManager();
24452 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24453 } catch (RemoteException e) {
24455 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24456 throw new IllegalArgumentException(
24457 "Cannot kill dependents of non-existing package " + packageName);
24460 synchronized(this) {
24461 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24462 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24463 "dep: " + packageName);
24466 Binder.restoreCallingIdentity(callingId);
24471 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24472 throws RemoteException {
24473 final long callingId = Binder.clearCallingIdentity();
24475 mKeyguardController.dismissKeyguard(token, callback);
24477 Binder.restoreCallingIdentity(callingId);
24482 public int restartUserInBackground(final int userId) {
24483 return mUserController.restartUser(userId, /* foreground */ false);
24487 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24488 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24489 "scheduleApplicationInfoChanged()");
24491 synchronized (this) {
24492 final long origId = Binder.clearCallingIdentity();
24494 updateApplicationInfoLocked(packageNames, userId);
24496 Binder.restoreCallingIdentity(origId);
24501 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24502 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24503 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24504 final ProcessRecord app = mLruProcesses.get(i);
24505 if (app.thread == null) {
24509 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24513 final int packageCount = app.pkgList.size();
24514 for (int j = 0; j < packageCount; j++) {
24515 final String packageName = app.pkgList.keyAt(j);
24516 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24518 final ApplicationInfo ai = AppGlobals.getPackageManager()
24519 .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24521 app.thread.scheduleApplicationInfoChanged(ai);
24523 } catch (RemoteException e) {
24524 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24525 packageName, app));
24533 * Attach an agent to the specified process (proces name or PID)
24535 public void attachAgent(String process, String path) {
24537 synchronized (this) {
24538 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24539 if (proc == null || proc.thread == null) {
24540 throw new IllegalArgumentException("Unknown process: " + process);
24543 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24544 if (!isDebuggable) {
24545 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24546 throw new SecurityException("Process not debuggable: " + proc);
24550 proc.thread.attachAgent(path);
24552 } catch (RemoteException e) {
24553 throw new IllegalStateException("Process disappeared");
24558 public static class Injector {
24559 private NetworkManagementInternal mNmi;
24561 public Context getContext() {
24565 public AppOpsService getAppOpsService(File file, Handler handler) {
24566 return new AppOpsService(file, handler);
24569 public Handler getUiHandler(ActivityManagerService service) {
24570 return service.new UiHandler();
24573 public boolean isNetworkRestrictedForUid(int uid) {
24574 if (ensureHasNetworkManagementInternal()) {
24575 return mNmi.isNetworkRestrictedForUid(uid);
24580 private boolean ensureHasNetworkManagementInternal() {
24581 if (mNmi == null) {
24582 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24584 return mNmi != null;