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.FIRST_DYNAMIC_STACK_ID;
32 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
35 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
36 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
37 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
38 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
39 import static android.content.pm.PackageManager.GET_PROVIDERS;
40 import static android.content.pm.PackageManager.MATCH_ANY_USER;
41 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
43 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
44 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
45 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
46 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
47 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
49 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
50 import static android.os.Build.VERSION_CODES.N;
51 import static android.os.Process.BLUETOOTH_UID;
52 import static android.os.Process.FIRST_APPLICATION_UID;
53 import static android.os.Process.FIRST_ISOLATED_UID;
54 import static android.os.Process.LAST_ISOLATED_UID;
55 import static android.os.Process.NFC_UID;
56 import static android.os.Process.PHONE_UID;
57 import static android.os.Process.PROC_CHAR;
58 import static android.os.Process.PROC_OUT_LONG;
59 import static android.os.Process.PROC_PARENS;
60 import static android.os.Process.PROC_SPACE_TERM;
61 import static android.os.Process.ProcessStartResult;
62 import static android.os.Process.ROOT_UID;
63 import static android.os.Process.SCHED_FIFO;
64 import static android.os.Process.SCHED_OTHER;
65 import static android.os.Process.SCHED_RESET_ON_FORK;
66 import static android.os.Process.SHELL_UID;
67 import static android.os.Process.SIGNAL_QUIT;
68 import static android.os.Process.SIGNAL_USR1;
69 import static android.os.Process.SYSTEM_UID;
70 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
71 import static android.os.Process.THREAD_GROUP_DEFAULT;
72 import static android.os.Process.THREAD_GROUP_TOP_APP;
73 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
74 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
75 import static android.os.Process.getFreeMemory;
76 import static android.os.Process.getTotalMemory;
77 import static android.os.Process.isThreadInProcess;
78 import static android.os.Process.killProcess;
79 import static android.os.Process.killProcessQuiet;
80 import static android.os.Process.myPid;
81 import static android.os.Process.myUid;
82 import static android.os.Process.readProcFile;
83 import static android.os.Process.removeAllProcessGroups;
84 import static android.os.Process.sendSignal;
85 import static android.os.Process.setProcessGroup;
86 import static android.os.Process.setThreadPriority;
87 import static android.os.Process.setThreadScheduler;
88 import static android.os.Process.startWebView;
89 import static android.os.Process.zygoteProcess;
90 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
91 import static android.provider.Settings.Global.DEBUG_APP;
92 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
94 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
95 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
96 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
97 import static android.provider.Settings.System.FONT_SCALE;
98 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
99 import static android.text.format.DateUtils.DAY_IN_MILLIS;
100 import static android.view.Display.DEFAULT_DISPLAY;
101 import static android.view.Display.INVALID_DISPLAY;
102 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
103 import static com.android.internal.util.XmlUtils.readIntAttribute;
104 import static com.android.internal.util.XmlUtils.readLongAttribute;
105 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
106 import static com.android.internal.util.XmlUtils.writeIntAttribute;
107 import static com.android.internal.util.XmlUtils.writeLongAttribute;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
165 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
167 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
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.IActivityController;
215 import android.app.IActivityManager;
216 import android.app.IAppTask;
217 import android.app.IApplicationThread;
218 import android.app.IInstrumentationWatcher;
219 import android.app.INotificationManager;
220 import android.app.IProcessObserver;
221 import android.app.IServiceConnection;
222 import android.app.IStopUserCallback;
223 import android.app.ITaskStackListener;
224 import android.app.IUiAutomationConnection;
225 import android.app.IUidObserver;
226 import android.app.IUserSwitchObserver;
227 import android.app.Instrumentation;
228 import android.app.Notification;
229 import android.app.NotificationManager;
230 import android.app.PendingIntent;
231 import android.app.PictureInPictureParams;
232 import android.app.ProfilerInfo;
233 import android.app.RemoteAction;
234 import android.app.WaitResult;
235 import android.app.admin.DevicePolicyManager;
236 import android.app.assist.AssistContent;
237 import android.app.assist.AssistStructure;
238 import android.app.backup.IBackupManager;
239 import android.app.usage.UsageEvents;
240 import android.app.usage.UsageStatsManagerInternal;
241 import android.appwidget.AppWidgetManager;
242 import android.content.ActivityNotFoundException;
243 import android.content.BroadcastReceiver;
244 import android.content.ClipData;
245 import android.content.ComponentCallbacks2;
246 import android.content.ComponentName;
247 import android.content.ContentProvider;
248 import android.content.ContentResolver;
249 import android.content.Context;
250 import android.content.DialogInterface;
251 import android.content.IContentProvider;
252 import android.content.IIntentReceiver;
253 import android.content.IIntentSender;
254 import android.content.Intent;
255 import android.content.IntentFilter;
256 import android.content.pm.ActivityInfo;
257 import android.content.pm.ApplicationInfo;
258 import android.content.pm.ConfigurationInfo;
259 import android.content.pm.IPackageDataObserver;
260 import android.content.pm.IPackageManager;
261 import android.content.pm.InstrumentationInfo;
262 import android.content.pm.PackageInfo;
263 import android.content.pm.PackageManager;
264 import android.content.pm.PackageManager.NameNotFoundException;
265 import android.content.pm.PackageManagerInternal;
266 import android.content.pm.ParceledListSlice;
267 import android.content.pm.PathPermission;
268 import android.content.pm.PermissionInfo;
269 import android.content.pm.ProviderInfo;
270 import android.content.pm.ResolveInfo;
271 import android.content.pm.SELinuxUtil;
272 import android.content.pm.ServiceInfo;
273 import android.content.pm.UserInfo;
274 import android.content.res.CompatibilityInfo;
275 import android.content.res.Configuration;
276 import android.content.res.Resources;
277 import android.database.ContentObserver;
278 import android.graphics.Bitmap;
279 import android.graphics.Point;
280 import android.graphics.Rect;
281 import android.location.LocationManager;
282 import android.media.audiofx.AudioEffect;
283 import android.metrics.LogMaker;
284 import android.net.Proxy;
285 import android.net.ProxyInfo;
286 import android.net.Uri;
287 import android.os.BatteryStats;
288 import android.os.Binder;
289 import android.os.Build;
290 import android.os.Bundle;
291 import android.os.Debug;
292 import android.os.DropBoxManager;
293 import android.os.Environment;
294 import android.os.FactoryTest;
295 import android.os.FileObserver;
296 import android.os.FileUtils;
297 import android.os.Handler;
298 import android.os.IBinder;
299 import android.os.IDeviceIdentifiersPolicyService;
300 import android.os.IPermissionController;
301 import android.os.IProcessInfoService;
302 import android.os.IProgressListener;
303 import android.os.LocaleList;
304 import android.os.Looper;
305 import android.os.Message;
306 import android.os.Parcel;
307 import android.os.ParcelFileDescriptor;
308 import android.os.PersistableBundle;
309 import android.os.PowerManager;
310 import android.os.PowerManagerInternal;
311 import android.os.Process;
312 import android.os.RemoteCallbackList;
313 import android.os.RemoteException;
314 import android.os.ResultReceiver;
315 import android.os.ServiceManager;
316 import android.os.ShellCallback;
317 import android.os.StrictMode;
318 import android.os.SystemClock;
319 import android.os.SystemProperties;
320 import android.os.Trace;
321 import android.os.TransactionTooLargeException;
322 import android.os.UpdateLock;
323 import android.os.UserHandle;
324 import android.os.UserManager;
325 import android.os.WorkSource;
326 import android.os.storage.IStorageManager;
327 import android.os.storage.StorageManager;
328 import android.os.storage.StorageManagerInternal;
329 import android.provider.Downloads;
330 import android.provider.Settings;
331 import android.service.voice.IVoiceInteractionSession;
332 import android.service.voice.VoiceInteractionManagerInternal;
333 import android.service.voice.VoiceInteractionSession;
334 import android.telecom.TelecomManager;
335 import android.text.TextUtils;
336 import android.text.format.DateUtils;
337 import android.text.format.Time;
338 import android.text.style.SuggestionSpan;
339 import android.util.ArrayMap;
340 import android.util.ArraySet;
341 import android.util.AtomicFile;
342 import android.util.TimingsTraceLog;
343 import android.util.DebugUtils;
344 import android.util.DisplayMetrics;
345 import android.util.EventLog;
346 import android.util.Log;
347 import android.util.Pair;
348 import android.util.PrintWriterPrinter;
349 import android.util.Slog;
350 import android.util.SparseArray;
351 import android.util.SparseIntArray;
352 import android.util.TimeUtils;
353 import android.util.Xml;
354 import android.view.Gravity;
355 import android.view.LayoutInflater;
356 import android.view.View;
357 import android.view.WindowManager;
359 import com.android.server.job.JobSchedulerInternal;
360 import com.google.android.collect.Lists;
361 import com.google.android.collect.Maps;
363 import com.android.internal.R;
364 import com.android.internal.annotations.GuardedBy;
365 import com.android.internal.annotations.VisibleForTesting;
366 import com.android.internal.app.AssistUtils;
367 import com.android.internal.app.DumpHeapActivity;
368 import com.android.internal.app.IAppOpsCallback;
369 import com.android.internal.app.IAppOpsService;
370 import com.android.internal.app.IVoiceInteractor;
371 import com.android.internal.app.ProcessMap;
372 import com.android.internal.app.SystemUserHomeActivity;
373 import com.android.internal.app.procstats.ProcessStats;
374 import com.android.internal.logging.MetricsLogger;
375 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
376 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
377 import com.android.internal.notification.SystemNotificationChannels;
378 import com.android.internal.os.BackgroundThread;
379 import com.android.internal.os.BatteryStatsImpl;
380 import com.android.internal.os.IResultReceiver;
381 import com.android.internal.os.ProcessCpuTracker;
382 import com.android.internal.os.TransferPipe;
383 import com.android.internal.os.Zygote;
384 import com.android.internal.policy.IKeyguardDismissCallback;
385 import com.android.internal.telephony.TelephonyIntents;
386 import com.android.internal.util.ArrayUtils;
387 import com.android.internal.util.DumpUtils;
388 import com.android.internal.util.FastPrintWriter;
389 import com.android.internal.util.FastXmlSerializer;
390 import com.android.internal.util.MemInfoReader;
391 import com.android.internal.util.Preconditions;
392 import com.android.server.AppOpsService;
393 import com.android.server.AttributeCache;
394 import com.android.server.DeviceIdleController;
395 import com.android.server.IntentResolver;
396 import com.android.server.LocalServices;
397 import com.android.server.LockGuard;
398 import com.android.server.NetworkManagementInternal;
399 import com.android.server.RescueParty;
400 import com.android.server.ServiceThread;
401 import com.android.server.SystemConfig;
402 import com.android.server.SystemService;
403 import com.android.server.SystemServiceManager;
404 import com.android.server.ThreadPriorityBooster;
405 import com.android.server.Watchdog;
406 import com.android.server.am.ActivityStack.ActivityState;
407 import com.android.server.firewall.IntentFirewall;
408 import com.android.server.pm.Installer;
409 import com.android.server.pm.Installer.InstallerException;
410 import com.android.server.statusbar.StatusBarManagerInternal;
411 import com.android.server.vr.VrManagerInternal;
412 import com.android.server.wm.PinnedStackWindowController;
413 import com.android.server.wm.WindowManagerService;
415 import java.text.SimpleDateFormat;
416 import org.xmlpull.v1.XmlPullParser;
417 import org.xmlpull.v1.XmlPullParserException;
418 import org.xmlpull.v1.XmlSerializer;
421 import java.io.FileDescriptor;
422 import java.io.FileInputStream;
423 import java.io.FileNotFoundException;
424 import java.io.FileOutputStream;
425 import java.io.IOException;
426 import java.io.InputStreamReader;
427 import java.io.PrintWriter;
428 import java.io.StringWriter;
429 import java.io.UnsupportedEncodingException;
430 import java.lang.ref.WeakReference;
431 import java.nio.charset.StandardCharsets;
432 import java.text.DateFormat;
433 import java.util.ArrayList;
434 import java.util.Arrays;
435 import java.util.Collections;
436 import java.util.Comparator;
437 import java.util.Date;
438 import java.util.HashMap;
439 import java.util.HashSet;
440 import java.util.Iterator;
441 import java.util.List;
442 import java.util.Locale;
443 import java.util.Map;
444 import java.util.Objects;
445 import java.util.Set;
446 import java.util.concurrent.CountDownLatch;
447 import java.util.concurrent.atomic.AtomicBoolean;
448 import java.util.concurrent.atomic.AtomicLong;
450 import dalvik.system.VMRuntime;
451 import libcore.io.IoUtils;
452 import libcore.util.EmptyArray;
454 public class ActivityManagerService extends IActivityManager.Stub
455 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
458 * Priority we boost main thread and RT of top app to.
460 public static final int TOP_APP_PRIORITY_BOOST = -10;
462 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
463 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
464 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
465 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
466 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
467 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
468 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
469 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
470 private static final String TAG_LRU = TAG + POSTFIX_LRU;
471 private static final String TAG_MU = TAG + POSTFIX_MU;
472 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
473 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
474 private static final String TAG_POWER = TAG + POSTFIX_POWER;
475 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
476 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
477 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
478 private static final String TAG_PSS = TAG + POSTFIX_PSS;
479 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
480 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
481 private static final String TAG_STACK = TAG + POSTFIX_STACK;
482 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
483 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
484 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
485 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
487 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
488 // here so that while the job scheduler can depend on AMS, the other way around
489 // need not be the case.
490 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
492 /** Control over CPU and battery monitoring */
493 // write battery stats every 30 minutes.
494 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
495 static final boolean MONITOR_CPU_USAGE = true;
496 // don't sample cpu less than every 5 seconds.
497 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
498 // wait possibly forever for next cpu sample.
499 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
500 static final boolean MONITOR_THREAD_CPU_USAGE = false;
502 // The flags that are set for all calls we make to the package manager.
503 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
505 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
507 // Amount of time after a call to stopAppSwitches() during which we will
508 // prevent further untrusted switches from happening.
509 static final long APP_SWITCH_DELAY_TIME = 5*1000;
511 // How long we wait for a launched process to attach to the activity manager
512 // before we decide it's never going to come up for real.
513 static final int PROC_START_TIMEOUT = 10*1000;
514 // How long we wait for an attached process to publish its content providers
515 // before we decide it must be hung.
516 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
518 // How long we wait for a launched process to attach to the activity manager
519 // before we decide it's never going to come up for real, when the process was
520 // started with a wrapper for instrumentation (such as Valgrind) because it
521 // could take much longer than usual.
522 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
524 // How long we allow a receiver to run before giving up on it.
525 static final int BROADCAST_FG_TIMEOUT = 10*1000;
526 static final int BROADCAST_BG_TIMEOUT = 60*1000;
528 // How long we wait until we timeout on key dispatching.
529 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
531 // How long we wait until we timeout on key dispatching during instrumentation.
532 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
534 // How long to wait in getAssistContextExtras for the activity and foreground services
535 // to respond with the result.
536 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
538 // How long top wait when going through the modern assist (which doesn't need to block
539 // on getting this result before starting to launch its UI).
540 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
542 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
543 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
545 // Maximum number of persisted Uri grants a package is allowed
546 static final int MAX_PERSISTED_URI_GRANTS = 128;
548 static final int MY_PID = myPid();
550 static final String[] EMPTY_STRING_ARRAY = new String[0];
552 // How many bytes to write into the dropbox log before truncating
553 static final int DROPBOX_MAX_SIZE = 192 * 1024;
554 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
555 // as one line, but close enough for now.
556 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
558 // Access modes for handleIncomingUser.
559 static final int ALLOW_NON_FULL = 0;
560 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
561 static final int ALLOW_FULL_ONLY = 2;
563 // Necessary ApplicationInfo flags to mark an app as persistent
564 private static final int PERSISTENT_MASK =
565 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
567 // Intent sent when remote bugreport collection has been completed
568 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
569 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
571 // Used to indicate that an app transition should be animated.
572 static final boolean ANIMATE = true;
574 // Determines whether to take full screen screenshots
575 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
578 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
580 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
583 * State indicating that there is no need for any blocking for network.
586 static final int NETWORK_STATE_NO_CHANGE = 0;
589 * State indicating that the main thread needs to be informed about the network wait.
592 static final int NETWORK_STATE_BLOCK = 1;
595 * State indicating that any threads waiting for network state to get updated can be unblocked.
598 static final int NETWORK_STATE_UNBLOCK = 2;
600 // Max character limit for a notification title. If the notification title is larger than this
601 // the notification will not be legible to the user.
602 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
604 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
606 /** All system services */
607 SystemServiceManager mSystemServiceManager;
608 AssistUtils mAssistUtils;
610 private Installer mInstaller;
612 /** Run all ActivityStacks through this */
613 final ActivityStackSupervisor mStackSupervisor;
614 private final KeyguardController mKeyguardController;
616 final ActivityStarter mActivityStarter;
618 final TaskChangeNotificationController mTaskChangeNotificationController;
620 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
622 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
624 public final IntentFirewall mIntentFirewall;
626 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
627 // default action automatically. Important for devices without direct input
629 private boolean mShowDialogs = true;
631 private final VrController mVrController;
633 // VR Vr2d Display Id.
634 int mVr2dDisplayId = INVALID_DISPLAY;
636 // Whether we should use SCHED_FIFO for UI and RenderThreads.
637 private boolean mUseFifoUiScheduling = false;
639 BroadcastQueue mFgBroadcastQueue;
640 BroadcastQueue mBgBroadcastQueue;
641 // Convenient for easy iteration over the queues. Foreground is first
642 // so that dispatch of foreground broadcasts gets precedence.
643 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
645 BroadcastStats mLastBroadcastStats;
646 BroadcastStats mCurBroadcastStats;
648 BroadcastQueue broadcastQueueForIntent(Intent intent) {
649 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
650 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
651 "Broadcast intent " + intent + " on "
652 + (isFg ? "foreground" : "background") + " queue");
653 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
657 * The last resumed activity. This is identical to the current resumed activity most
658 * of the time but could be different when we're pausing one activity before we resume
661 private ActivityRecord mLastResumedActivity;
664 * If non-null, we are tracking the time the user spends in the currently focused app.
666 private AppTimeTracker mCurAppTimeTracker;
669 * List of intents that were used to start the most recent tasks.
671 final RecentTasks mRecentTasks;
674 * For addAppTask: cached of the last activity component that was added.
676 ComponentName mLastAddedTaskComponent;
679 * For addAppTask: cached of the last activity uid that was added.
681 int mLastAddedTaskUid;
684 * For addAppTask: cached of the last ActivityInfo that was added.
686 ActivityInfo mLastAddedTaskActivity;
689 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
691 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
694 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
696 String mDeviceOwnerName;
698 final UserController mUserController;
700 final AppErrors mAppErrors;
703 * Dump of the activity state at the time of the last ANR. Cleared after
704 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
706 String mLastANRState;
709 * Indicates the maximum time spent waiting for the network rules to get updated.
712 long mWaitForNetworkTimeoutMs;
714 public boolean canShowErrorDialogs() {
715 return mShowDialogs && !mSleeping && !mShuttingDown
716 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
717 && !(UserManager.isDeviceInDemoMode(mContext)
718 && mUserController.getCurrentUser().isDemo());
721 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
722 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
724 static void boostPriorityForLockedSection() {
725 sThreadPriorityBooster.boost();
728 static void resetPriorityAfterLockedSection() {
729 sThreadPriorityBooster.reset();
732 public class PendingAssistExtras extends Binder implements Runnable {
733 public final ActivityRecord activity;
734 public boolean isHome;
735 public final Bundle extras;
736 public final Intent intent;
737 public final String hint;
738 public final IResultReceiver receiver;
739 public final int userHandle;
740 public boolean haveResult = false;
741 public Bundle result = null;
742 public AssistStructure structure = null;
743 public AssistContent content = null;
744 public Bundle receiverExtras;
746 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
747 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
748 activity = _activity;
752 receiver = _receiver;
753 receiverExtras = _receiverExtras;
754 userHandle = _userHandle;
759 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
760 synchronized (this) {
764 pendingAssistExtrasTimedOut(this);
768 final ArrayList<PendingAssistExtras> mPendingAssistExtras
769 = new ArrayList<PendingAssistExtras>();
772 * Process management.
774 final ProcessList mProcessList = new ProcessList();
777 * All of the applications we currently have running organized by name.
778 * The keys are strings of the application package name (as
779 * returned by the package manager), and the keys are ApplicationRecord
782 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
785 * Tracking long-term execution of processes to look for abuse and other
788 final ProcessStatsService mProcessStats;
791 * The currently running isolated processes.
793 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
796 * Counter for assigning isolated process uids, to avoid frequently reusing the
799 int mNextIsolatedProcessUid = 0;
802 * The currently running heavy-weight process, if any.
804 ProcessRecord mHeavyWeightProcess = null;
807 * Non-persistent appId whitelist for background restrictions
809 int[] mBackgroundAppIdWhitelist = new int[] {
814 * Broadcast actions that will always be deliverable to unlaunched/background apps
816 ArraySet<String> mBackgroundLaunchBroadcasts;
819 * All of the processes we currently have running organized by pid.
820 * The keys are the pid running the application.
822 * <p>NOTE: This object is protected by its own lock, NOT the global
823 * activity manager lock!
825 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
828 * All of the processes that have been forced to be important. The key
829 * is the pid of the caller who requested it (we hold a death
832 abstract class ImportanceToken implements IBinder.DeathRecipient {
837 ImportanceToken(int _pid, IBinder _token, String _reason) {
844 public String toString() {
845 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
846 + " " + reason + " " + pid + " " + token + " }";
849 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
852 * List of records for processes that someone had tried to start before the
853 * system was ready. We don't start them at that point, but ensure they
854 * are started by the time booting is complete.
856 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
859 * List of persistent applications that are in the process
862 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
865 * Processes that are being forcibly torn down.
867 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
870 * List of running applications, sorted by recent usage.
871 * The first entry in the list is the least recently used.
873 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
876 * Where in mLruProcesses that the processes hosting activities start.
878 int mLruProcessActivityStart = 0;
881 * Where in mLruProcesses that the processes hosting services start.
882 * This is after (lower index) than mLruProcessesActivityStart.
884 int mLruProcessServiceStart = 0;
887 * List of processes that should gc as soon as things are idle.
889 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
892 * Processes we want to collect PSS data from.
894 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
896 private boolean mBinderTransactionTrackingEnabled = false;
899 * Last time we requested PSS data of all processes.
901 long mLastFullPssTime = SystemClock.uptimeMillis();
904 * If set, the next time we collect PSS data we should do a full collection
905 * with data from native processes and the kernel.
907 boolean mFullPssPending = false;
910 * This is the process holding what we currently consider to be
911 * the "home" activity.
913 ProcessRecord mHomeProcess;
916 * This is the process holding the activity the user last visited that
917 * is in a different process from the one they are currently in.
919 ProcessRecord mPreviousProcess;
922 * The time at which the previous process was last visible.
924 long mPreviousProcessVisibleTime;
927 * Track all uids that have actively running processes.
929 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
932 * This is for verifying the UID report flow.
934 static final boolean VALIDATE_UID_STATES = true;
935 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
938 * Packages that the user has asked to have run in screen size
939 * compatibility mode instead of filling the screen.
941 final CompatModePackages mCompatModePackages;
944 * Set of IntentSenderRecord objects that are currently active.
946 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
947 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
950 * Fingerprints (hashCode()) of stack traces that we've
951 * already logged DropBox entries for. Guarded by itself. If
952 * something (rogue user app) forces this over
953 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
955 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
956 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
959 * Strict Mode background batched logging state.
961 * The string buffer is guarded by itself, and its lock is also
962 * used to determine if another batched write is already
965 private final StringBuilder mStrictModeBuffer = new StringBuilder();
968 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
969 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
971 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
974 * Resolver for broadcast intents to registered receivers.
975 * Holds BroadcastFilter (subclass of IntentFilter).
977 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
978 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
980 protected boolean allowFilterResult(
981 BroadcastFilter filter, List<BroadcastFilter> dest) {
982 IBinder target = filter.receiverList.receiver.asBinder();
983 for (int i = dest.size() - 1; i >= 0; i--) {
984 if (dest.get(i).receiverList.receiver.asBinder() == target) {
992 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
993 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
994 || userId == filter.owningUserId) {
995 return super.newResult(filter, match, userId);
1001 protected BroadcastFilter[] newArray(int size) {
1002 return new BroadcastFilter[size];
1006 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1007 return packageName.equals(filter.packageName);
1012 * State of all active sticky broadcasts per user. Keys are the action of the
1013 * sticky Intent, values are an ArrayList of all broadcasted intents with
1014 * that action (which should usually be one). The SparseArray is keyed
1015 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1016 * for stickies that are sent to all users.
1018 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1019 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1021 final ActiveServices mServices;
1023 final static class Association {
1024 final int mSourceUid;
1025 final String mSourceProcess;
1026 final int mTargetUid;
1027 final ComponentName mTargetComponent;
1028 final String mTargetProcess;
1036 // states of the source process when the bind occurred.
1037 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1038 long mLastStateUptime;
1039 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1040 - ActivityManager.MIN_PROCESS_STATE+1];
1042 Association(int sourceUid, String sourceProcess, int targetUid,
1043 ComponentName targetComponent, String targetProcess) {
1044 mSourceUid = sourceUid;
1045 mSourceProcess = sourceProcess;
1046 mTargetUid = targetUid;
1047 mTargetComponent = targetComponent;
1048 mTargetProcess = targetProcess;
1053 * When service association tracking is enabled, this is all of the associations we
1054 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1055 * -> association data.
1057 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1058 mAssociations = new SparseArray<>();
1059 boolean mTrackingAssociations;
1062 * Backup/restore process management
1064 String mBackupAppName = null;
1065 BackupRecord mBackupTarget = null;
1067 final ProviderMap mProviderMap;
1070 * List of content providers who have clients waiting for them. The
1071 * application is currently being launched and the provider will be
1072 * removed from this list once it is published.
1074 final ArrayList<ContentProviderRecord> mLaunchingProviders
1075 = new ArrayList<ContentProviderRecord>();
1078 * File storing persisted {@link #mGrantedUriPermissions}.
1080 private final AtomicFile mGrantFile;
1082 /** XML constants used in {@link #mGrantFile} */
1083 private static final String TAG_URI_GRANTS = "uri-grants";
1084 private static final String TAG_URI_GRANT = "uri-grant";
1085 private static final String ATTR_USER_HANDLE = "userHandle";
1086 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1087 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1088 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1089 private static final String ATTR_TARGET_PKG = "targetPkg";
1090 private static final String ATTR_URI = "uri";
1091 private static final String ATTR_MODE_FLAGS = "modeFlags";
1092 private static final String ATTR_CREATED_TIME = "createdTime";
1093 private static final String ATTR_PREFIX = "prefix";
1096 * Global set of specific {@link Uri} permissions that have been granted.
1097 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1098 * to {@link UriPermission#uri} to {@link UriPermission}.
1101 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1102 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1104 public static class GrantUri {
1105 public final int sourceUserId;
1106 public final Uri uri;
1107 public boolean prefix;
1109 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1110 this.sourceUserId = sourceUserId;
1112 this.prefix = prefix;
1116 public int hashCode() {
1118 hashCode = 31 * hashCode + sourceUserId;
1119 hashCode = 31 * hashCode + uri.hashCode();
1120 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1125 public boolean equals(Object o) {
1126 if (o instanceof GrantUri) {
1127 GrantUri other = (GrantUri) o;
1128 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1129 && prefix == other.prefix;
1135 public String toString() {
1136 String result = uri.toString() + " [user " + sourceUserId + "]";
1137 if (prefix) result += " [prefix]";
1141 public String toSafeString() {
1142 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1143 if (prefix) result += " [prefix]";
1147 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1148 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1149 ContentProvider.getUriWithoutUserId(uri), false);
1153 CoreSettingsObserver mCoreSettingsObserver;
1155 FontScaleSettingObserver mFontScaleSettingObserver;
1157 private final class FontScaleSettingObserver extends ContentObserver {
1158 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1160 public FontScaleSettingObserver() {
1162 ContentResolver resolver = mContext.getContentResolver();
1163 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1167 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1168 if (mFontScaleUri.equals(uri)) {
1169 updateFontScaleIfNeeded(userId);
1175 * Thread-local storage used to carry caller permissions over through
1176 * indirect content-provider access.
1178 private class Identity {
1179 public final IBinder token;
1180 public final int pid;
1181 public final int uid;
1183 Identity(IBinder _token, int _pid, int _uid) {
1190 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1193 * All information we have collected about the runtime performance of
1194 * any user id that can impact battery performance.
1196 final BatteryStatsService mBatteryStatsService;
1199 * Information about component usage
1201 UsageStatsManagerInternal mUsageStatsService;
1204 * Access to DeviceIdleController service.
1206 DeviceIdleController.LocalService mLocalDeviceIdleController;
1209 * Set of app ids that are whitelisted for device idle and thus background check.
1211 int[] mDeviceIdleWhitelist = new int[0];
1214 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1216 int[] mDeviceIdleTempWhitelist = new int[0];
1218 static final class PendingTempWhitelist {
1219 final int targetUid;
1220 final long duration;
1223 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1224 targetUid = _targetUid;
1225 duration = _duration;
1230 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1233 * Information about and control over application operations
1235 final AppOpsService mAppOpsService;
1237 /** Current sequencing integer of the configuration, for skipping old configurations. */
1238 private int mConfigurationSeq;
1241 * Temp object used when global and/or display override configuration is updated. It is also
1242 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1245 private Configuration mTempConfig = new Configuration();
1247 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1248 new UpdateConfigurationResult();
1249 private static final class UpdateConfigurationResult {
1250 // Configuration changes that were updated.
1252 // If the activity was relaunched to match the new configuration.
1253 boolean activityRelaunched;
1257 activityRelaunched = false;
1261 boolean mSuppressResizeConfigChanges;
1264 * Hardware-reported OpenGLES version.
1266 final int GL_ES_VERSION;
1269 * List of initialization arguments to pass to all processes when binding applications to them.
1270 * For example, references to the commonly used services.
1272 HashMap<String, IBinder> mAppBindArgs;
1273 HashMap<String, IBinder> mIsolatedAppBindArgs;
1276 * Temporary to avoid allocations. Protected by main lock.
1278 final StringBuilder mStringBuilder = new StringBuilder(256);
1281 * Used to control how we initialize the service.
1283 ComponentName mTopComponent;
1284 String mTopAction = Intent.ACTION_MAIN;
1287 volatile boolean mProcessesReady = false;
1288 volatile boolean mSystemReady = false;
1289 volatile boolean mOnBattery = false;
1290 volatile int mFactoryTest;
1292 @GuardedBy("this") boolean mBooting = false;
1293 @GuardedBy("this") boolean mCallFinishBooting = false;
1294 @GuardedBy("this") boolean mBootAnimationComplete = false;
1295 @GuardedBy("this") boolean mLaunchWarningShown = false;
1296 @GuardedBy("this") boolean mCheckedForSetup = false;
1298 final Context mContext;
1301 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1302 * change at runtime. Use mContext for non-UI purposes.
1304 final Context mUiContext;
1307 * The time at which we will allow normal application switches again,
1308 * after a call to {@link #stopAppSwitches()}.
1310 long mAppSwitchesAllowedTime;
1313 * This is set to true after the first switch after mAppSwitchesAllowedTime
1314 * is set; any switches after that will clear the time.
1316 boolean mDidAppSwitch;
1319 * Last time (in uptime) at which we checked for power usage.
1321 long mLastPowerCheckUptime;
1324 * Set while we are wanting to sleep, to prevent any
1325 * activities from being started/resumed.
1327 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1329 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1330 * while in the sleep state until there is a pending transition out of sleep, in which case
1331 * mSleeping is set to false, and remains false while awake.
1333 * Whether mSleeping can quickly toggled between true/false without the device actually
1334 * display changing states is undefined.
1336 private boolean mSleeping = false;
1339 * The process state used for processes that are running the top activities.
1340 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1342 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1345 * Set while we are running a voice interaction. This overrides
1346 * sleeping while it is active.
1348 IVoiceInteractionSession mRunningVoice;
1351 * For some direct access we need to power manager.
1353 PowerManagerInternal mLocalPowerManager;
1356 * We want to hold a wake lock while running a voice interaction session, since
1357 * this may happen with the screen off and we need to keep the CPU running to
1358 * be able to continue to interact with the user.
1360 PowerManager.WakeLock mVoiceWakeLock;
1363 * State of external calls telling us if the device is awake or asleep.
1365 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1368 * Set if we are shutting down the system, similar to sleeping.
1370 boolean mShuttingDown = false;
1373 * Current sequence id for oom_adj computation traversal.
1378 * Current sequence id for process LRU updating.
1383 * Keep track of the non-cached/empty process we last found, to help
1384 * determine how to distribute cached/empty processes next time.
1386 int mNumNonCachedProcs = 0;
1389 * Keep track of the number of cached hidden procs, to balance oom adj
1390 * distribution between those and empty procs.
1392 int mNumCachedHiddenProcs = 0;
1395 * Keep track of the number of service processes we last found, to
1396 * determine on the next iteration which should be B services.
1398 int mNumServiceProcs = 0;
1399 int mNewNumAServiceProcs = 0;
1400 int mNewNumServiceProcs = 0;
1403 * Allow the current computed overall memory level of the system to go down?
1404 * This is set to false when we are killing processes for reasons other than
1405 * memory management, so that the now smaller process list will not be taken as
1406 * an indication that memory is tighter.
1408 boolean mAllowLowerMemLevel = false;
1411 * The last computed memory level, for holding when we are in a state that
1412 * processes are going away for other reasons.
1414 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1417 * The last total number of process we have, to determine if changes actually look
1418 * like a shrinking number of process due to lower RAM.
1420 int mLastNumProcesses;
1423 * The uptime of the last time we performed idle maintenance.
1425 long mLastIdleTime = SystemClock.uptimeMillis();
1428 * Total time spent with RAM that has been added in the past since the last idle time.
1430 long mLowRamTimeSinceLastIdle = 0;
1433 * If RAM is currently low, when that horrible situation started.
1435 long mLowRamStartTime = 0;
1438 * For reporting to battery stats the current top application.
1440 private String mCurResumedPackage = null;
1441 private int mCurResumedUid = -1;
1444 * For reporting to battery stats the apps currently running foreground
1445 * service. The ProcessMap is package/uid tuples; each of these contain
1446 * an array of the currently foreground processes.
1448 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1449 = new ProcessMap<ArrayList<ProcessRecord>>();
1452 * Set if the systemServer made a call to enterSafeMode.
1457 * If true, we are running under a test environment so will sample PSS from processes
1458 * much more rapidly to try to collect better data when the tests are rapidly
1459 * running through apps.
1461 boolean mTestPssMode = false;
1463 String mDebugApp = null;
1464 boolean mWaitForDebugger = false;
1465 boolean mDebugTransient = false;
1466 String mOrigDebugApp = null;
1467 boolean mOrigWaitForDebugger = false;
1468 boolean mAlwaysFinishActivities = false;
1469 boolean mForceResizableActivities;
1471 * Flag that indicates if multi-window is enabled.
1473 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1474 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1475 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1476 * At least one of the forms of multi-window must be enabled in order for this flag to be
1477 * initialized to 'true'.
1479 * @see #mSupportsSplitScreenMultiWindow
1480 * @see #mSupportsFreeformWindowManagement
1481 * @see #mSupportsPictureInPicture
1482 * @see #mSupportsMultiDisplay
1484 boolean mSupportsMultiWindow;
1485 boolean mSupportsSplitScreenMultiWindow;
1486 boolean mSupportsFreeformWindowManagement;
1487 boolean mSupportsPictureInPicture;
1488 boolean mSupportsMultiDisplay;
1489 boolean mSupportsLeanbackOnly;
1490 IActivityController mController = null;
1491 boolean mControllerIsAMonkey = false;
1492 String mProfileApp = null;
1493 ProcessRecord mProfileProc = null;
1494 ProfilerInfo mProfilerInfo = null;
1495 int mProfileType = 0;
1496 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1497 String mMemWatchDumpProcName;
1498 String mMemWatchDumpFile;
1499 int mMemWatchDumpPid;
1500 int mMemWatchDumpUid;
1501 String mTrackAllocationApp = null;
1502 String mNativeDebuggingApp = null;
1504 final long[] mTmpLong = new long[2];
1506 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1509 * A global counter for generating sequence numbers.
1510 * This value will be used when incrementing sequence numbers in individual uidRecords.
1512 * Having a global counter ensures that seq numbers are monotonically increasing for a
1513 * particular uid even when the uidRecord is re-created.
1517 long mProcStateSeqCounter = 0;
1519 private final Injector mInjector;
1521 static final class ProcessChangeItem {
1522 static final int CHANGE_ACTIVITIES = 1<<0;
1527 boolean foregroundActivities;
1530 static final class UidObserverRegistration {
1536 final SparseIntArray lastProcStates;
1538 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1542 cutpoint = _cutpoint;
1543 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1544 lastProcStates = new SparseIntArray();
1546 lastProcStates = null;
1551 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1552 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1554 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1555 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1557 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1558 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1560 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1561 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1563 OomAdjObserver mCurOomAdjObserver;
1566 interface OomAdjObserver {
1567 void onOomAdjMessage(String msg);
1571 * Runtime CPU use collection thread. This object's lock is used to
1572 * perform synchronization with the thread (notifying it to run).
1574 final Thread mProcessCpuThread;
1577 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1578 * Must acquire this object's lock when accessing it.
1579 * NOTE: this lock will be held while doing long operations (trawling
1580 * through all processes in /proc), so it should never be acquired by
1581 * any critical paths such as when holding the main activity manager lock.
1583 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1584 MONITOR_THREAD_CPU_USAGE);
1585 final AtomicLong mLastCpuTime = new AtomicLong(0);
1586 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1587 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1589 long mLastWriteTime = 0;
1592 * Used to retain an update lock when the foreground activity is in
1595 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1598 * Set to true after the system has finished booting.
1600 boolean mBooted = false;
1602 WindowManagerService mWindowManager;
1603 final ActivityThread mSystemThread;
1605 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1606 final ProcessRecord mApp;
1608 final IApplicationThread mAppThread;
1610 AppDeathRecipient(ProcessRecord app, int pid,
1611 IApplicationThread thread) {
1612 if (DEBUG_ALL) Slog.v(
1613 TAG, "New death recipient " + this
1614 + " for thread " + thread.asBinder());
1617 mAppThread = thread;
1621 public void binderDied() {
1622 if (DEBUG_ALL) Slog.v(
1623 TAG, "Death received in " + this
1624 + " for thread " + mAppThread.asBinder());
1625 synchronized(ActivityManagerService.this) {
1626 appDiedLocked(mApp, mPid, mAppThread, true);
1631 static final int SHOW_ERROR_UI_MSG = 1;
1632 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1633 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1634 static final int UPDATE_CONFIGURATION_MSG = 4;
1635 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1636 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1637 static final int SERVICE_TIMEOUT_MSG = 12;
1638 static final int UPDATE_TIME_ZONE = 13;
1639 static final int SHOW_UID_ERROR_UI_MSG = 14;
1640 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1641 static final int PROC_START_TIMEOUT_MSG = 20;
1642 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1643 static final int KILL_APPLICATION_MSG = 22;
1644 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1645 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1646 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1647 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1648 static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1649 static final int CLEAR_DNS_CACHE_MSG = 28;
1650 static final int UPDATE_HTTP_PROXY_MSG = 29;
1651 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1652 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1653 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1654 static final int REPORT_MEM_USAGE_MSG = 33;
1655 static final int REPORT_USER_SWITCH_MSG = 34;
1656 static final int CONTINUE_USER_SWITCH_MSG = 35;
1657 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1658 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1659 static final int PERSIST_URI_GRANTS_MSG = 38;
1660 static final int REQUEST_ALL_PSS_MSG = 39;
1661 static final int START_PROFILES_MSG = 40;
1662 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1663 static final int SYSTEM_USER_START_MSG = 42;
1664 static final int SYSTEM_USER_CURRENT_MSG = 43;
1665 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1666 static final int FINISH_BOOTING_MSG = 45;
1667 static final int START_USER_SWITCH_UI_MSG = 46;
1668 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1669 static final int DISMISS_DIALOG_UI_MSG = 48;
1670 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1671 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1672 static final int DELETE_DUMPHEAP_MSG = 51;
1673 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1674 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1675 static final int REPORT_TIME_TRACKER_MSG = 54;
1676 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1677 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1678 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1679 static final int IDLE_UIDS_MSG = 58;
1680 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1681 static final int LOG_STACK_STATE = 60;
1682 static final int VR_MODE_CHANGE_MSG = 61;
1683 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1684 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1685 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1686 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1687 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1688 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1689 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1690 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1691 static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1692 static final int START_USER_SWITCH_FG_MSG = 712;
1693 static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1695 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1696 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1697 static final int FIRST_COMPAT_MODE_MSG = 300;
1698 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1700 static ServiceThread sKillThread = null;
1701 static KillHandler sKillHandler = null;
1703 CompatModeDialog mCompatModeDialog;
1704 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1705 long mLastMemUsageReportTime = 0;
1708 * Flag whether the current user is a "monkey", i.e. whether
1709 * the UI is driven by a UI automation tool.
1711 private boolean mUserIsMonkey;
1713 /** Flag whether the device has a Recents UI */
1714 boolean mHasRecents;
1716 /** The dimensions of the thumbnails in the Recents UI. */
1717 int mThumbnailWidth;
1718 int mThumbnailHeight;
1719 float mFullscreenThumbnailScale;
1721 final ServiceThread mHandlerThread;
1722 final MainHandler mHandler;
1723 final Handler mUiHandler;
1725 final ActivityManagerConstants mConstants;
1727 PackageManagerInternal mPackageManagerInt;
1729 // VoiceInteraction session ID that changes for each new request except when
1730 // being called for multiwindow assist in a single session.
1731 private int mViSessionId = 1000;
1733 final boolean mPermissionReviewRequired;
1735 private static String sTheRealBuildSerial = Build.UNKNOWN;
1738 * Current global configuration information. Contains general settings for the entire system,
1739 * also corresponds to the merged configuration of the default display.
1741 Configuration getGlobalConfiguration() {
1742 return mStackSupervisor.getConfiguration();
1745 final class KillHandler extends Handler {
1746 static final int KILL_PROCESS_GROUP_MSG = 4000;
1748 public KillHandler(Looper looper) {
1749 super(looper, null, true);
1753 public void handleMessage(Message msg) {
1755 case KILL_PROCESS_GROUP_MSG:
1757 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1758 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1759 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1764 super.handleMessage(msg);
1769 final class UiHandler extends Handler {
1770 public UiHandler() {
1771 super(com.android.server.UiThread.get().getLooper(), null, true);
1775 public void handleMessage(Message msg) {
1777 case SHOW_ERROR_UI_MSG: {
1778 mAppErrors.handleShowAppErrorUi(msg);
1779 ensureBootCompleted();
1781 case SHOW_NOT_RESPONDING_UI_MSG: {
1782 mAppErrors.handleShowAnrUi(msg);
1783 ensureBootCompleted();
1785 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1786 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1787 synchronized (ActivityManagerService.this) {
1788 ProcessRecord proc = (ProcessRecord) data.get("app");
1790 Slog.e(TAG, "App not found when showing strict mode dialog.");
1793 if (proc.crashDialog != null) {
1794 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1797 AppErrorResult res = (AppErrorResult) data.get("result");
1798 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1799 Dialog d = new StrictModeViolationDialog(mUiContext,
1800 ActivityManagerService.this, res, proc);
1802 proc.crashDialog = d;
1804 // The device is asleep, so just pretend that the user
1805 // saw a crash dialog and hit "force quit".
1809 ensureBootCompleted();
1811 case SHOW_FACTORY_ERROR_UI_MSG: {
1812 Dialog d = new FactoryErrorDialog(
1813 mUiContext, msg.getData().getCharSequence("msg"));
1815 ensureBootCompleted();
1817 case WAIT_FOR_DEBUGGER_UI_MSG: {
1818 synchronized (ActivityManagerService.this) {
1819 ProcessRecord app = (ProcessRecord)msg.obj;
1820 if (msg.arg1 != 0) {
1821 if (!app.waitedForDebugger) {
1822 Dialog d = new AppWaitingForDebuggerDialog(
1823 ActivityManagerService.this,
1826 app.waitedForDebugger = true;
1830 if (app.waitDialog != null) {
1831 app.waitDialog.dismiss();
1832 app.waitDialog = null;
1837 case SHOW_UID_ERROR_UI_MSG: {
1839 AlertDialog d = new BaseErrorDialog(mUiContext);
1840 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1841 d.setCancelable(false);
1842 d.setTitle(mUiContext.getText(R.string.android_system_label));
1843 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1844 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1845 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1849 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1851 AlertDialog d = new BaseErrorDialog(mUiContext);
1852 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1853 d.setCancelable(false);
1854 d.setTitle(mUiContext.getText(R.string.android_system_label));
1855 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1856 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1857 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1861 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1862 synchronized (ActivityManagerService.this) {
1863 ActivityRecord ar = (ActivityRecord) msg.obj;
1864 if (mCompatModeDialog != null) {
1865 if (mCompatModeDialog.mAppInfo.packageName.equals(
1866 ar.info.applicationInfo.packageName)) {
1869 mCompatModeDialog.dismiss();
1870 mCompatModeDialog = null;
1872 if (ar != null && false) {
1873 if (mCompatModePackages.getPackageAskCompatModeLocked(
1875 int mode = mCompatModePackages.computeCompatModeLocked(
1876 ar.info.applicationInfo);
1877 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1878 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1879 mCompatModeDialog = new CompatModeDialog(
1880 ActivityManagerService.this, mUiContext,
1881 ar.info.applicationInfo);
1882 mCompatModeDialog.show();
1889 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1890 synchronized (ActivityManagerService.this) {
1891 final ActivityRecord ar = (ActivityRecord) msg.obj;
1892 if (mUnsupportedDisplaySizeDialog != null) {
1893 mUnsupportedDisplaySizeDialog.dismiss();
1894 mUnsupportedDisplaySizeDialog = null;
1896 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1898 // TODO(multi-display): Show dialog on appropriate display.
1899 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1900 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1901 mUnsupportedDisplaySizeDialog.show();
1906 case START_USER_SWITCH_UI_MSG: {
1907 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1910 case DISMISS_DIALOG_UI_MSG: {
1911 final Dialog d = (Dialog) msg.obj;
1915 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1916 dispatchProcessesChanged();
1919 case DISPATCH_PROCESS_DIED_UI_MSG: {
1920 final int pid = msg.arg1;
1921 final int uid = msg.arg2;
1922 dispatchProcessDied(pid, uid);
1925 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1926 dispatchUidsChanged();
1928 case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1929 dispatchOomAdjObserver((String)msg.obj);
1931 case PUSH_TEMP_WHITELIST_UI_MSG: {
1932 pushTempWhitelist();
1938 final class MainHandler extends Handler {
1939 public MainHandler(Looper looper) {
1940 super(looper, null, true);
1944 public void handleMessage(Message msg) {
1946 case UPDATE_CONFIGURATION_MSG: {
1947 final ContentResolver resolver = mContext.getContentResolver();
1948 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1951 case GC_BACKGROUND_PROCESSES_MSG: {
1952 synchronized (ActivityManagerService.this) {
1953 performAppGcsIfAppropriateLocked();
1956 case SERVICE_TIMEOUT_MSG: {
1957 mServices.serviceTimeout((ProcessRecord)msg.obj);
1959 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1960 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1962 case SERVICE_FOREGROUND_CRASH_MSG: {
1963 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1965 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1966 RemoteCallbackList<IResultReceiver> callbacks
1967 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1968 int N = callbacks.beginBroadcast();
1969 for (int i = 0; i < N; i++) {
1971 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1972 } catch (RemoteException e) {
1975 callbacks.finishBroadcast();
1977 case UPDATE_TIME_ZONE: {
1978 synchronized (ActivityManagerService.this) {
1979 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1980 ProcessRecord r = mLruProcesses.get(i);
1981 if (r.thread != null) {
1983 r.thread.updateTimeZone();
1984 } catch (RemoteException ex) {
1985 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1991 case CLEAR_DNS_CACHE_MSG: {
1992 synchronized (ActivityManagerService.this) {
1993 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1994 ProcessRecord r = mLruProcesses.get(i);
1995 if (r.thread != null) {
1997 r.thread.clearDnsCache();
1998 } catch (RemoteException ex) {
1999 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2005 case UPDATE_HTTP_PROXY_MSG: {
2006 ProxyInfo proxy = (ProxyInfo)msg.obj;
2009 String exclList = "";
2010 Uri pacFileUrl = Uri.EMPTY;
2011 if (proxy != null) {
2012 host = proxy.getHost();
2013 port = Integer.toString(proxy.getPort());
2014 exclList = proxy.getExclusionListAsString();
2015 pacFileUrl = proxy.getPacFileUrl();
2017 synchronized (ActivityManagerService.this) {
2018 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2019 ProcessRecord r = mLruProcesses.get(i);
2020 if (r.thread != null) {
2022 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2023 } catch (RemoteException ex) {
2024 Slog.w(TAG, "Failed to update http proxy for: " +
2025 r.info.processName);
2031 case PROC_START_TIMEOUT_MSG: {
2032 ProcessRecord app = (ProcessRecord)msg.obj;
2033 synchronized (ActivityManagerService.this) {
2034 processStartTimedOutLocked(app);
2037 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2038 ProcessRecord app = (ProcessRecord)msg.obj;
2039 synchronized (ActivityManagerService.this) {
2040 processContentProviderPublishTimedOutLocked(app);
2043 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2044 synchronized (ActivityManagerService.this) {
2045 mActivityStarter.doPendingActivityLaunchesLocked(true);
2048 case KILL_APPLICATION_MSG: {
2049 synchronized (ActivityManagerService.this) {
2050 final int appId = msg.arg1;
2051 final int userId = msg.arg2;
2052 Bundle bundle = (Bundle)msg.obj;
2053 String pkg = bundle.getString("pkg");
2054 String reason = bundle.getString("reason");
2055 forceStopPackageLocked(pkg, appId, false, false, true, false,
2056 false, userId, reason);
2059 case FINALIZE_PENDING_INTENT_MSG: {
2060 ((PendingIntentRecord)msg.obj).completeFinalize();
2062 case POST_HEAVY_NOTIFICATION_MSG: {
2063 INotificationManager inm = NotificationManager.getService();
2068 ActivityRecord root = (ActivityRecord)msg.obj;
2069 ProcessRecord process = root.app;
2070 if (process == null) {
2075 Context context = mContext.createPackageContext(process.info.packageName, 0);
2076 String text = mContext.getString(R.string.heavy_weight_notification,
2077 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2078 Notification notification =
2079 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2080 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2084 .setColor(mContext.getColor(
2085 com.android.internal.R.color.system_notification_accent_color))
2086 .setContentTitle(text)
2088 mContext.getText(R.string.heavy_weight_notification_detail))
2089 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2090 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2091 new UserHandle(root.userId)))
2094 inm.enqueueNotificationWithTag("android", "android", null,
2095 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2096 notification, root.userId);
2097 } catch (RuntimeException e) {
2098 Slog.w(ActivityManagerService.TAG,
2099 "Error showing notification for heavy-weight app", e);
2100 } catch (RemoteException e) {
2102 } catch (NameNotFoundException e) {
2103 Slog.w(TAG, "Unable to create context for heavy notification", e);
2106 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2107 INotificationManager inm = NotificationManager.getService();
2112 inm.cancelNotificationWithTag("android", null,
2113 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2114 } catch (RuntimeException e) {
2115 Slog.w(ActivityManagerService.TAG,
2116 "Error canceling notification for service", e);
2117 } catch (RemoteException e) {
2120 case CHECK_EXCESSIVE_POWER_USE_MSG: {
2121 synchronized (ActivityManagerService.this) {
2122 checkExcessivePowerUsageLocked();
2123 removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2124 Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2125 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2128 case REPORT_MEM_USAGE_MSG: {
2129 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2130 Thread thread = new Thread() {
2131 @Override public void run() {
2132 reportMemUsage(memInfos);
2138 case START_USER_SWITCH_FG_MSG: {
2139 mUserController.startUserInForeground(msg.arg1);
2142 case REPORT_USER_SWITCH_MSG: {
2143 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2146 case CONTINUE_USER_SWITCH_MSG: {
2147 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2150 case USER_SWITCH_TIMEOUT_MSG: {
2151 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2154 case IMMERSIVE_MODE_LOCK_MSG: {
2155 final boolean nextState = (msg.arg1 != 0);
2156 if (mUpdateLock.isHeld() != nextState) {
2157 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2158 "Applying new update lock state '" + nextState
2159 + "' for " + (ActivityRecord)msg.obj);
2161 mUpdateLock.acquire();
2163 mUpdateLock.release();
2168 case PERSIST_URI_GRANTS_MSG: {
2169 writeGrantedUriPermissions();
2172 case REQUEST_ALL_PSS_MSG: {
2173 synchronized (ActivityManagerService.this) {
2174 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2178 case START_PROFILES_MSG: {
2179 synchronized (ActivityManagerService.this) {
2180 mUserController.startProfilesLocked();
2184 case UPDATE_TIME_PREFERENCE_MSG: {
2185 // The user's time format preference might have changed.
2186 // For convenience we re-use the Intent extra values.
2187 synchronized (ActivityManagerService.this) {
2188 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2189 ProcessRecord r = mLruProcesses.get(i);
2190 if (r.thread != null) {
2192 r.thread.updateTimePrefs(msg.arg1);
2193 } catch (RemoteException ex) {
2194 Slog.w(TAG, "Failed to update preferences for: "
2195 + r.info.processName);
2202 case SYSTEM_USER_START_MSG: {
2203 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2204 Integer.toString(msg.arg1), msg.arg1);
2205 mSystemServiceManager.startUser(msg.arg1);
2208 case SYSTEM_USER_UNLOCK_MSG: {
2209 final int userId = msg.arg1;
2210 mSystemServiceManager.unlockUser(userId);
2211 synchronized (ActivityManagerService.this) {
2212 mRecentTasks.loadUserRecentsLocked(userId);
2214 if (userId == UserHandle.USER_SYSTEM) {
2215 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2217 installEncryptionUnawareProviders(userId);
2218 mUserController.finishUserUnlocked((UserState) msg.obj);
2221 case SYSTEM_USER_CURRENT_MSG: {
2222 mBatteryStatsService.noteEvent(
2223 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2224 Integer.toString(msg.arg2), msg.arg2);
2225 mBatteryStatsService.noteEvent(
2226 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2227 Integer.toString(msg.arg1), msg.arg1);
2228 mSystemServiceManager.switchUser(msg.arg1);
2231 case ENTER_ANIMATION_COMPLETE_MSG: {
2232 synchronized (ActivityManagerService.this) {
2233 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2234 if (r != null && r.app != null && r.app.thread != null) {
2236 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2237 } catch (RemoteException e) {
2243 case FINISH_BOOTING_MSG: {
2244 if (msg.arg1 != 0) {
2245 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2247 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2249 if (msg.arg2 != 0) {
2250 enableScreenAfterBoot();
2254 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2256 Locale l = (Locale) msg.obj;
2257 IBinder service = ServiceManager.getService("mount");
2258 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2259 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2260 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2261 } catch (RemoteException e) {
2262 Log.e(TAG, "Error storing locale for decryption UI", e);
2266 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2267 final int uid = msg.arg1;
2268 final byte[] firstPacket = (byte[]) msg.obj;
2270 synchronized (mPidsSelfLocked) {
2271 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2272 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2275 p.thread.notifyCleartextNetwork(firstPacket);
2276 } catch (RemoteException ignored) {
2283 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2284 final String procName;
2286 final long memLimit;
2287 final String reportPackage;
2288 synchronized (ActivityManagerService.this) {
2289 procName = mMemWatchDumpProcName;
2290 uid = mMemWatchDumpUid;
2291 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2293 val = mMemWatchProcesses.get(procName, 0);
2296 memLimit = val.first;
2297 reportPackage = val.second;
2300 reportPackage = null;
2303 if (procName == null) {
2307 if (DEBUG_PSS) Slog.d(TAG_PSS,
2308 "Showing dump heap notification from " + procName + "/" + uid);
2310 INotificationManager inm = NotificationManager.getService();
2315 String text = mContext.getString(R.string.dump_heap_notification, procName);
2318 Intent deleteIntent = new Intent();
2319 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2320 Intent intent = new Intent();
2321 intent.setClassName("android", DumpHeapActivity.class.getName());
2322 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2323 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2324 if (reportPackage != null) {
2325 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2327 int userId = UserHandle.getUserId(uid);
2328 Notification notification =
2329 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2330 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2333 .setAutoCancel(true)
2335 .setColor(mContext.getColor(
2336 com.android.internal.R.color.system_notification_accent_color))
2337 .setContentTitle(text)
2339 mContext.getText(R.string.dump_heap_notification_detail))
2340 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2341 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2342 new UserHandle(userId)))
2343 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2344 deleteIntent, 0, UserHandle.SYSTEM))
2348 inm.enqueueNotificationWithTag("android", "android", null,
2349 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2350 notification, userId);
2351 } catch (RuntimeException e) {
2352 Slog.w(ActivityManagerService.TAG,
2353 "Error showing notification for dump heap", e);
2354 } catch (RemoteException e) {
2357 case DELETE_DUMPHEAP_MSG: {
2358 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2359 null, DumpHeapActivity.JAVA_URI,
2360 Intent.FLAG_GRANT_READ_URI_PERMISSION
2361 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2362 UserHandle.myUserId());
2363 synchronized (ActivityManagerService.this) {
2364 mMemWatchDumpFile = null;
2365 mMemWatchDumpProcName = null;
2366 mMemWatchDumpPid = -1;
2367 mMemWatchDumpUid = -1;
2370 case FOREGROUND_PROFILE_CHANGED_MSG: {
2371 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2373 case REPORT_TIME_TRACKER_MSG: {
2374 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2375 tracker.deliverResult(mContext);
2377 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2378 mUserController.dispatchUserSwitchComplete(msg.arg1);
2380 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2381 mUserController.dispatchLockedBootComplete(msg.arg1);
2383 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2384 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2386 connection.shutdown();
2387 } catch (RemoteException e) {
2388 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2390 // Only a UiAutomation can set this flag and now that
2391 // it is finished we make sure it is reset to its default.
2392 mUserIsMonkey = false;
2394 case IDLE_UIDS_MSG: {
2397 case VR_MODE_CHANGE_MSG: {
2398 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2401 synchronized (ActivityManagerService.this) {
2402 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2403 mWindowManager.disableNonVrUi(disableNonVrUi);
2404 if (disableNonVrUi) {
2405 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2406 // then remove the pinned stack.
2407 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2409 if (pinnedStack != null) {
2410 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2415 case NOTIFY_VR_SLEEPING_MSG: {
2416 notifyVrManagerOfSleepState(msg.arg1 != 0);
2418 case NOTIFY_VR_KEYGUARD_MSG: {
2419 notifyVrManagerOfKeyguardState(msg.arg1 != 0);
2421 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2422 synchronized (ActivityManagerService.this) {
2423 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2424 ProcessRecord r = mLruProcesses.get(i);
2425 if (r.thread != null) {
2427 r.thread.handleTrustStorageUpdate();
2428 } catch (RemoteException ex) {
2429 Slog.w(TAG, "Failed to handle trust storage update for: " +
2430 r.info.processName);
2440 static final int COLLECT_PSS_BG_MSG = 1;
2442 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2444 public void handleMessage(Message msg) {
2446 case COLLECT_PSS_BG_MSG: {
2447 long start = SystemClock.uptimeMillis();
2448 MemInfoReader memInfo = null;
2449 synchronized (ActivityManagerService.this) {
2450 if (mFullPssPending) {
2451 mFullPssPending = false;
2452 memInfo = new MemInfoReader();
2455 if (memInfo != null) {
2456 updateCpuStatsNow();
2457 long nativeTotalPss = 0;
2458 final List<ProcessCpuTracker.Stats> stats;
2459 synchronized (mProcessCpuTracker) {
2460 stats = mProcessCpuTracker.getStats( (st)-> {
2461 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2464 final int N = stats.size();
2465 for (int j = 0; j < N; j++) {
2466 synchronized (mPidsSelfLocked) {
2467 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2468 // This is one of our own processes; skip it.
2472 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2474 memInfo.readMemInfo();
2475 synchronized (ActivityManagerService.this) {
2476 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2477 + (SystemClock.uptimeMillis()-start) + "ms");
2478 final long cachedKb = memInfo.getCachedSizeKb();
2479 final long freeKb = memInfo.getFreeSizeKb();
2480 final long zramKb = memInfo.getZramTotalSizeKb();
2481 final long kernelKb = memInfo.getKernelUsedSizeKb();
2482 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2483 kernelKb*1024, nativeTotalPss*1024);
2484 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2490 long[] tmp = new long[2];
2496 synchronized (ActivityManagerService.this) {
2497 if (mPendingPssProcesses.size() <= 0) {
2498 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2499 "Collected PSS of " + num + " processes in "
2500 + (SystemClock.uptimeMillis() - start) + "ms");
2501 mPendingPssProcesses.clear();
2504 proc = mPendingPssProcesses.remove(0);
2505 procState = proc.pssProcState;
2506 lastPssTime = proc.lastPssTime;
2507 if (proc.thread != null && procState == proc.setProcState
2508 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2509 < SystemClock.uptimeMillis()) {
2517 long pss = Debug.getPss(pid, tmp, null);
2518 synchronized (ActivityManagerService.this) {
2519 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2520 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2522 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2523 SystemClock.uptimeMillis());
2533 public void setSystemProcess() {
2535 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2536 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2537 ServiceManager.addService("meminfo", new MemBinder(this));
2538 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2539 ServiceManager.addService("dbinfo", new DbBinder(this));
2540 if (MONITOR_CPU_USAGE) {
2541 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2543 ServiceManager.addService("permission", new PermissionController(this));
2544 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2546 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2547 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2548 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2550 synchronized (this) {
2551 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2552 app.persistent = true;
2554 app.maxAdj = ProcessList.SYSTEM_ADJ;
2555 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2556 synchronized (mPidsSelfLocked) {
2557 mPidsSelfLocked.put(app.pid, app);
2559 updateLruProcessLocked(app, false, null);
2560 updateOomAdjLocked();
2562 } catch (PackageManager.NameNotFoundException e) {
2563 throw new RuntimeException(
2564 "Unable to find android system package", e);
2568 public void setWindowManager(WindowManagerService wm) {
2569 mWindowManager = wm;
2570 mStackSupervisor.setWindowManager(wm);
2571 mActivityStarter.setWindowManager(wm);
2574 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2575 mUsageStatsService = usageStatsManager;
2578 public void startObservingNativeCrashes() {
2579 final NativeCrashListener ncl = new NativeCrashListener(this);
2583 public IAppOpsService getAppOpsService() {
2584 return mAppOpsService;
2587 static class MemBinder extends Binder {
2588 ActivityManagerService mActivityManagerService;
2589 MemBinder(ActivityManagerService activityManagerService) {
2590 mActivityManagerService = activityManagerService;
2594 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2595 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2596 "meminfo", pw)) return;
2597 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2601 static class GraphicsBinder extends Binder {
2602 ActivityManagerService mActivityManagerService;
2603 GraphicsBinder(ActivityManagerService activityManagerService) {
2604 mActivityManagerService = activityManagerService;
2608 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2609 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2610 "gfxinfo", pw)) return;
2611 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2615 static class DbBinder extends Binder {
2616 ActivityManagerService mActivityManagerService;
2617 DbBinder(ActivityManagerService activityManagerService) {
2618 mActivityManagerService = activityManagerService;
2622 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2623 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2624 "dbinfo", pw)) return;
2625 mActivityManagerService.dumpDbInfo(fd, pw, args);
2629 static class CpuBinder extends Binder {
2630 ActivityManagerService mActivityManagerService;
2631 CpuBinder(ActivityManagerService activityManagerService) {
2632 mActivityManagerService = activityManagerService;
2636 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2637 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2638 "cpuinfo", pw)) return;
2639 synchronized (mActivityManagerService.mProcessCpuTracker) {
2640 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2641 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2642 SystemClock.uptimeMillis()));
2647 public static final class Lifecycle extends SystemService {
2648 private final ActivityManagerService mService;
2650 public Lifecycle(Context context) {
2652 mService = new ActivityManagerService(context);
2656 public void onStart() {
2661 public void onCleanupUser(int userId) {
2662 mService.mBatteryStatsService.onCleanupUser(userId);
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(systemContext, 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();
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;
3008 if (pr.lastCpuTime == 0) {
3009 pr.lastCpuTime = pr.curCpuTime;
3012 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3013 if (ps == null || !ps.isActive()) {
3014 st.batteryStats = ps = bstats.getProcessStatsLocked(
3015 bstats.mapUid(st.uid), st.name);
3017 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3020 final int userTime = mProcessCpuTracker.getLastUserTime();
3021 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3022 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3023 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3024 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3025 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3026 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3027 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3032 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3033 mLastWriteTime = now;
3034 mBatteryStatsService.scheduleWriteToDisk();
3041 public void batteryNeedsCpuUpdate() {
3042 updateCpuStatsNow();
3046 public void batteryPowerChanged(boolean onBattery) {
3047 // When plugging in, update the CPU stats first before changing
3049 updateCpuStatsNow();
3050 synchronized (this) {
3051 synchronized(mPidsSelfLocked) {
3052 mOnBattery = DEBUG_POWER ? true : onBattery;
3058 public void batterySendBroadcast(Intent intent) {
3059 synchronized (this) {
3060 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3061 AppOpsManager.OP_NONE, null, false, false,
3062 -1, SYSTEM_UID, UserHandle.USER_ALL);
3067 * Initialize the application bind args. These are passed to each
3068 * process when the bindApplication() IPC is sent to the process. They're
3069 * lazily setup to make sure the services are running when they're asked for.
3071 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3072 // Isolated processes won't get this optimization, so that we don't
3073 // violate the rules about which services they have access to.
3075 if (mIsolatedAppBindArgs == null) {
3076 mIsolatedAppBindArgs = new HashMap<>();
3077 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3079 return mIsolatedAppBindArgs;
3082 if (mAppBindArgs == null) {
3083 mAppBindArgs = new HashMap<>();
3085 // Setup the application init args
3086 mAppBindArgs.put("package", ServiceManager.getService("package"));
3087 mAppBindArgs.put("window", ServiceManager.getService("window"));
3088 mAppBindArgs.put(Context.ALARM_SERVICE,
3089 ServiceManager.getService(Context.ALARM_SERVICE));
3091 return mAppBindArgs;
3095 * Update AMS states when an activity is resumed. This should only be called by
3096 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3098 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3099 final TaskRecord task = r.getTask();
3100 if (task.isApplicationTask()) {
3101 if (mCurAppTimeTracker != r.appTimeTracker) {
3102 // We are switching app tracking. Complete the current one.
3103 if (mCurAppTimeTracker != null) {
3104 mCurAppTimeTracker.stop();
3105 mHandler.obtainMessage(
3106 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3107 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3108 mCurAppTimeTracker = null;
3110 if (r.appTimeTracker != null) {
3111 mCurAppTimeTracker = r.appTimeTracker;
3112 startTimeTrackingFocusedActivityLocked();
3115 startTimeTrackingFocusedActivityLocked();
3118 r.appTimeTracker = null;
3120 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3121 // TODO: Probably not, because we don't want to resume voice on switching
3122 // back to this activity
3123 if (task.voiceInteractor != null) {
3124 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3126 finishRunningVoiceLocked();
3128 if (mLastResumedActivity != null) {
3129 final IVoiceInteractionSession session;
3131 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3132 if (lastResumedActivityTask != null
3133 && lastResumedActivityTask.voiceSession != null) {
3134 session = lastResumedActivityTask.voiceSession;
3136 session = mLastResumedActivity.voiceSession;
3139 if (session != null) {
3140 // We had been in a voice interaction session, but now focused has
3141 // move to something different. Just finish the session, we can't
3142 // return to it and retain the proper state and synchronization with
3143 // the voice interaction service.
3144 finishVoiceTask(session);
3149 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3150 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3151 mHandler.obtainMessage(
3152 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3154 mLastResumedActivity = r;
3156 mWindowManager.setFocusedApp(r.appToken, true);
3158 applyUpdateLockStateLocked(r);
3159 applyUpdateVrModeLocked(r);
3161 EventLogTags.writeAmSetResumedActivity(
3162 r == null ? -1 : r.userId,
3163 r == null ? "NULL" : r.shortComponentName,
3168 public void setFocusedStack(int stackId) {
3169 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3170 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3171 final long callingId = Binder.clearCallingIdentity();
3173 synchronized (this) {
3174 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3175 if (stack == null) {
3178 final ActivityRecord r = stack.topRunningActivityLocked();
3179 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3180 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3184 Binder.restoreCallingIdentity(callingId);
3189 public void setFocusedTask(int taskId) {
3190 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3191 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3192 final long callingId = Binder.clearCallingIdentity();
3194 synchronized (this) {
3195 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3199 final ActivityRecord r = task.topRunningActivityLocked();
3200 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3201 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3205 Binder.restoreCallingIdentity(callingId);
3209 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3211 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3212 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3213 mTaskChangeNotificationController.registerTaskStackListener(listener);
3217 * Unregister a task stack listener so that it stops receiving callbacks.
3220 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3221 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3222 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3226 public void notifyActivityDrawn(IBinder token) {
3227 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3228 synchronized (this) {
3229 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3231 r.getStack().notifyActivityDrawnLocked(r);
3236 final void applyUpdateLockStateLocked(ActivityRecord r) {
3237 // Modifications to the UpdateLock state are done on our handler, outside
3238 // the activity manager's locks. The new state is determined based on the
3239 // state *now* of the relevant activity record. The object is passed to
3240 // the handler solely for logging detail, not to be consulted/modified.
3241 final boolean nextState = r != null && r.immersive;
3242 mHandler.sendMessage(
3243 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3246 final void applyUpdateVrModeLocked(ActivityRecord r) {
3247 // VR apps are expected to run in a main display. If an app is turning on VR for
3248 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3249 // fullscreen stack before enabling VR Mode.
3250 // TODO: The goal of this code is to keep the VR app on the main display. When the
3251 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3252 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3253 // option would be a better choice here.
3254 if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3255 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3256 + " to main stack for VR");
3257 moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3259 mHandler.sendMessage(
3260 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3263 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3264 mHandler.sendMessage(
3265 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3268 private void notifyVrManagerOfSleepState(boolean isSleeping) {
3269 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3270 if (vrService == null) {
3273 vrService.onSleepStateChanged(isSleeping);
3276 private void sendNotifyVrManagerOfKeyguardState(boolean isShowing) {
3277 mHandler.sendMessage(
3278 mHandler.obtainMessage(NOTIFY_VR_KEYGUARD_MSG, isShowing ? 1 : 0, 0));
3281 private void notifyVrManagerOfKeyguardState(boolean isShowing) {
3282 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3283 if (vrService == null) {
3286 vrService.onKeyguardStateChanged(isShowing);
3289 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3290 Message msg = Message.obtain();
3291 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3292 msg.obj = r.getTask().askedCompatMode ? null : r;
3293 mUiHandler.sendMessage(msg);
3296 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3297 final Configuration globalConfig = getGlobalConfiguration();
3298 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3299 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3300 final Message msg = Message.obtain();
3301 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3303 mUiHandler.sendMessage(msg);
3307 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3308 String what, Object obj, ProcessRecord srcApp) {
3309 app.lastActivityTime = now;
3311 if (app.activities.size() > 0) {
3312 // Don't want to touch dependent processes that are hosting activities.
3316 int lrui = mLruProcesses.lastIndexOf(app);
3318 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3319 + what + " " + obj + " from " + srcApp);
3323 if (lrui >= index) {
3324 // Don't want to cause this to move dependent processes *back* in the
3325 // list as if they were less frequently used.
3329 if (lrui >= mLruProcessActivityStart) {
3330 // Don't want to touch dependent processes that are hosting activities.
3334 mLruProcesses.remove(lrui);
3338 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3339 + " in LRU list: " + app);
3340 mLruProcesses.add(index, app);
3344 static void killProcessGroup(int uid, int pid) {
3345 if (sKillHandler != null) {
3346 sKillHandler.sendMessage(
3347 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3349 Slog.w(TAG, "Asked to kill process group before system bringup!");
3350 Process.killProcessGroup(uid, pid);
3354 final void removeLruProcessLocked(ProcessRecord app) {
3355 int lrui = mLruProcesses.lastIndexOf(app);
3358 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3359 killProcessQuiet(app.pid);
3360 killProcessGroup(app.uid, app.pid);
3362 if (lrui <= mLruProcessActivityStart) {
3363 mLruProcessActivityStart--;
3365 if (lrui <= mLruProcessServiceStart) {
3366 mLruProcessServiceStart--;
3368 mLruProcesses.remove(lrui);
3372 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3373 ProcessRecord client) {
3374 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3375 || app.treatLikeActivity;
3376 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3377 if (!activityChange && hasActivity) {
3378 // The process has activities, so we are only allowing activity-based adjustments
3379 // to move it. It should be kept in the front of the list with other
3380 // processes that have activities, and we don't want those to change their
3381 // order except due to activity operations.
3386 final long now = SystemClock.uptimeMillis();
3387 app.lastActivityTime = now;
3389 // First a quick reject: if the app is already at the position we will
3390 // put it, then there is nothing to do.
3392 final int N = mLruProcesses.size();
3393 if (N > 0 && mLruProcesses.get(N-1) == app) {
3394 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3398 if (mLruProcessServiceStart > 0
3399 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3400 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3405 int lrui = mLruProcesses.lastIndexOf(app);
3407 if (app.persistent && lrui >= 0) {
3408 // We don't care about the position of persistent processes, as long as
3409 // they are in the list.
3410 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3414 /* In progress: compute new position first, so we can avoid doing work
3415 if the process is not actually going to move. Not yet working.
3418 boolean inActivity = false, inService = false;
3420 // Process has activities, put it at the very tipsy-top.
3421 addIndex = mLruProcesses.size();
3422 nextIndex = mLruProcessServiceStart;
3424 } else if (hasService) {
3425 // Process has services, put it at the top of the service list.
3426 addIndex = mLruProcessActivityStart;
3427 nextIndex = mLruProcessServiceStart;
3431 // Process not otherwise of interest, it goes to the top of the non-service area.
3432 addIndex = mLruProcessServiceStart;
3433 if (client != null) {
3434 int clientIndex = mLruProcesses.lastIndexOf(client);
3435 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3437 if (clientIndex >= 0 && addIndex > clientIndex) {
3438 addIndex = clientIndex;
3441 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3444 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3445 + mLruProcessActivityStart + "): " + app);
3449 if (lrui < mLruProcessActivityStart) {
3450 mLruProcessActivityStart--;
3452 if (lrui < mLruProcessServiceStart) {
3453 mLruProcessServiceStart--;
3456 if (addIndex > lrui) {
3459 if (nextIndex > lrui) {
3463 mLruProcesses.remove(lrui);
3467 mLruProcesses.add(addIndex, app);
3469 mLruProcessActivityStart++;
3472 mLruProcessActivityStart++;
3478 final int N = mLruProcesses.size();
3479 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3480 // Process doesn't have activities, but has clients with
3481 // activities... move it up, but one below the top (the top
3482 // should always have a real activity).
3483 if (DEBUG_LRU) Slog.d(TAG_LRU,
3484 "Adding to second-top of LRU activity list: " + app);
3485 mLruProcesses.add(N - 1, app);
3486 // To keep it from spamming the LRU list (by making a bunch of clients),
3487 // we will push down any other entries owned by the app.
3488 final int uid = app.info.uid;
3489 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3490 ProcessRecord subProc = mLruProcesses.get(i);
3491 if (subProc.info.uid == uid) {
3492 // We want to push this one down the list. If the process after
3493 // it is for the same uid, however, don't do so, because we don't
3494 // want them internally to be re-ordered.
3495 if (mLruProcesses.get(i - 1).info.uid != uid) {
3496 if (DEBUG_LRU) Slog.d(TAG_LRU,
3497 "Pushing uid " + uid + " swapping at " + i + ": "
3498 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3499 ProcessRecord tmp = mLruProcesses.get(i);
3500 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3501 mLruProcesses.set(i - 1, tmp);
3505 // A gap, we can stop here.
3510 // Process has activities, put it at the very tipsy-top.
3511 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3512 mLruProcesses.add(app);
3514 nextIndex = mLruProcessServiceStart;
3515 } else if (hasService) {
3516 // Process has services, put it at the top of the service list.
3517 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3518 mLruProcesses.add(mLruProcessActivityStart, app);
3519 nextIndex = mLruProcessServiceStart;
3520 mLruProcessActivityStart++;
3522 // Process not otherwise of interest, it goes to the top of the non-service area.
3523 int index = mLruProcessServiceStart;
3524 if (client != null) {
3525 // If there is a client, don't allow the process to be moved up higher
3526 // in the list than that client.
3527 int clientIndex = mLruProcesses.lastIndexOf(client);
3528 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3529 + " when updating " + app);
3530 if (clientIndex <= lrui) {
3531 // Don't allow the client index restriction to push it down farther in the
3532 // list than it already is.
3535 if (clientIndex >= 0 && index > clientIndex) {
3536 index = clientIndex;
3539 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3540 mLruProcesses.add(index, app);
3541 nextIndex = index-1;
3542 mLruProcessActivityStart++;
3543 mLruProcessServiceStart++;
3546 // If the app is currently using a content provider or service,
3547 // bump those processes as well.
3548 for (int j=app.connections.size()-1; j>=0; j--) {
3549 ConnectionRecord cr = app.connections.valueAt(j);
3550 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3551 && cr.binding.service.app != null
3552 && cr.binding.service.app.lruSeq != mLruSeq
3553 && !cr.binding.service.app.persistent) {
3554 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3555 "service connection", cr, app);
3558 for (int j=app.conProviders.size()-1; j>=0; j--) {
3559 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3560 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3561 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3562 "provider reference", cpr, app);
3567 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3568 if (uid == SYSTEM_UID) {
3569 // The system gets to run in any process. If there are multiple
3570 // processes with the same uid, just pick the first (this
3571 // should never happen).
3572 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3573 if (procs == null) return null;
3574 final int procCount = procs.size();
3575 for (int i = 0; i < procCount; i++) {
3576 final int procUid = procs.keyAt(i);
3577 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)
3578 || UserHandle.isIsolated(procUid)) {
3579 // Don't use an app process or different user process for system component.
3582 return procs.valueAt(i);
3585 ProcessRecord proc = mProcessNames.get(processName, uid);
3586 if (false && proc != null && !keepIfLarge
3587 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3588 && proc.lastCachedPss >= 4000) {
3589 // Turn this condition on to cause killing to happen regularly, for testing.
3590 if (proc.baseProcessTracker != null) {
3591 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3593 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3594 } else if (proc != null && !keepIfLarge
3595 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3596 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3597 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3598 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3599 if (proc.baseProcessTracker != null) {
3600 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3602 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3608 void notifyPackageUse(String packageName, int reason) {
3609 synchronized(this) {
3610 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3614 boolean isNextTransitionForward() {
3615 int transit = mWindowManager.getPendingAppTransition();
3616 return transit == TRANSIT_ACTIVITY_OPEN
3617 || transit == TRANSIT_TASK_OPEN
3618 || transit == TRANSIT_TASK_TO_FRONT;
3621 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3622 String processName, String abiOverride, int uid, Runnable crashHandler) {
3623 synchronized(this) {
3624 ApplicationInfo info = new ApplicationInfo();
3625 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3626 // For isolated processes, the former contains the parent's uid and the latter the
3627 // actual uid of the isolated process.
3628 // In the special case introduced by this method (which is, starting an isolated
3629 // process directly from the SystemServer without an actual parent app process) the
3630 // closest thing to a parent's uid is SYSTEM_UID.
3631 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3632 // the |isolated| logic in the ProcessRecord constructor.
3633 info.uid = SYSTEM_UID;
3634 info.processName = processName;
3635 info.className = entryPoint;
3636 info.packageName = "android";
3637 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3638 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3639 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3640 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3641 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3643 return proc != null ? proc.pid : 0;
3647 final ProcessRecord startProcessLocked(String processName,
3648 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3649 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3650 boolean isolated, boolean keepIfLarge) {
3651 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3652 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3653 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3654 null /* crashHandler */);
3657 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3658 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3659 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3660 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3661 long startTime = SystemClock.elapsedRealtime();
3664 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3665 checkTime(startTime, "startProcess: after getProcessRecord");
3667 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3668 // If we are in the background, then check to see if this process
3669 // is bad. If so, we will just silently fail.
3670 if (mAppErrors.isBadProcessLocked(info)) {
3671 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3672 + "/" + info.processName);
3676 // When the user is explicitly starting a process, then clear its
3677 // crash count so that we won't make it bad until they see at
3678 // least one crash dialog again, and make the process good again
3679 // if it had been bad.
3680 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3681 + "/" + info.processName);
3682 mAppErrors.resetProcessCrashTimeLocked(info);
3683 if (mAppErrors.isBadProcessLocked(info)) {
3684 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3685 UserHandle.getUserId(info.uid), info.uid,
3687 mAppErrors.clearBadProcessLocked(info);
3694 // If this is an isolated process, it can't re-use an existing process.
3698 // We don't have to do anything more if:
3699 // (1) There is an existing application record; and
3700 // (2) The caller doesn't think it is dead, OR there is no thread
3701 // object attached to it so we know it couldn't have crashed; and
3702 // (3) There is a pid assigned to it, so it is either starting or
3704 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3705 + " app=" + app + " knownToBeDead=" + knownToBeDead
3706 + " thread=" + (app != null ? app.thread : null)
3707 + " pid=" + (app != null ? app.pid : -1));
3708 if (app != null && app.pid > 0) {
3709 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3710 // We already have the app running, or are waiting for it to
3711 // come up (we have a pid but not yet its thread), so keep it.
3712 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3713 // If this is a new package in the process, add the package to the list
3714 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3715 checkTime(startTime, "startProcess: done, added package to proc");
3719 // An application record is attached to a previous process,
3721 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3722 checkTime(startTime, "startProcess: bad proc running, killing");
3723 killProcessGroup(app.uid, app.pid);
3724 handleAppDiedLocked(app, true, true);
3725 checkTime(startTime, "startProcess: done killing old proc");
3728 String hostingNameStr = hostingName != null
3729 ? hostingName.flattenToShortString() : null;
3732 checkTime(startTime, "startProcess: creating new process record");
3733 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3735 Slog.w(TAG, "Failed making new process record for "
3736 + processName + "/" + info.uid + " isolated=" + isolated);
3739 app.crashHandler = crashHandler;
3740 checkTime(startTime, "startProcess: done creating new process record");
3742 // If this is a new package in the process, add the package to the list
3743 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3744 checkTime(startTime, "startProcess: added package to existing proc");
3747 // If the system is not ready yet, then hold off on starting this
3748 // process until it is.
3749 if (!mProcessesReady
3750 && !isAllowedWhileBooting(info)
3751 && !allowWhileBooting) {
3752 if (!mProcessesOnHold.contains(app)) {
3753 mProcessesOnHold.add(app);
3755 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3756 "System not ready, putting on hold: " + app);
3757 checkTime(startTime, "startProcess: returning with proc on hold");
3761 checkTime(startTime, "startProcess: stepping in to startProcess");
3763 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3764 checkTime(startTime, "startProcess: done starting proc!");
3765 return (app.pid != 0) ? app : null;
3768 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3769 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3772 private final void startProcessLocked(ProcessRecord app,
3773 String hostingType, String hostingNameStr) {
3774 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3775 null /* entryPoint */, null /* entryPointArgs */);
3778 private final void startProcessLocked(ProcessRecord app, String hostingType,
3779 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3780 long startTime = SystemClock.elapsedRealtime();
3781 if (app.pid > 0 && app.pid != MY_PID) {
3782 checkTime(startTime, "startProcess: removing from pids map");
3783 synchronized (mPidsSelfLocked) {
3784 mPidsSelfLocked.remove(app.pid);
3785 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3787 checkTime(startTime, "startProcess: done removing from pids map");
3791 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3792 "startProcessLocked removing on hold: " + app);
3793 mProcessesOnHold.remove(app);
3795 checkTime(startTime, "startProcess: starting to update cpu stats");
3797 checkTime(startTime, "startProcess: done updating cpu stats");
3801 final int userId = UserHandle.getUserId(app.uid);
3802 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3803 } catch (RemoteException e) {
3804 throw e.rethrowAsRuntimeException();
3809 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3810 if (!app.isolated) {
3811 int[] permGids = null;
3813 checkTime(startTime, "startProcess: getting gids from package manager");
3814 final IPackageManager pm = AppGlobals.getPackageManager();
3815 permGids = pm.getPackageGids(app.info.packageName,
3816 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3817 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3818 StorageManagerInternal.class);
3819 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3820 app.info.packageName);
3821 } catch (RemoteException e) {
3822 throw e.rethrowAsRuntimeException();
3826 * Add shared application and profile GIDs so applications can share some
3827 * resources like shared libraries and access user-wide resources
3829 if (ArrayUtils.isEmpty(permGids)) {
3832 gids = new int[permGids.length + 3];
3833 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3835 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3836 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3837 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3839 checkTime(startTime, "startProcess: building args");
3840 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3841 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3842 && mTopComponent != null
3843 && app.processName.equals(mTopComponent.getPackageName())) {
3846 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3847 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3852 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3853 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3854 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3855 // Also turn on CheckJNI for debuggable apps. It's quite
3856 // awkward to turn on otherwise.
3857 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3859 // Run the app in safe mode if its manifest requests so or the
3860 // system is booted in safe mode.
3861 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3862 mSafeMode == true) {
3863 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3865 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3866 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3868 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3869 if ("true".equals(genDebugInfoProperty)) {
3870 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3872 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3873 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3875 if ("1".equals(SystemProperties.get("debug.assert"))) {
3876 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3878 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3879 // Enable all debug flags required by the native debugger.
3880 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3881 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3882 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3883 mNativeDebuggingApp = null;
3886 String invokeWith = null;
3887 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3888 // Debuggable apps may include a wrapper script with their library directory.
3889 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3890 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3892 if (new File(wrapperFileName).exists()) {
3893 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3896 StrictMode.setThreadPolicy(oldPolicy);
3900 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3901 if (requiredAbi == null) {
3902 requiredAbi = Build.SUPPORTED_ABIS[0];
3905 String instructionSet = null;
3906 if (app.info.primaryCpuAbi != null) {
3907 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3911 app.requiredAbi = requiredAbi;
3912 app.instructionSet = instructionSet;
3914 // the per-user SELinux context must be set
3915 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3916 Slog.wtf(TAG, "SELinux tag not defined",
3917 new IllegalStateException("SELinux tag not defined for "
3918 + app.info.packageName + " (uid " + app.uid + ")"));
3920 final String seInfo = app.info.seInfo
3921 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3922 // Start the process. It will either succeed and return a result containing
3923 // the PID of the new process, or else throw a RuntimeException.
3924 boolean isActivityProcess = (entryPoint == null);
3925 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3926 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3928 checkTime(startTime, "startProcess: asking zygote to start proc");
3929 ProcessStartResult startResult;
3930 if (hostingType.equals("webview_service")) {
3931 startResult = startWebView(entryPoint,
3932 app.processName, uid, uid, gids, debugFlags, mountExternal,
3933 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3934 app.info.dataDir, null, entryPointArgs);
3936 startResult = Process.start(entryPoint,
3937 app.processName, uid, uid, gids, debugFlags, mountExternal,
3938 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3939 app.info.dataDir, invokeWith, entryPointArgs);
3941 checkTime(startTime, "startProcess: returned from zygote!");
3942 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3944 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3945 checkTime(startTime, "startProcess: done updating battery stats");
3947 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3948 UserHandle.getUserId(uid), startResult.pid, uid,
3949 app.processName, hostingType,
3950 hostingNameStr != null ? hostingNameStr : "");
3953 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3954 seInfo, app.info.sourceDir, startResult.pid);
3955 } catch (RemoteException ex) {
3959 if (app.persistent) {
3960 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3963 checkTime(startTime, "startProcess: building log message");
3964 StringBuilder buf = mStringBuilder;
3966 buf.append("Start proc ");
3967 buf.append(startResult.pid);
3969 buf.append(app.processName);
3971 UserHandle.formatUid(buf, uid);
3972 if (!isActivityProcess) {
3974 buf.append(entryPoint);
3977 buf.append(" for ");
3978 buf.append(hostingType);
3979 if (hostingNameStr != null) {
3981 buf.append(hostingNameStr);
3983 Slog.i(TAG, buf.toString());
3984 app.setPid(startResult.pid);
3985 app.usingWrapper = startResult.usingWrapper;
3986 app.removed = false;
3988 app.killedByAm = false;
3989 checkTime(startTime, "startProcess: starting to update pids map");
3990 ProcessRecord oldApp;
3991 synchronized (mPidsSelfLocked) {
3992 oldApp = mPidsSelfLocked.get(startResult.pid);
3994 // If there is already an app occupying that pid that hasn't been cleaned up
3995 if (oldApp != null && !app.isolated) {
3996 // Clean up anything relating to this pid first
3997 Slog.w(TAG, "Reusing pid " + startResult.pid
3998 + " while app is still mapped to it");
3999 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4000 true /*replacingPid*/);
4002 synchronized (mPidsSelfLocked) {
4003 this.mPidsSelfLocked.put(startResult.pid, app);
4004 if (isActivityProcess) {
4005 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4007 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4008 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4011 checkTime(startTime, "startProcess: done updating pids map");
4012 } catch (RuntimeException e) {
4013 Slog.e(TAG, "Failure starting process " + app.processName, e);
4015 // Something went very wrong while trying to start this process; one
4016 // common case is when the package is frozen due to an active
4017 // upgrade. To recover, clean up any active bookkeeping related to
4018 // starting this process. (We already invoked this method once when
4019 // the package was initially frozen through KILL_APPLICATION_MSG, so
4020 // it doesn't hurt to use it again.)
4021 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4022 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4026 void updateUsageStats(ActivityRecord component, boolean resumed) {
4027 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4028 "updateUsageStats: comp=" + component + "res=" + resumed);
4029 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4031 if (mUsageStatsService != null) {
4032 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4033 UsageEvents.Event.MOVE_TO_FOREGROUND);
4035 synchronized (stats) {
4036 stats.noteActivityResumedLocked(component.app.uid);
4039 if (mUsageStatsService != null) {
4040 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4041 UsageEvents.Event.MOVE_TO_BACKGROUND);
4043 synchronized (stats) {
4044 stats.noteActivityPausedLocked(component.app.uid);
4049 Intent getHomeIntent() {
4050 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4051 intent.setComponent(mTopComponent);
4052 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4053 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4054 intent.addCategory(Intent.CATEGORY_HOME);
4059 boolean startHomeActivityLocked(int userId, String reason) {
4060 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4061 && mTopAction == null) {
4062 // We are running in factory test mode, but unable to find
4063 // the factory test app, so just sit around displaying the
4064 // error message and don't try to start anything.
4067 Intent intent = getHomeIntent();
4068 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4069 if (aInfo != null) {
4070 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4071 // Don't do this if the home app is currently being
4073 aInfo = new ActivityInfo(aInfo);
4074 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4075 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4076 aInfo.applicationInfo.uid, true);
4077 if (app == null || app.instr == null) {
4078 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4079 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4080 // For ANR debugging to verify if the user activity is the one that actually
4082 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4083 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4086 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4092 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4093 ActivityInfo ai = null;
4094 ComponentName comp = intent.getComponent();
4098 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4100 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4102 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4106 ai = info.activityInfo;
4109 } catch (RemoteException e) {
4117 * Starts the "new version setup screen" if appropriate.
4119 void startSetupActivityLocked() {
4120 // Only do this once per boot.
4121 if (mCheckedForSetup) {
4125 // We will show this screen if the current one is a different
4126 // version than the last one shown, and we are not running in
4127 // low-level factory test mode.
4128 final ContentResolver resolver = mContext.getContentResolver();
4129 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4130 Settings.Global.getInt(resolver,
4131 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4132 mCheckedForSetup = true;
4134 // See if we should be showing the platform update setup UI.
4135 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4136 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4137 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4138 if (!ris.isEmpty()) {
4139 final ResolveInfo ri = ris.get(0);
4140 String vers = ri.activityInfo.metaData != null
4141 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4143 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4144 vers = ri.activityInfo.applicationInfo.metaData.getString(
4145 Intent.METADATA_SETUP_VERSION);
4147 String lastVers = Settings.Secure.getString(
4148 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4149 if (vers != null && !vers.equals(lastVers)) {
4150 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4151 intent.setComponent(new ComponentName(
4152 ri.activityInfo.packageName, ri.activityInfo.name));
4153 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4154 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4155 null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4161 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4162 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4165 void enforceNotIsolatedCaller(String caller) {
4166 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4167 throw new SecurityException("Isolated process not allowed to call " + caller);
4171 void enforceShellRestriction(String restriction, int userHandle) {
4172 if (Binder.getCallingUid() == SHELL_UID) {
4173 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4174 throw new SecurityException("Shell does not have permission to access user "
4181 public int getFrontActivityScreenCompatMode() {
4182 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4183 synchronized (this) {
4184 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4189 public void setFrontActivityScreenCompatMode(int mode) {
4190 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4191 "setFrontActivityScreenCompatMode");
4192 synchronized (this) {
4193 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4198 public int getPackageScreenCompatMode(String packageName) {
4199 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4200 synchronized (this) {
4201 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4206 public void setPackageScreenCompatMode(String packageName, int mode) {
4207 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4208 "setPackageScreenCompatMode");
4209 synchronized (this) {
4210 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4215 public boolean getPackageAskScreenCompat(String packageName) {
4216 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4217 synchronized (this) {
4218 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4223 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4224 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4225 "setPackageAskScreenCompat");
4226 synchronized (this) {
4227 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4231 private boolean hasUsageStatsPermission(String callingPackage) {
4232 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4233 Binder.getCallingUid(), callingPackage);
4234 if (mode == AppOpsManager.MODE_DEFAULT) {
4235 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4236 == PackageManager.PERMISSION_GRANTED;
4238 return mode == AppOpsManager.MODE_ALLOWED;
4242 public int getPackageProcessState(String packageName, String callingPackage) {
4243 if (!hasUsageStatsPermission(callingPackage)) {
4244 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4245 "getPackageProcessState");
4248 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4249 synchronized (this) {
4250 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4251 final ProcessRecord proc = mLruProcesses.get(i);
4252 if (procState > proc.setProcState) {
4253 if (proc.pkgList.containsKey(packageName) ||
4254 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4255 procState = proc.setProcState;
4264 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4265 throws RemoteException {
4266 synchronized (this) {
4267 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4269 throw new IllegalArgumentException("Unknown process: " + process);
4271 if (app.thread == null) {
4272 throw new IllegalArgumentException("Process has no app thread");
4274 if (app.trimMemoryLevel >= level) {
4275 throw new IllegalArgumentException(
4276 "Unable to set a higher trim level than current level");
4278 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4279 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4280 throw new IllegalArgumentException("Unable to set a background trim level "
4281 + "on a foreground process");
4283 app.thread.scheduleTrimMemory(level);
4284 app.trimMemoryLevel = level;
4289 private void dispatchProcessesChanged() {
4291 synchronized (this) {
4292 N = mPendingProcessChanges.size();
4293 if (mActiveProcessChanges.length < N) {
4294 mActiveProcessChanges = new ProcessChangeItem[N];
4296 mPendingProcessChanges.toArray(mActiveProcessChanges);
4297 mPendingProcessChanges.clear();
4298 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4299 "*** Delivering " + N + " process changes");
4302 int i = mProcessObservers.beginBroadcast();
4305 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4306 if (observer != null) {
4308 for (int j=0; j<N; j++) {
4309 ProcessChangeItem item = mActiveProcessChanges[j];
4310 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4311 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4312 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4313 + item.uid + ": " + item.foregroundActivities);
4314 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4315 item.foregroundActivities);
4318 } catch (RemoteException e) {
4322 mProcessObservers.finishBroadcast();
4324 synchronized (this) {
4325 for (int j=0; j<N; j++) {
4326 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4331 private void dispatchProcessDied(int pid, int uid) {
4332 int i = mProcessObservers.beginBroadcast();
4335 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4336 if (observer != null) {
4338 observer.onProcessDied(pid, uid);
4339 } catch (RemoteException e) {
4343 mProcessObservers.finishBroadcast();
4347 void dispatchUidsChanged() {
4349 synchronized (this) {
4350 N = mPendingUidChanges.size();
4351 if (mActiveUidChanges.length < N) {
4352 mActiveUidChanges = new UidRecord.ChangeItem[N];
4354 for (int i=0; i<N; i++) {
4355 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4356 mActiveUidChanges[i] = change;
4357 if (change.uidRecord != null) {
4358 change.uidRecord.pendingChange = null;
4359 change.uidRecord = null;
4362 mPendingUidChanges.clear();
4363 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4364 "*** Delivering " + N + " uid changes");
4367 int i = mUidObservers.beginBroadcast();
4370 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4371 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4373 mUidObservers.finishBroadcast();
4375 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4376 for (int j = 0; j < N; ++j) {
4377 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4378 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4379 mValidateUids.remove(item.uid);
4381 UidRecord validateUid = mValidateUids.get(item.uid);
4382 if (validateUid == null) {
4383 validateUid = new UidRecord(item.uid);
4384 mValidateUids.put(item.uid, validateUid);
4386 if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4387 validateUid.idle = true;
4388 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4389 validateUid.idle = false;
4391 validateUid.curProcState = validateUid.setProcState = item.processState;
4392 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4397 synchronized (this) {
4398 for (int j = 0; j < N; j++) {
4399 mAvailUidChanges.add(mActiveUidChanges[j]);
4404 private void dispatchUidsChangedForObserver(IUidObserver observer,
4405 UidObserverRegistration reg, int changesSize) {
4406 if (observer == null) {
4410 for (int j = 0; j < changesSize; j++) {
4411 UidRecord.ChangeItem item = mActiveUidChanges[j];
4412 final int change = item.change;
4413 if (change == UidRecord.CHANGE_PROCSTATE &&
4414 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4415 // No-op common case: no significant change, the observer is not
4416 // interested in all proc state changes.
4419 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4420 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4421 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422 "UID idle uid=" + item.uid);
4423 observer.onUidIdle(item.uid, item.ephemeral);
4425 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4426 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4427 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4428 "UID active uid=" + item.uid);
4429 observer.onUidActive(item.uid);
4432 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4433 if ((change & UidRecord.CHANGE_CACHED) != 0) {
4434 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4435 "UID cached uid=" + item.uid);
4436 observer.onUidCachedChanged(item.uid, true);
4437 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4438 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4439 "UID active uid=" + item.uid);
4440 observer.onUidCachedChanged(item.uid, false);
4443 if ((change & UidRecord.CHANGE_GONE) != 0) {
4444 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4445 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4446 "UID gone uid=" + item.uid);
4447 observer.onUidGone(item.uid, item.ephemeral);
4449 if (reg.lastProcStates != null) {
4450 reg.lastProcStates.delete(item.uid);
4453 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4454 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4455 "UID CHANGED uid=" + item.uid
4456 + ": " + item.processState);
4457 boolean doReport = true;
4458 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4459 final int lastState = reg.lastProcStates.get(item.uid,
4460 ActivityManager.PROCESS_STATE_UNKNOWN);
4461 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4462 final boolean lastAboveCut = lastState <= reg.cutpoint;
4463 final boolean newAboveCut = item.processState <= reg.cutpoint;
4464 doReport = lastAboveCut != newAboveCut;
4466 doReport = item.processState
4467 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4471 if (reg.lastProcStates != null) {
4472 reg.lastProcStates.put(item.uid, item.processState);
4474 observer.onUidStateChanged(item.uid, item.processState,
4480 } catch (RemoteException e) {
4484 void dispatchOomAdjObserver(String msg) {
4485 OomAdjObserver observer;
4486 synchronized (this) {
4487 observer = mCurOomAdjObserver;
4490 if (observer != null) {
4491 observer.onOomAdjMessage(msg);
4495 void setOomAdjObserver(int uid, OomAdjObserver observer) {
4496 synchronized (this) {
4497 mCurOomAdjUid = uid;
4498 mCurOomAdjObserver = observer;
4502 void clearOomAdjObserver() {
4503 synchronized (this) {
4505 mCurOomAdjObserver = null;
4509 void reportOomAdjMessageLocked(String tag, String msg) {
4511 if (mCurOomAdjObserver != null) {
4512 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4517 public final int startActivity(IApplicationThread caller, String callingPackage,
4518 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4519 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4520 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4521 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4522 UserHandle.getCallingUserId());
4526 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4527 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4528 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4529 enforceNotIsolatedCaller("startActivity");
4530 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4531 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4532 // TODO: Switch to user app stacks here.
4533 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4534 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4535 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4539 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4540 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4541 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4544 // This is very dangerous -- it allows you to perform a start activity (including
4545 // permission grants) as any app that may launch one of your own activities. So
4546 // we will only allow this to be done from activities that are part of the core framework,
4547 // and then only when they are running as the system.
4548 final ActivityRecord sourceRecord;
4549 final int targetUid;
4550 final String targetPackage;
4551 synchronized (this) {
4552 if (resultTo == null) {
4553 throw new SecurityException("Must be called from an activity");
4555 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4556 if (sourceRecord == null) {
4557 throw new SecurityException("Called with bad activity token: " + resultTo);
4559 if (!sourceRecord.info.packageName.equals("android")) {
4560 throw new SecurityException(
4561 "Must be called from an activity that is declared in the android package");
4563 if (sourceRecord.app == null) {
4564 throw new SecurityException("Called without a process attached to activity");
4566 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4567 // This is still okay, as long as this activity is running under the
4568 // uid of the original calling activity.
4569 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4570 throw new SecurityException(
4571 "Calling activity in uid " + sourceRecord.app.uid
4572 + " must be system uid or original calling uid "
4573 + sourceRecord.launchedFromUid);
4576 if (ignoreTargetSecurity) {
4577 if (intent.getComponent() == null) {
4578 throw new SecurityException(
4579 "Component must be specified with ignoreTargetSecurity");
4581 if (intent.getSelector() != null) {
4582 throw new SecurityException(
4583 "Selector not allowed with ignoreTargetSecurity");
4586 targetUid = sourceRecord.launchedFromUid;
4587 targetPackage = sourceRecord.launchedFromPackage;
4590 if (userId == UserHandle.USER_NULL) {
4591 userId = UserHandle.getUserId(sourceRecord.app.uid);
4594 // TODO: Switch to user app stacks here.
4596 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4597 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4598 null, null, bOptions, ignoreTargetSecurity, userId, null,
4599 "startActivityAsCaller");
4601 } catch (SecurityException e) {
4602 // XXX need to figure out how to propagate to original app.
4603 // A SecurityException here is generally actually a fault of the original
4604 // calling activity (such as a fairly granting permissions), so propagate it
4607 StringBuilder msg = new StringBuilder();
4608 msg.append("While launching");
4609 msg.append(intent.toString());
4611 msg.append(e.getMessage());
4618 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4619 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4620 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4621 enforceNotIsolatedCaller("startActivityAndWait");
4622 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4623 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4624 WaitResult res = new WaitResult();
4625 // TODO: Switch to user app stacks here.
4626 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4627 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4628 bOptions, false, userId, null, "startActivityAndWait");
4633 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4634 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4635 int startFlags, Configuration config, Bundle bOptions, int userId) {
4636 enforceNotIsolatedCaller("startActivityWithConfig");
4637 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4638 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4639 // TODO: Switch to user app stacks here.
4640 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4641 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4642 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4647 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4648 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4649 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4650 throws TransactionTooLargeException {
4651 enforceNotIsolatedCaller("startActivityIntentSender");
4652 // Refuse possible leaked file descriptors
4653 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4654 throw new IllegalArgumentException("File descriptors passed in Intent");
4657 if (!(target instanceof PendingIntentRecord)) {
4658 throw new IllegalArgumentException("Bad PendingIntent object");
4661 PendingIntentRecord pir = (PendingIntentRecord)target;
4663 synchronized (this) {
4664 // If this is coming from the currently resumed activity, it is
4665 // effectively saying that app switches are allowed at this point.
4666 final ActivityStack stack = getFocusedStack();
4667 if (stack.mResumedActivity != null &&
4668 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4669 mAppSwitchesAllowedTime = 0;
4672 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4673 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4678 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4679 Intent intent, String resolvedType, IVoiceInteractionSession session,
4680 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4681 Bundle bOptions, int userId) {
4682 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4683 != PackageManager.PERMISSION_GRANTED) {
4684 String msg = "Permission Denial: startVoiceActivity() from pid="
4685 + Binder.getCallingPid()
4686 + ", uid=" + Binder.getCallingUid()
4687 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4689 throw new SecurityException(msg);
4691 if (session == null || interactor == null) {
4692 throw new NullPointerException("null session or interactor");
4694 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4695 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4696 // TODO: Switch to user app stacks here.
4697 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4698 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4699 null, bOptions, false, userId, null, "startVoiceActivity");
4703 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4704 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4705 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4706 != PackageManager.PERMISSION_GRANTED) {
4707 final String msg = "Permission Denial: startAssistantActivity() from pid="
4708 + Binder.getCallingPid()
4709 + ", uid=" + Binder.getCallingUid()
4710 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4712 throw new SecurityException(msg);
4714 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4715 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4716 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4717 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4718 userId, null, "startAssistantActivity");
4722 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4723 throws RemoteException {
4724 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4725 synchronized (this) {
4726 ActivityRecord activity = getFocusedStack().topActivity();
4727 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4728 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4730 if (mRunningVoice != null || activity.getTask().voiceSession != null
4731 || activity.voiceSession != null) {
4732 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4735 if (activity.pendingVoiceInteractionStart) {
4736 Slog.w(TAG, "Pending start of voice interaction already.");
4739 activity.pendingVoiceInteractionStart = true;
4741 LocalServices.getService(VoiceInteractionManagerInternal.class)
4742 .startLocalVoiceInteraction(callingActivity, options);
4746 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4747 LocalServices.getService(VoiceInteractionManagerInternal.class)
4748 .stopLocalVoiceInteraction(callingActivity);
4752 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4753 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4754 .supportsLocalVoiceInteraction();
4757 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4758 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4759 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4760 if (activityToCallback == null) return;
4761 activityToCallback.setVoiceSessionLocked(voiceSession);
4763 // Inform the activity
4765 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4767 long token = Binder.clearCallingIdentity();
4769 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4771 Binder.restoreCallingIdentity(token);
4773 // TODO: VI Should we cache the activity so that it's easier to find later
4774 // rather than scan through all the stacks and activities?
4775 } catch (RemoteException re) {
4776 activityToCallback.clearVoiceSessionLocked();
4777 // TODO: VI Should this terminate the voice session?
4782 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4783 synchronized (this) {
4784 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4786 mVoiceWakeLock.acquire();
4788 mVoiceWakeLock.release();
4795 public boolean startNextMatchingActivity(IBinder callingActivity,
4796 Intent intent, Bundle bOptions) {
4797 // Refuse possible leaked file descriptors
4798 if (intent != null && intent.hasFileDescriptors() == true) {
4799 throw new IllegalArgumentException("File descriptors passed in Intent");
4801 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4803 synchronized (this) {
4804 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4806 ActivityOptions.abort(options);
4809 if (r.app == null || r.app.thread == null) {
4810 // The caller is not running... d'oh!
4811 ActivityOptions.abort(options);
4814 intent = new Intent(intent);
4815 // The caller is not allowed to change the data.
4816 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4817 // And we are resetting to find the next component...
4818 intent.setComponent(null);
4820 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4822 ActivityInfo aInfo = null;
4824 List<ResolveInfo> resolves =
4825 AppGlobals.getPackageManager().queryIntentActivities(
4826 intent, r.resolvedType,
4827 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4828 UserHandle.getCallingUserId()).getList();
4830 // Look for the original activity in the list...
4831 final int N = resolves != null ? resolves.size() : 0;
4832 for (int i=0; i<N; i++) {
4833 ResolveInfo rInfo = resolves.get(i);
4834 if (rInfo.activityInfo.packageName.equals(r.packageName)
4835 && rInfo.activityInfo.name.equals(r.info.name)) {
4836 // We found the current one... the next matching is
4840 aInfo = resolves.get(i).activityInfo;
4843 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4844 + "/" + r.info.name);
4845 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4846 ? "null" : aInfo.packageName + "/" + aInfo.name));
4851 } catch (RemoteException e) {
4854 if (aInfo == null) {
4855 // Nobody who is next!
4856 ActivityOptions.abort(options);
4857 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4861 intent.setComponent(new ComponentName(
4862 aInfo.applicationInfo.packageName, aInfo.name));
4863 intent.setFlags(intent.getFlags()&~(
4864 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4865 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4866 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4867 Intent.FLAG_ACTIVITY_NEW_TASK));
4869 // Okay now we need to start the new activity, replacing the
4870 // currently running activity. This is a little tricky because
4871 // we want to start the new one as if the current one is finished,
4872 // but not finish the current one first so that there is no flicker.
4874 final boolean wasFinishing = r.finishing;
4877 // Propagate reply information over to the new activity.
4878 final ActivityRecord resultTo = r.resultTo;
4879 final String resultWho = r.resultWho;
4880 final int requestCode = r.requestCode;
4882 if (resultTo != null) {
4883 resultTo.removeResultsLocked(r, resultWho, requestCode);
4886 final long origId = Binder.clearCallingIdentity();
4887 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4888 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4889 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4890 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4891 false, false, null, null, "startNextMatchingActivity");
4892 Binder.restoreCallingIdentity(origId);
4894 r.finishing = wasFinishing;
4895 if (res != ActivityManager.START_SUCCESS) {
4903 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4904 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4905 String msg = "Permission Denial: startActivityFromRecents called without " +
4906 START_TASKS_FROM_RECENTS;
4908 throw new SecurityException(msg);
4910 final long origId = Binder.clearCallingIdentity();
4912 synchronized (this) {
4913 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4916 Binder.restoreCallingIdentity(origId);
4920 final int startActivityInPackage(int uid, String callingPackage,
4921 Intent intent, String resolvedType, IBinder resultTo,
4922 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4923 TaskRecord inTask, String reason) {
4925 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4926 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4928 // TODO: Switch to user app stacks here.
4929 return mActivityStarter.startActivityMayWait(null, uid, ActivityStarter.PID_NULL, uid,
4930 callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode,
4931 startFlags, null, null, null, bOptions, false, userId, inTask, reason);
4935 public final int startActivities(IApplicationThread caller, String callingPackage,
4936 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4938 final String reason = "startActivities";
4939 enforceNotIsolatedCaller(reason);
4940 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4941 userId, false, ALLOW_FULL_ONLY, reason, null);
4942 // TODO: Switch to user app stacks here.
4943 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4944 resolvedTypes, resultTo, bOptions, userId, reason);
4948 final int startActivitiesInPackage(int uid, String callingPackage,
4949 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4950 Bundle bOptions, int userId) {
4951 return startActivitiesInPackage(uid, ActivityStarter.PID_NULL, UserHandle.USER_NULL,
4952 callingPackage, intents, resolvedTypes, resultTo, bOptions, userId);
4955 final int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid,
4956 String callingPackage, Intent[] intents, String[] resolvedTypes,
4957 IBinder resultTo, Bundle bOptions, int userId) {
4959 final String reason = "startActivityInPackage";
4960 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4961 userId, false, ALLOW_FULL_ONLY, reason, null);
4962 // TODO: Switch to user app stacks here.
4963 int ret = mActivityStarter.startActivities(null, uid, realCallingPid, realCallingUid,
4964 callingPackage, intents, resolvedTypes, resultTo, bOptions, userId, reason);
4969 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4970 synchronized (this) {
4971 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4975 r.reportFullyDrawnLocked(restoredFromBundle);
4980 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4981 synchronized (this) {
4982 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4986 final long origId = Binder.clearCallingIdentity();
4988 r.setRequestedOrientation(requestedOrientation);
4990 Binder.restoreCallingIdentity(origId);
4996 public int getRequestedOrientation(IBinder token) {
4997 synchronized (this) {
4998 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5000 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5002 return r.getRequestedOrientation();
5007 public final void requestActivityRelaunch(IBinder token) {
5008 synchronized(this) {
5009 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5013 final long origId = Binder.clearCallingIdentity();
5015 r.forceNewConfig = true;
5016 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5017 true /* preserveWindow */);
5019 Binder.restoreCallingIdentity(origId);
5025 * This is the internal entry point for handling Activity.finish().
5027 * @param token The Binder token referencing the Activity we want to finish.
5028 * @param resultCode Result code, if any, from this Activity.
5029 * @param resultData Result data (Intent), if any, from this Activity.
5030 * @param finishTask Whether to finish the task associated with this Activity.
5032 * @return Returns true if the activity successfully finished, or false if it is still running.
5035 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5037 // Refuse possible leaked file descriptors
5038 if (resultData != null && resultData.hasFileDescriptors() == true) {
5039 throw new IllegalArgumentException("File descriptors passed in Intent");
5042 synchronized(this) {
5043 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5047 // Keep track of the root activity of the task before we finish it
5048 TaskRecord tr = r.getTask();
5049 ActivityRecord rootR = tr.getRootActivity();
5050 if (rootR == null) {
5051 Slog.w(TAG, "Finishing task with all activities already finished");
5053 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5055 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5056 mStackSupervisor.isLastLockedTask(tr)) {
5057 Slog.i(TAG, "Not finishing task in lock task mode");
5058 mStackSupervisor.showLockTaskToast();
5061 if (mController != null) {
5062 // Find the first activity that is not finishing.
5063 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5065 // ask watcher if this is allowed
5066 boolean resumeOK = true;
5068 resumeOK = mController.activityResuming(next.packageName);
5069 } catch (RemoteException e) {
5071 Watchdog.getInstance().setActivityController(null);
5075 Slog.i(TAG, "Not finishing activity because controller resumed");
5080 final long origId = Binder.clearCallingIdentity();
5083 final boolean finishWithRootActivity =
5084 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5085 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5086 || (finishWithRootActivity && r == rootR)) {
5087 // If requested, remove the task that is associated to this activity only if it
5088 // was the root activity in the task. The result code and data is ignored
5089 // because we don't support returning them across task boundaries. Also, to
5090 // keep backwards compatibility we remove the task from recents when finishing
5091 // task with root activity.
5092 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5094 Slog.i(TAG, "Removing task failed to finish activity");
5097 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5098 resultData, "app-request", true);
5100 Slog.i(TAG, "Failed to finish by app-request");
5105 Binder.restoreCallingIdentity(origId);
5111 public final void finishHeavyWeightApp() {
5112 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5113 != PackageManager.PERMISSION_GRANTED) {
5114 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5115 + Binder.getCallingPid()
5116 + ", uid=" + Binder.getCallingUid()
5117 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5119 throw new SecurityException(msg);
5122 synchronized(this) {
5123 if (mHeavyWeightProcess == null) {
5127 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5128 for (int i = 0; i < activities.size(); i++) {
5129 ActivityRecord r = activities.get(i);
5130 if (!r.finishing && r.isInStackLocked()) {
5131 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5132 null, "finish-heavy", true);
5136 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5137 mHeavyWeightProcess.userId, 0));
5138 mHeavyWeightProcess = null;
5143 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5145 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5146 != PackageManager.PERMISSION_GRANTED) {
5147 String msg = "Permission Denial: crashApplication() from pid="
5148 + Binder.getCallingPid()
5149 + ", uid=" + Binder.getCallingUid()
5150 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5152 throw new SecurityException(msg);
5155 synchronized(this) {
5156 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5161 public final void finishSubActivity(IBinder token, String resultWho,
5163 synchronized(this) {
5164 final long origId = Binder.clearCallingIdentity();
5165 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5167 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5169 Binder.restoreCallingIdentity(origId);
5174 public boolean finishActivityAffinity(IBinder token) {
5175 synchronized(this) {
5176 final long origId = Binder.clearCallingIdentity();
5178 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5183 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5185 final TaskRecord task = r.getTask();
5186 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5187 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5188 mStackSupervisor.showLockTaskToast();
5191 return task.getStack().finishActivityAffinityLocked(r);
5193 Binder.restoreCallingIdentity(origId);
5199 public void finishVoiceTask(IVoiceInteractionSession session) {
5200 synchronized (this) {
5201 final long origId = Binder.clearCallingIdentity();
5203 // TODO: VI Consider treating local voice interactions and voice tasks
5205 mStackSupervisor.finishVoiceTask(session);
5207 Binder.restoreCallingIdentity(origId);
5214 public boolean releaseActivityInstance(IBinder token) {
5215 synchronized(this) {
5216 final long origId = Binder.clearCallingIdentity();
5218 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5222 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5224 Binder.restoreCallingIdentity(origId);
5230 public void releaseSomeActivities(IApplicationThread appInt) {
5231 synchronized(this) {
5232 final long origId = Binder.clearCallingIdentity();
5234 ProcessRecord app = getRecordForAppLocked(appInt);
5235 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5237 Binder.restoreCallingIdentity(origId);
5243 public boolean willActivityBeVisible(IBinder token) {
5244 synchronized(this) {
5245 ActivityStack stack = ActivityRecord.getStackLocked(token);
5246 if (stack != null) {
5247 return stack.willActivityBeVisibleLocked(token);
5254 public void overridePendingTransition(IBinder token, String packageName,
5255 int enterAnim, int exitAnim) {
5256 synchronized(this) {
5257 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5262 final long origId = Binder.clearCallingIdentity();
5264 if (self.state == ActivityState.RESUMED
5265 || self.state == ActivityState.PAUSING) {
5266 mWindowManager.overridePendingAppTransition(packageName,
5267 enterAnim, exitAnim, null);
5270 Binder.restoreCallingIdentity(origId);
5275 * Main function for removing an existing process from the activity manager
5276 * as a result of that process going away. Clears out all connections
5279 private final void handleAppDiedLocked(ProcessRecord app,
5280 boolean restarting, boolean allowRestart) {
5282 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5283 false /*replacingPid*/);
5284 if (!kept && !restarting) {
5285 removeLruProcessLocked(app);
5287 ProcessList.remove(pid);
5291 if (mProfileProc == app) {
5292 clearProfilerLocked();
5295 // Remove this application's activities from active lists.
5296 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5298 app.activities.clear();
5300 if (app.instr != null) {
5301 Slog.w(TAG, "Crash of app " + app.processName
5302 + " running instrumentation " + app.instr.mClass);
5303 Bundle info = new Bundle();
5304 info.putString("shortMsg", "Process crashed.");
5305 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5308 mWindowManager.deferSurfaceLayout();
5310 if (!restarting && hasVisibleActivities
5311 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5312 // If there was nothing to resume, and we are not already restarting this process, but
5313 // there is a visible activity that is hosted by the process... then make sure all
5314 // visible activities are running, taking care of restarting this process.
5315 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5318 mWindowManager.continueSurfaceLayout();
5322 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5323 final IBinder threadBinder = thread.asBinder();
5324 // Find the application record.
5325 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5326 final ProcessRecord rec = mLruProcesses.get(i);
5327 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5334 final ProcessRecord getRecordForAppLocked(
5335 IApplicationThread thread) {
5336 if (thread == null) {
5340 int appIndex = getLRURecordIndexForAppLocked(thread);
5341 if (appIndex >= 0) {
5342 return mLruProcesses.get(appIndex);
5345 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5346 // double-check that.
5347 final IBinder threadBinder = thread.asBinder();
5348 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5349 for (int i = pmap.size()-1; i >= 0; i--) {
5350 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5351 for (int j = procs.size()-1; j >= 0; j--) {
5352 final ProcessRecord proc = procs.valueAt(j);
5353 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5354 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5364 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5365 // If there are no longer any background processes running,
5366 // and the app that died was not running instrumentation,
5367 // then tell everyone we are now low on memory.
5368 boolean haveBg = false;
5369 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5370 ProcessRecord rec = mLruProcesses.get(i);
5371 if (rec.thread != null
5372 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5379 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5381 long now = SystemClock.uptimeMillis();
5382 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5385 mLastMemUsageReportTime = now;
5388 final ArrayList<ProcessMemInfo> memInfos
5389 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5390 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5391 long now = SystemClock.uptimeMillis();
5392 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5393 ProcessRecord rec = mLruProcesses.get(i);
5394 if (rec == dyingProc || rec.thread == null) {
5398 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5399 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5401 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5402 // The low memory report is overriding any current
5403 // state for a GC request. Make sure to do
5404 // heavy/important/visible/foreground processes first.
5405 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5406 rec.lastRequestedGc = 0;
5408 rec.lastRequestedGc = rec.lastLowMemory;
5410 rec.reportLowMemory = true;
5411 rec.lastLowMemory = now;
5412 mProcessesToGc.remove(rec);
5413 addProcessToGcListLocked(rec);
5417 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5418 mHandler.sendMessage(msg);
5420 scheduleAppGcsLocked();
5424 final void appDiedLocked(ProcessRecord app) {
5425 appDiedLocked(app, app.pid, app.thread, false);
5428 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5429 boolean fromBinderDied) {
5430 // First check if this ProcessRecord is actually active for the pid.
5431 synchronized (mPidsSelfLocked) {
5432 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5433 if (curProc != app) {
5434 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5439 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5440 synchronized (stats) {
5441 stats.noteProcessDiedLocked(app.info.uid, pid);
5445 if (!fromBinderDied) {
5446 killProcessQuiet(pid);
5448 killProcessGroup(app.uid, pid);
5452 // Clean up already done if the process has been re-started.
5453 if (app.pid == pid && app.thread != null &&
5454 app.thread.asBinder() == thread.asBinder()) {
5455 boolean doLowMem = app.instr == null;
5456 boolean doOomAdj = doLowMem;
5457 if (!app.killedByAm) {
5458 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5459 + ProcessList.makeOomAdjString(app.setAdj)
5460 + ProcessList.makeProcStateString(app.setProcState));
5461 mAllowLowerMemLevel = true;
5463 // Note that we always want to do oom adj to update our state with the
5464 // new number of procs.
5465 mAllowLowerMemLevel = false;
5468 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5469 app.setAdj, app.setProcState);
5470 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5471 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5472 handleAppDiedLocked(app, false, true);
5475 updateOomAdjLocked();
5478 doLowMemReportIfNeededLocked(app);
5480 } else if (app.pid != pid) {
5481 // A new process has already been started.
5482 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5483 + ") has died and restarted (pid " + app.pid + ").");
5484 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5485 } else if (DEBUG_PROCESSES) {
5486 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5487 + thread.asBinder());
5492 * If a stack trace dump file is configured, dump process stack traces.
5493 * @param clearTraces causes the dump file to be erased prior to the new
5494 * traces being written, if true; when false, the new traces will be
5495 * appended to any existing file content.
5496 * @param firstPids of dalvik VM processes to dump stack traces for first
5497 * @param lastPids of dalvik VM processes to dump stack traces for last
5498 * @param nativePids optional list of native pids to dump stack crawls
5500 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5501 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5502 ArrayList<Integer> nativePids) {
5503 ArrayList<Integer> extraPids = null;
5505 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5506 // of the top users at the time of the request.
5507 if (processCpuTracker != null) {
5508 processCpuTracker.init();
5511 } catch (InterruptedException ignored) {
5514 processCpuTracker.update();
5516 // We'll take the stack crawls of just the top apps using CPU.
5517 final int N = processCpuTracker.countWorkingStats();
5518 extraPids = new ArrayList<>();
5519 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5520 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5521 if (lastPids.indexOfKey(stats.pid) >= 0) {
5522 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5524 extraPids.add(stats.pid);
5525 } else if (DEBUG_ANR) {
5526 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5532 boolean useTombstonedForJavaTraces = false;
5535 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5536 if (tracesDirProp.isEmpty()) {
5537 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5538 // dumping scheme. All traces are written to a global trace file (usually
5539 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5540 // the file if requested.
5542 // This mode of operation will be removed in the near future.
5545 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5546 if (globalTracesPath.isEmpty()) {
5547 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5551 tracesFile = new File(globalTracesPath);
5553 if (clearTraces && tracesFile.exists()) {
5554 tracesFile.delete();
5557 tracesFile.createNewFile();
5558 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5559 } catch (IOException e) {
5560 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5564 File tracesDir = new File(tracesDirProp);
5565 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5566 // Each set of ANR traces is written to a separate file and dumpstate will process
5567 // all such files and add them to a captured bug report if they're recent enough.
5568 maybePruneOldTraces(tracesDir);
5570 // NOTE: We should consider creating the file in native code atomically once we've
5571 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5573 tracesFile = createAnrDumpFile(tracesDir);
5574 if (tracesFile == null) {
5578 useTombstonedForJavaTraces = true;
5581 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5582 useTombstonedForJavaTraces);
5586 @GuardedBy("ActivityManagerService.class")
5587 private static SimpleDateFormat sAnrFileDateFormat;
5589 private static synchronized File createAnrDumpFile(File tracesDir) {
5590 if (sAnrFileDateFormat == null) {
5591 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5594 final String formattedDate = sAnrFileDateFormat.format(new Date());
5595 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5598 if (anrFile.createNewFile()) {
5599 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5602 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5604 } catch (IOException ioe) {
5605 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5612 * Prune all trace files that are more than a day old.
5614 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5615 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5616 * since it's the system_server that creates trace files for most ANRs.
5618 private static void maybePruneOldTraces(File tracesDir) {
5619 final long now = System.currentTimeMillis();
5620 final File[] traceFiles = tracesDir.listFiles();
5622 if (traceFiles != null) {
5623 for (File file : traceFiles) {
5624 if ((now - file.lastModified()) > DAY_IN_MILLIS) {
5625 if (!file.delete()) {
5626 Slog.w(TAG, "Unable to prune stale trace file: " + file);
5634 * Legacy code, do not use. Existing users will be deleted.
5639 public static class DumpStackFileObserver extends FileObserver {
5640 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5641 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5643 private final String mTracesPath;
5644 private boolean mClosed;
5646 public DumpStackFileObserver(String tracesPath) {
5647 super(tracesPath, FileObserver.CLOSE_WRITE);
5648 mTracesPath = tracesPath;
5652 public synchronized void onEvent(int event, String path) {
5657 public long dumpWithTimeout(int pid, long timeout) {
5658 sendSignal(pid, SIGNAL_QUIT);
5659 final long start = SystemClock.elapsedRealtime();
5661 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5662 synchronized (this) {
5664 wait(waitTime); // Wait for traces file to be closed.
5665 } catch (InterruptedException e) {
5670 // This avoids a corner case of passing a negative time to the native
5671 // trace in case we've already hit the overall timeout.
5672 final long timeWaited = SystemClock.elapsedRealtime() - start;
5673 if (timeWaited >= timeout) {
5678 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5679 ". Attempting native stack collection.");
5681 final long nativeDumpTimeoutMs = Math.min(
5682 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5684 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5685 (int) (nativeDumpTimeoutMs / 1000));
5688 final long end = SystemClock.elapsedRealtime();
5691 return (end - start);
5696 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5697 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5698 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5699 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5702 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5703 final long timeStart = SystemClock.elapsedRealtime();
5704 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5705 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5706 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5709 return SystemClock.elapsedRealtime() - timeStart;
5712 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5713 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5714 boolean useTombstonedForJavaTraces) {
5716 // We don't need any sort of inotify based monitoring when we're dumping traces via
5717 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5718 // control of all writes to the file in question.
5719 final DumpStackFileObserver observer;
5720 if (useTombstonedForJavaTraces) {
5723 // Use a FileObserver to detect when traces finish writing.
5724 // The order of traces is considered important to maintain for legibility.
5725 observer = new DumpStackFileObserver(tracesFile);
5728 // We must complete all stack dumps within 20 seconds.
5729 long remainingTime = 20 * 1000;
5731 if (observer != null) {
5732 observer.startWatching();
5735 // First collect all of the stacks of the most important pids.
5736 if (firstPids != null) {
5737 int num = firstPids.size();
5738 for (int i = 0; i < num; i++) {
5739 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5740 + firstPids.get(i));
5741 final long timeTaken;
5742 if (useTombstonedForJavaTraces) {
5743 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5745 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5748 remainingTime -= timeTaken;
5749 if (remainingTime <= 0) {
5750 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5751 "); deadline exceeded.");
5756 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5761 // Next collect the stacks of the native pids
5762 if (nativePids != null) {
5763 for (int pid : nativePids) {
5764 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5765 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5767 final long start = SystemClock.elapsedRealtime();
5768 Debug.dumpNativeBacktraceToFileTimeout(
5769 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5770 final long timeTaken = SystemClock.elapsedRealtime() - start;
5772 remainingTime -= timeTaken;
5773 if (remainingTime <= 0) {
5774 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5775 "); deadline exceeded.");
5780 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5785 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5786 if (extraPids != null) {
5787 for (int pid : extraPids) {
5788 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5790 final long timeTaken;
5791 if (useTombstonedForJavaTraces) {
5792 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5794 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5797 remainingTime -= timeTaken;
5798 if (remainingTime <= 0) {
5799 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5800 "); deadline exceeded.");
5805 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5810 if (observer != null) {
5811 observer.stopWatching();
5816 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5817 if (true || Build.IS_USER) {
5820 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5821 if (tracesPath == null || tracesPath.length() == 0) {
5825 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5826 StrictMode.allowThreadDiskWrites();
5828 final File tracesFile = new File(tracesPath);
5829 final File tracesDir = tracesFile.getParentFile();
5830 final File tracesTmp = new File(tracesDir, "__tmp__");
5832 if (tracesFile.exists()) {
5834 tracesFile.renameTo(tracesTmp);
5836 StringBuilder sb = new StringBuilder();
5837 Time tobj = new Time();
5838 tobj.set(System.currentTimeMillis());
5839 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5841 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5842 sb.append(" since ");
5844 FileOutputStream fos = new FileOutputStream(tracesFile);
5845 fos.write(sb.toString().getBytes());
5847 fos.write("\n*** No application process!".getBytes());
5850 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5851 } catch (IOException e) {
5852 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5857 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5858 firstPids.add(app.pid);
5859 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5862 File lastTracesFile = null;
5863 File curTracesFile = null;
5864 for (int i=9; i>=0; i--) {
5865 String name = String.format(Locale.US, "slow%02d.txt", i);
5866 curTracesFile = new File(tracesDir, name);
5867 if (curTracesFile.exists()) {
5868 if (lastTracesFile != null) {
5869 curTracesFile.renameTo(lastTracesFile);
5871 curTracesFile.delete();
5874 lastTracesFile = curTracesFile;
5876 tracesFile.renameTo(curTracesFile);
5877 if (tracesTmp.exists()) {
5878 tracesTmp.renameTo(tracesFile);
5881 StrictMode.setThreadPolicy(oldPolicy);
5885 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5886 if (!mLaunchWarningShown) {
5887 mLaunchWarningShown = true;
5888 mUiHandler.post(new Runnable() {
5891 synchronized (ActivityManagerService.this) {
5892 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5894 mUiHandler.postDelayed(new Runnable() {
5897 synchronized (ActivityManagerService.this) {
5899 mLaunchWarningShown = false;
5910 public boolean clearApplicationUserData(final String packageName,
5911 final IPackageDataObserver observer, int userId) {
5912 enforceNotIsolatedCaller("clearApplicationUserData");
5913 int uid = Binder.getCallingUid();
5914 int pid = Binder.getCallingPid();
5915 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5916 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5918 final ApplicationInfo appInfo;
5919 final boolean isInstantApp;
5921 long callingId = Binder.clearCallingIdentity();
5923 IPackageManager pm = AppGlobals.getPackageManager();
5924 synchronized(this) {
5925 // Instant packages are not protected
5926 if (getPackageManagerInternalLocked().isPackageDataProtected(
5927 resolvedUserId, packageName)) {
5928 throw new SecurityException(
5929 "Cannot clear data for a protected package: " + packageName);
5932 ApplicationInfo applicationInfo = null;
5934 applicationInfo = pm.getApplicationInfo(packageName,
5935 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5936 } catch (RemoteException e) {
5939 appInfo = applicationInfo;
5941 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5943 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5944 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5945 throw new SecurityException("PID " + pid + " does not have permission "
5946 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5947 + " of package " + packageName);
5950 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5951 .hasInstantApplicationMetadata(packageName, resolvedUserId);
5952 final boolean isUninstalledAppWithoutInstantMetadata =
5953 (appInfo == null && !hasInstantMetadata);
5954 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5955 || hasInstantMetadata;
5956 final boolean canAccessInstantApps = checkComponentPermission(
5957 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5958 == PackageManager.PERMISSION_GRANTED;
5960 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5961 && !canAccessInstantApps)) {
5962 Slog.w(TAG, "Invalid packageName: " + packageName);
5963 if (observer != null) {
5965 observer.onRemoveCompleted(packageName, false);
5966 } catch (RemoteException e) {
5967 Slog.i(TAG, "Observer no longer exists.");
5973 if (appInfo != null) {
5974 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5975 // Remove all tasks match the cleared application package and user
5976 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5977 final TaskRecord tr = mRecentTasks.get(i);
5978 final String taskPackageName =
5979 tr.getBaseIntent().getComponent().getPackageName();
5980 if (tr.userId != resolvedUserId) continue;
5981 if (!taskPackageName.equals(packageName)) continue;
5982 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5983 REMOVE_FROM_RECENTS);
5988 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5990 public void onRemoveCompleted(String packageName, boolean succeeded)
5991 throws RemoteException {
5992 if (appInfo != null) {
5993 synchronized (ActivityManagerService.this) {
5994 finishForceStopPackageLocked(packageName, appInfo.uid);
5997 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5998 Uri.fromParts("package", packageName, null));
5999 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6000 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6001 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6003 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6004 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6005 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6008 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6009 null, null, null, null, false, false, resolvedUserId);
6012 if (observer != null) {
6013 observer.onRemoveCompleted(packageName, succeeded);
6019 // Clear application user data
6020 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6022 if (appInfo != null) {
6023 synchronized (this) {
6024 // Remove all permissions granted from/to this package
6025 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6028 // Reset notification settings.
6029 INotificationManager inm = NotificationManager.getService();
6030 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6032 } catch (RemoteException e) {
6035 Binder.restoreCallingIdentity(callingId);
6041 public void killBackgroundProcesses(final String packageName, int userId) {
6042 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6043 != PackageManager.PERMISSION_GRANTED &&
6044 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6045 != PackageManager.PERMISSION_GRANTED) {
6046 String msg = "Permission Denial: killBackgroundProcesses() from pid="
6047 + Binder.getCallingPid()
6048 + ", uid=" + Binder.getCallingUid()
6049 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6051 throw new SecurityException(msg);
6054 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6055 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6056 long callingId = Binder.clearCallingIdentity();
6058 IPackageManager pm = AppGlobals.getPackageManager();
6059 synchronized(this) {
6062 appId = UserHandle.getAppId(
6063 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6064 } catch (RemoteException e) {
6067 Slog.w(TAG, "Invalid packageName: " + packageName);
6070 killPackageProcessesLocked(packageName, appId, userId,
6071 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6074 Binder.restoreCallingIdentity(callingId);
6079 public void killAllBackgroundProcesses() {
6080 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6081 != PackageManager.PERMISSION_GRANTED) {
6082 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6083 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6084 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6086 throw new SecurityException(msg);
6089 final long callingId = Binder.clearCallingIdentity();
6091 synchronized (this) {
6092 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6093 final int NP = mProcessNames.getMap().size();
6094 for (int ip = 0; ip < NP; ip++) {
6095 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6096 final int NA = apps.size();
6097 for (int ia = 0; ia < NA; ia++) {
6098 final ProcessRecord app = apps.valueAt(ia);
6099 if (app.persistent) {
6100 // We don't kill persistent processes.
6105 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6112 final int N = procs.size();
6113 for (int i = 0; i < N; i++) {
6114 removeProcessLocked(procs.get(i), false, true, "kill all background");
6117 mAllowLowerMemLevel = true;
6119 updateOomAdjLocked();
6120 doLowMemReportIfNeededLocked(null);
6123 Binder.restoreCallingIdentity(callingId);
6128 * Kills all background processes, except those matching any of the
6129 * specified properties.
6131 * @param minTargetSdk the target SDK version at or above which to preserve
6132 * processes, or {@code -1} to ignore the target SDK
6133 * @param maxProcState the process state at or below which to preserve
6134 * processes, or {@code -1} to ignore the process state
6136 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6137 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6138 != PackageManager.PERMISSION_GRANTED) {
6139 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6140 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6141 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6143 throw new SecurityException(msg);
6146 final long callingId = Binder.clearCallingIdentity();
6148 synchronized (this) {
6149 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6150 final int NP = mProcessNames.getMap().size();
6151 for (int ip = 0; ip < NP; ip++) {
6152 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6153 final int NA = apps.size();
6154 for (int ia = 0; ia < NA; ia++) {
6155 final ProcessRecord app = apps.valueAt(ia);
6158 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6159 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6166 final int N = procs.size();
6167 for (int i = 0; i < N; i++) {
6168 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6172 Binder.restoreCallingIdentity(callingId);
6177 public void forceStopPackage(final String packageName, int userId) {
6178 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6179 != PackageManager.PERMISSION_GRANTED) {
6180 String msg = "Permission Denial: forceStopPackage() from pid="
6181 + Binder.getCallingPid()
6182 + ", uid=" + Binder.getCallingUid()
6183 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6185 throw new SecurityException(msg);
6187 final int callingPid = Binder.getCallingPid();
6188 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6189 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6190 long callingId = Binder.clearCallingIdentity();
6192 IPackageManager pm = AppGlobals.getPackageManager();
6193 synchronized(this) {
6194 int[] users = userId == UserHandle.USER_ALL
6195 ? mUserController.getUsers() : new int[] { userId };
6196 for (int user : users) {
6199 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6201 } catch (RemoteException e) {
6204 Slog.w(TAG, "Invalid packageName: " + packageName);
6208 pm.setPackageStoppedState(packageName, true, user);
6209 } catch (RemoteException e) {
6210 } catch (IllegalArgumentException e) {
6211 Slog.w(TAG, "Failed trying to unstop package "
6212 + packageName + ": " + e);
6214 if (mUserController.isUserRunningLocked(user, 0)) {
6215 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6216 finishForceStopPackageLocked(packageName, pkgUid);
6221 Binder.restoreCallingIdentity(callingId);
6226 public void addPackageDependency(String packageName) {
6227 synchronized (this) {
6228 int callingPid = Binder.getCallingPid();
6229 if (callingPid == myPid()) {
6234 synchronized (mPidsSelfLocked) {
6235 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6238 if (proc.pkgDeps == null) {
6239 proc.pkgDeps = new ArraySet<String>(1);
6241 proc.pkgDeps.add(packageName);
6247 * The pkg name and app id have to be specified.
6250 public void killApplication(String pkg, int appId, int userId, String reason) {
6254 // Make sure the uid is valid.
6256 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6259 int callerUid = Binder.getCallingUid();
6260 // Only the system server can kill an application
6261 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6262 // Post an aysnc message to kill the application
6263 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6266 Bundle bundle = new Bundle();
6267 bundle.putString("pkg", pkg);
6268 bundle.putString("reason", reason);
6270 mHandler.sendMessage(msg);
6272 throw new SecurityException(callerUid + " cannot kill pkg: " +
6278 public void closeSystemDialogs(String reason) {
6279 enforceNotIsolatedCaller("closeSystemDialogs");
6281 final int pid = Binder.getCallingPid();
6282 final int uid = Binder.getCallingUid();
6283 final long origId = Binder.clearCallingIdentity();
6285 synchronized (this) {
6286 // Only allow this from foreground processes, so that background
6287 // applications can't abuse it to prevent system UI from being shown.
6288 if (uid >= FIRST_APPLICATION_UID) {
6290 synchronized (mPidsSelfLocked) {
6291 proc = mPidsSelfLocked.get(pid);
6293 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6294 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6295 + " from background process " + proc);
6299 closeSystemDialogsLocked(reason);
6302 Binder.restoreCallingIdentity(origId);
6306 void closeSystemDialogsLocked(String reason) {
6307 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6308 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6309 | Intent.FLAG_RECEIVER_FOREGROUND);
6310 if (reason != null) {
6311 intent.putExtra("reason", reason);
6313 mWindowManager.closeSystemDialogs(reason);
6315 mStackSupervisor.closeSystemDialogsLocked();
6317 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6318 AppOpsManager.OP_NONE, null, false, false,
6319 -1, SYSTEM_UID, UserHandle.USER_ALL);
6323 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6324 enforceNotIsolatedCaller("getProcessMemoryInfo");
6325 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6326 for (int i=pids.length-1; i>=0; i--) {
6329 synchronized (this) {
6330 synchronized (mPidsSelfLocked) {
6331 proc = mPidsSelfLocked.get(pids[i]);
6332 oomAdj = proc != null ? proc.setAdj : 0;
6335 infos[i] = new Debug.MemoryInfo();
6336 Debug.getMemoryInfo(pids[i], infos[i]);
6338 synchronized (this) {
6339 if (proc.thread != null && proc.setAdj == oomAdj) {
6340 // Record this for posterity if the process has been stable.
6341 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6342 infos[i].getTotalUss(), false, proc.pkgList);
6351 public long[] getProcessPss(int[] pids) {
6352 enforceNotIsolatedCaller("getProcessPss");
6353 long[] pss = new long[pids.length];
6354 for (int i=pids.length-1; i>=0; i--) {
6357 synchronized (this) {
6358 synchronized (mPidsSelfLocked) {
6359 proc = mPidsSelfLocked.get(pids[i]);
6360 oomAdj = proc != null ? proc.setAdj : 0;
6363 long[] tmpUss = new long[1];
6364 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6366 synchronized (this) {
6367 if (proc.thread != null && proc.setAdj == oomAdj) {
6368 // Record this for posterity if the process has been stable.
6369 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6378 public void killApplicationProcess(String processName, int uid) {
6379 if (processName == null) {
6383 int callerUid = Binder.getCallingUid();
6384 // Only the system server can kill an application
6385 if (callerUid == SYSTEM_UID) {
6386 synchronized (this) {
6387 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6388 if (app != null && app.thread != null) {
6390 app.thread.scheduleSuicide();
6391 } catch (RemoteException e) {
6392 // If the other end already died, then our work here is done.
6395 Slog.w(TAG, "Process/uid not found attempting kill of "
6396 + processName + " / " + uid);
6400 throw new SecurityException(callerUid + " cannot kill app process: " +
6405 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6406 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6407 false, true, false, false, UserHandle.getUserId(uid), reason);
6410 private void finishForceStopPackageLocked(final String packageName, int uid) {
6411 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6412 Uri.fromParts("package", packageName, null));
6413 if (!mProcessesReady) {
6414 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6415 | Intent.FLAG_RECEIVER_FOREGROUND);
6417 intent.putExtra(Intent.EXTRA_UID, uid);
6418 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6419 broadcastIntentLocked(null, null, intent,
6420 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6421 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6425 private final boolean killPackageProcessesLocked(String packageName, int appId,
6426 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6427 boolean doit, boolean evenPersistent, String reason) {
6428 ArrayList<ProcessRecord> procs = new ArrayList<>();
6430 // Remove all processes this package may have touched: all with the
6431 // same UID (except for the system or root user), and all whose name
6432 // matches the package name.
6433 final int NP = mProcessNames.getMap().size();
6434 for (int ip=0; ip<NP; ip++) {
6435 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6436 final int NA = apps.size();
6437 for (int ia=0; ia<NA; ia++) {
6438 ProcessRecord app = apps.valueAt(ia);
6439 if (app.persistent && !evenPersistent) {
6440 // we don't kill persistent processes
6450 // Skip process if it doesn't meet our oom adj requirement.
6451 if (app.setAdj < minOomAdj) {
6455 // If no package is specified, we call all processes under the
6457 if (packageName == null) {
6458 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6461 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6464 // Package has been specified, we want to hit all processes
6465 // that match it. We need to qualify this by the processes
6466 // that are running under the specified app and user ID.
6468 final boolean isDep = app.pkgDeps != null
6469 && app.pkgDeps.contains(packageName);
6470 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6473 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6476 if (!app.pkgList.containsKey(packageName) && !isDep) {
6481 // Process has passed all conditions, kill it!
6490 int N = procs.size();
6491 for (int i=0; i<N; i++) {
6492 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6494 updateOomAdjLocked();
6498 private void cleanupDisabledPackageComponentsLocked(
6499 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6501 Set<String> disabledClasses = null;
6502 boolean packageDisabled = false;
6503 IPackageManager pm = AppGlobals.getPackageManager();
6505 if (changedClasses == null) {
6506 // Nothing changed...
6510 // Determine enable/disable state of the package and its components.
6511 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6512 for (int i = changedClasses.length - 1; i >= 0; i--) {
6513 final String changedClass = changedClasses[i];
6515 if (changedClass.equals(packageName)) {
6517 // Entire package setting changed
6518 enabled = pm.getApplicationEnabledSetting(packageName,
6519 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6520 } catch (Exception e) {
6521 // No such package/component; probably racing with uninstall. In any
6522 // event it means we have nothing further to do here.
6525 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6526 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6527 if (packageDisabled) {
6528 // Entire package is disabled.
6529 // No need to continue to check component states.
6530 disabledClasses = null;
6535 enabled = pm.getComponentEnabledSetting(
6536 new ComponentName(packageName, changedClass),
6537 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6538 } catch (Exception e) {
6539 // As above, probably racing with uninstall.
6542 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6543 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6544 if (disabledClasses == null) {
6545 disabledClasses = new ArraySet<>(changedClasses.length);
6547 disabledClasses.add(changedClass);
6552 if (!packageDisabled && disabledClasses == null) {
6553 // Nothing to do here...
6557 // Clean-up disabled activities.
6558 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6559 packageName, disabledClasses, true, false, userId) && mBooted) {
6560 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6561 mStackSupervisor.scheduleIdleLocked();
6564 // Clean-up disabled tasks
6565 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6567 // Clean-up disabled services.
6568 mServices.bringDownDisabledPackageServicesLocked(
6569 packageName, disabledClasses, userId, false, killProcess, true);
6571 // Clean-up disabled providers.
6572 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6573 mProviderMap.collectPackageProvidersLocked(
6574 packageName, disabledClasses, true, false, userId, providers);
6575 for (int i = providers.size() - 1; i >= 0; i--) {
6576 removeDyingProviderLocked(null, providers.get(i), true);
6579 // Clean-up disabled broadcast receivers.
6580 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6581 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6582 packageName, disabledClasses, userId, true);
6587 final boolean clearBroadcastQueueForUserLocked(int userId) {
6588 boolean didSomething = false;
6589 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6590 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6591 null, null, userId, true);
6593 return didSomething;
6596 final boolean forceStopPackageLocked(String packageName, int appId,
6597 boolean callerWillRestart, boolean purgeCache, boolean doit,
6598 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6601 if (userId == UserHandle.USER_ALL && packageName == null) {
6602 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6605 if (appId < 0 && packageName != null) {
6607 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6608 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6609 } catch (RemoteException e) {
6614 if (packageName != null) {
6615 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6616 + " user=" + userId + ": " + reason);
6618 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6621 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6624 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6625 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6626 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6628 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6630 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6631 packageName, null, doit, evenPersistent, userId)) {
6635 didSomething = true;
6638 if (mServices.bringDownDisabledPackageServicesLocked(
6639 packageName, null, userId, evenPersistent, true, doit)) {
6643 didSomething = true;
6646 if (packageName == null) {
6647 // Remove all sticky broadcasts from this user.
6648 mStickyBroadcasts.remove(userId);
6651 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6652 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6653 userId, providers)) {
6657 didSomething = true;
6659 for (i = providers.size() - 1; i >= 0; i--) {
6660 removeDyingProviderLocked(null, providers.get(i), true);
6663 // Remove transient permissions granted from/to this package/user
6664 removeUriPermissionsForPackageLocked(packageName, userId, false);
6667 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6668 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6669 packageName, null, userId, doit);
6673 if (packageName == null || uninstalling) {
6674 // Remove pending intents. For now we only do this when force
6675 // stopping users, because we have some problems when doing this
6676 // for packages -- app widgets are not currently cleaned up for
6677 // such packages, so they can be left with bad pending intents.
6678 if (mIntentSenderRecords.size() > 0) {
6679 Iterator<WeakReference<PendingIntentRecord>> it
6680 = mIntentSenderRecords.values().iterator();
6681 while (it.hasNext()) {
6682 WeakReference<PendingIntentRecord> wpir = it.next();
6687 PendingIntentRecord pir = wpir.get();
6692 if (packageName == null) {
6693 // Stopping user, remove all objects for the user.
6694 if (pir.key.userId != userId) {
6695 // Not the same user, skip it.
6699 if (UserHandle.getAppId(pir.uid) != appId) {
6700 // Different app id, skip it.
6703 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6704 // Different user, skip it.
6707 if (!pir.key.packageName.equals(packageName)) {
6708 // Different package, skip it.
6715 didSomething = true;
6717 makeIntentSenderCanceledLocked(pir);
6718 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6719 pir.key.activity.pendingResults.remove(pir.ref);
6726 if (purgeCache && packageName != null) {
6727 AttributeCache ac = AttributeCache.instance();
6729 ac.removePackage(packageName);
6733 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6734 mStackSupervisor.scheduleIdleLocked();
6738 return didSomething;
6741 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6742 return removeProcessNameLocked(name, uid, null);
6745 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6746 final ProcessRecord expecting) {
6747 ProcessRecord old = mProcessNames.get(name, uid);
6748 // Only actually remove when the currently recorded value matches the
6749 // record that we expected; if it doesn't match then we raced with a
6750 // newly created process and we don't want to destroy the new one.
6751 if ((expecting == null) || (old == expecting)) {
6752 mProcessNames.remove(name, uid);
6754 if (old != null && old.uidRecord != null) {
6755 old.uidRecord.numProcs--;
6756 if (old.uidRecord.numProcs == 0) {
6757 // No more processes using this uid, tell clients it is gone.
6758 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6759 "No more processes in " + old.uidRecord);
6760 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6761 EventLogTags.writeAmUidStopped(uid);
6762 mActiveUids.remove(uid);
6763 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6765 old.uidRecord = null;
6767 mIsolatedProcesses.remove(uid);
6771 private final void addProcessNameLocked(ProcessRecord proc) {
6772 // We shouldn't already have a process under this name, but just in case we
6773 // need to clean up whatever may be there now.
6774 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6775 if (old == proc && proc.persistent) {
6776 // We are re-adding a persistent process. Whatevs! Just leave it there.
6777 Slog.w(TAG, "Re-adding persistent process " + proc);
6778 } else if (old != null) {
6779 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6781 UidRecord uidRec = mActiveUids.get(proc.uid);
6782 if (uidRec == null) {
6783 uidRec = new UidRecord(proc.uid);
6784 // This is the first appearance of the uid, report it now!
6785 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6786 "Creating new process uid: " + uidRec);
6787 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6788 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6789 uidRec.setWhitelist = uidRec.curWhitelist = true;
6791 uidRec.updateHasInternetPermission();
6792 mActiveUids.put(proc.uid, uidRec);
6793 EventLogTags.writeAmUidRunning(uidRec.uid);
6794 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6796 proc.uidRecord = uidRec;
6798 // Reset render thread tid if it was already set, so new process can set it again.
6799 proc.renderThreadTid = 0;
6801 mProcessNames.put(proc.processName, proc.uid, proc);
6802 if (proc.isolated) {
6803 mIsolatedProcesses.put(proc.uid, proc);
6807 boolean removeProcessLocked(ProcessRecord app,
6808 boolean callerWillRestart, boolean allowRestart, String reason) {
6809 final String name = app.processName;
6810 final int uid = app.uid;
6811 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6812 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6814 ProcessRecord old = mProcessNames.get(name, uid);
6816 // This process is no longer active, so nothing to do.
6817 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6820 removeProcessNameLocked(name, uid);
6821 if (mHeavyWeightProcess == app) {
6822 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6823 mHeavyWeightProcess.userId, 0));
6824 mHeavyWeightProcess = null;
6826 boolean needRestart = false;
6827 if (app.pid > 0 && app.pid != MY_PID) {
6829 synchronized (mPidsSelfLocked) {
6830 mPidsSelfLocked.remove(pid);
6831 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6833 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6834 boolean willRestart = false;
6835 if (app.persistent && !app.isolated) {
6836 if (!callerWillRestart) {
6842 app.kill(reason, true);
6844 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6845 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6847 handleAppDiedLocked(app, willRestart, allowRestart);
6849 removeLruProcessLocked(app);
6850 addAppLocked(app.info, null, false, null /* ABI override */);
6853 mRemovedProcesses.add(app);
6859 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6860 cleanupAppInLaunchingProvidersLocked(app, true);
6861 removeProcessLocked(app, false, true, "timeout publishing content providers");
6864 private final void processStartTimedOutLocked(ProcessRecord app) {
6865 final int pid = app.pid;
6866 boolean gone = false;
6867 synchronized (mPidsSelfLocked) {
6868 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6869 if (knownApp != null && knownApp.thread == null) {
6870 mPidsSelfLocked.remove(pid);
6876 Slog.w(TAG, "Process " + app + " failed to attach");
6877 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6878 pid, app.uid, app.processName);
6879 removeProcessNameLocked(app.processName, app.uid);
6880 if (mHeavyWeightProcess == app) {
6881 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6882 mHeavyWeightProcess.userId, 0));
6883 mHeavyWeightProcess = null;
6885 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6886 // Take care of any launching providers waiting for this process.
6887 cleanupAppInLaunchingProvidersLocked(app, true);
6888 // Take care of any services that are waiting for the process.
6889 mServices.processStartTimedOutLocked(app);
6890 app.kill("start timeout", true);
6892 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6894 removeLruProcessLocked(app);
6895 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6896 Slog.w(TAG, "Unattached app died before backup, skipping");
6897 mHandler.post(new Runnable() {
6901 IBackupManager bm = IBackupManager.Stub.asInterface(
6902 ServiceManager.getService(Context.BACKUP_SERVICE));
6903 bm.agentDisconnected(app.info.packageName);
6904 } catch (RemoteException e) {
6905 // Can't happen; the backup manager is local
6910 if (isPendingBroadcastProcessLocked(pid)) {
6911 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6912 skipPendingBroadcastLocked(pid);
6915 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6919 private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
6922 // Find the application record that is being attached... either via
6923 // the pid if we are running in multiple processes, or just pull the
6924 // next app record if we are emulating process with anonymous threads.
6926 long startTime = SystemClock.uptimeMillis();
6927 if (pid != MY_PID && pid >= 0) {
6928 synchronized (mPidsSelfLocked) {
6929 app = mPidsSelfLocked.get(pid);
6936 Slog.w(TAG, "No pending application record for pid " + pid
6937 + " (IApplicationThread " + thread + "); dropping process");
6938 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6939 if (pid > 0 && pid != MY_PID) {
6940 killProcessQuiet(pid);
6941 //TODO: killProcessGroup(app.info.uid, pid);
6944 thread.scheduleExit();
6945 } catch (Exception e) {
6946 // Ignore exceptions.
6952 // If this application record is still attached to a previous
6953 // process, clean it up now.
6954 if (app.thread != null) {
6955 handleAppDiedLocked(app, true, true);
6958 // Tell the process all about itself.
6960 if (DEBUG_ALL) Slog.v(
6961 TAG, "Binding process pid " + pid + " to record " + app);
6963 final String processName = app.processName;
6965 AppDeathRecipient adr = new AppDeathRecipient(
6967 thread.asBinder().linkToDeath(adr, 0);
6968 app.deathRecipient = adr;
6969 } catch (RemoteException e) {
6970 app.resetPackageList(mProcessStats);
6971 startProcessLocked(app, "link fail", processName);
6975 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6977 app.makeActive(thread, mProcessStats);
6978 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6979 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6980 app.forcingToImportant = null;
6981 updateProcessForegroundLocked(app, false, false);
6982 app.hasShownUi = false;
6983 app.debugging = false;
6985 app.killedByAm = false;
6989 // We carefully use the same state that PackageManager uses for
6990 // filtering, since we use this flag to decide if we need to install
6991 // providers when user is unlocked later
6992 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6994 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6996 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6997 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6999 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7000 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7002 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7005 checkTime(startTime, "attachApplicationLocked: before bindApplication");
7008 Slog.i(TAG, "Launching preboot mode app: " + app);
7011 if (DEBUG_ALL) Slog.v(
7012 TAG, "New app record " + app
7013 + " thread=" + thread.asBinder() + " pid=" + pid);
7015 int testMode = ApplicationThreadConstants.DEBUG_OFF;
7016 if (mDebugApp != null && mDebugApp.equals(processName)) {
7017 testMode = mWaitForDebugger
7018 ? ApplicationThreadConstants.DEBUG_WAIT
7019 : ApplicationThreadConstants.DEBUG_ON;
7020 app.debugging = true;
7021 if (mDebugTransient) {
7022 mDebugApp = mOrigDebugApp;
7023 mWaitForDebugger = mOrigWaitForDebugger;
7027 ProfilerInfo profilerInfo = null;
7028 String agent = null;
7029 if (mProfileApp != null && mProfileApp.equals(processName)) {
7031 profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7032 new ProfilerInfo(mProfilerInfo) : null;
7033 agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7034 } else if (app.instr != null && app.instr.mProfileFile != null) {
7035 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7039 boolean enableTrackAllocation = false;
7040 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7041 enableTrackAllocation = true;
7042 mTrackAllocationApp = null;
7045 // If the app is being launched for restore or full backup, set it up specially
7046 boolean isRestrictedBackupMode = false;
7047 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7048 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7049 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7050 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7051 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7054 if (app.instr != null) {
7055 notifyPackageUse(app.instr.mClass.getPackageName(),
7056 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7058 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7059 + processName + " with config " + getGlobalConfiguration());
7060 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7061 app.compat = compatibilityInfoForPackageLocked(appInfo);
7063 if (profilerInfo != null && profilerInfo.profileFd != null) {
7064 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7067 // We deprecated Build.SERIAL and it is not accessible to
7068 // apps that target the v2 security sandbox. Since access to
7069 // the serial is now behind a permission we push down the value.
7070 String buildSerial = appInfo.targetSandboxVersion < 2
7071 ? sTheRealBuildSerial : Build.UNKNOWN;
7073 // Check if this is a secondary process that should be incorporated into some
7074 // currently active instrumentation. (Note we do this AFTER all of the profiling
7075 // stuff above because profiling can currently happen only in the primary
7076 // instrumentation process.)
7077 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7078 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7079 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7080 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7081 if (aInstr.mTargetProcesses.length == 0) {
7082 // This is the wildcard mode, where every process brought up for
7083 // the target instrumentation should be included.
7084 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7086 aInstr.mRunningProcesses.add(app);
7089 for (String proc : aInstr.mTargetProcesses) {
7090 if (proc.equals(app.processName)) {
7092 aInstr.mRunningProcesses.add(app);
7101 // If we were asked to attach an agent on startup, do so now, before we're binding
7102 // application code.
7103 if (agent != null) {
7104 thread.attachAgent(agent);
7107 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7108 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7109 if (app.instr != null) {
7110 thread.bindApplication(processName, appInfo, providers,
7112 profilerInfo, app.instr.mArguments,
7114 app.instr.mUiAutomationConnection, testMode,
7115 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7116 isRestrictedBackupMode || !normalMode, app.persistent,
7117 new Configuration(getGlobalConfiguration()), app.compat,
7118 getCommonServicesLocked(app.isolated),
7119 mCoreSettingsObserver.getCoreSettingsLocked(),
7122 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7123 null, null, null, testMode,
7124 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7125 isRestrictedBackupMode || !normalMode, app.persistent,
7126 new Configuration(getGlobalConfiguration()), app.compat,
7127 getCommonServicesLocked(app.isolated),
7128 mCoreSettingsObserver.getCoreSettingsLocked(),
7132 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7133 updateLruProcessLocked(app, false, null);
7134 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7135 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7136 } catch (Exception e) {
7137 // todo: Yikes! What should we do? For now we will try to
7138 // start another process, but that could easily get us in
7139 // an infinite loop of restarting processes...
7140 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7142 app.resetPackageList(mProcessStats);
7143 app.unlinkDeathRecipient();
7144 startProcessLocked(app, "bind fail", processName);
7148 // Remove this record from the list of starting applications.
7149 mPersistentStartingProcesses.remove(app);
7150 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7151 "Attach application locked removing on hold: " + app);
7152 mProcessesOnHold.remove(app);
7154 boolean badApp = false;
7155 boolean didSomething = false;
7157 // See if the top visible activity is waiting to run in this process...
7160 if (mStackSupervisor.attachApplicationLocked(app)) {
7161 didSomething = true;
7163 } catch (Exception e) {
7164 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7169 // Find any services that should be running in this process...
7172 didSomething |= mServices.attachApplicationLocked(app, processName);
7173 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7174 } catch (Exception e) {
7175 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7180 // Check if a next-broadcast receiver is in this process...
7181 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7183 didSomething |= sendPendingBroadcastsLocked(app);
7184 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7185 } catch (Exception e) {
7186 // If the app died trying to launch the receiver we declare it 'bad'
7187 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7192 // Check whether the next backup agent is in this process...
7193 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7194 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7195 "New app is backup target, launching agent for " + app);
7196 notifyPackageUse(mBackupTarget.appInfo.packageName,
7197 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7199 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7200 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7201 mBackupTarget.backupMode);
7202 } catch (Exception e) {
7203 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7209 app.kill("error during init", true);
7210 handleAppDiedLocked(app, false, true);
7214 if (!didSomething) {
7215 updateOomAdjLocked();
7216 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7223 public final void attachApplication(IApplicationThread thread) {
7224 if (thread == null) {
7225 throw new SecurityException("Invalid application interface");
7227 synchronized (this) {
7228 int callingPid = Binder.getCallingPid();
7229 final long origId = Binder.clearCallingIdentity();
7230 attachApplicationLocked(thread, callingPid);
7231 Binder.restoreCallingIdentity(origId);
7236 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7237 final long origId = Binder.clearCallingIdentity();
7238 synchronized (this) {
7239 ActivityStack stack = ActivityRecord.getStackLocked(token);
7240 if (stack != null) {
7242 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7243 false /* processPausingActivities */, config);
7244 if (stopProfiling) {
7245 if ((mProfileProc == r.app) && mProfilerInfo != null) {
7246 clearProfilerLocked();
7251 Binder.restoreCallingIdentity(origId);
7254 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7255 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7256 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7259 void enableScreenAfterBoot() {
7260 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7261 SystemClock.uptimeMillis());
7262 mWindowManager.enableScreenAfterBoot();
7264 synchronized (this) {
7265 updateEventDispatchingLocked();
7270 public void showBootMessage(final CharSequence msg, final boolean always) {
7271 if (Binder.getCallingUid() != myUid()) {
7272 throw new SecurityException();
7274 mWindowManager.showBootMessage(msg, always);
7278 public void keyguardGoingAway(int flags) {
7279 enforceNotIsolatedCaller("keyguardGoingAway");
7280 final long token = Binder.clearCallingIdentity();
7282 synchronized (this) {
7283 mKeyguardController.keyguardGoingAway(flags);
7286 Binder.restoreCallingIdentity(token);
7291 * @return whther the keyguard is currently locked.
7293 boolean isKeyguardLocked() {
7294 return mKeyguardController.isKeyguardLocked();
7297 final void finishBooting() {
7298 synchronized (this) {
7299 if (!mBootAnimationComplete) {
7300 mCallFinishBooting = true;
7303 mCallFinishBooting = false;
7306 ArraySet<String> completedIsas = new ArraySet<String>();
7307 for (String abi : Build.SUPPORTED_ABIS) {
7308 zygoteProcess.establishZygoteConnectionForAbi(abi);
7309 final String instructionSet = VMRuntime.getInstructionSet(abi);
7310 if (!completedIsas.contains(instructionSet)) {
7312 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7313 } catch (InstallerException e) {
7314 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7315 e.getMessage() +")");
7317 completedIsas.add(instructionSet);
7321 IntentFilter pkgFilter = new IntentFilter();
7322 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7323 pkgFilter.addDataScheme("package");
7324 mContext.registerReceiver(new BroadcastReceiver() {
7326 public void onReceive(Context context, Intent intent) {
7327 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7329 for (String pkg : pkgs) {
7330 synchronized (ActivityManagerService.this) {
7331 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7332 0, "query restart")) {
7333 setResultCode(Activity.RESULT_OK);
7342 IntentFilter dumpheapFilter = new IntentFilter();
7343 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7344 mContext.registerReceiver(new BroadcastReceiver() {
7346 public void onReceive(Context context, Intent intent) {
7347 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7348 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7350 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7355 // Let system services know.
7356 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7358 synchronized (this) {
7359 // Ensure that any processes we had put on hold are now started
7361 final int NP = mProcessesOnHold.size();
7363 ArrayList<ProcessRecord> procs =
7364 new ArrayList<ProcessRecord>(mProcessesOnHold);
7365 for (int ip=0; ip<NP; ip++) {
7366 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7368 startProcessLocked(procs.get(ip), "on-hold", null);
7372 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7373 // Start looking for apps that are abusing wake locks.
7374 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7375 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7376 // Tell anyone interested that we are done booting!
7377 SystemProperties.set("sys.boot_completed", "1");
7379 // And trigger dev.bootcomplete if we are not showing encryption progress
7380 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7381 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7382 SystemProperties.set("dev.bootcomplete", "1");
7384 mUserController.sendBootCompletedLocked(
7385 new IIntentReceiver.Stub() {
7387 public void performReceive(Intent intent, int resultCode,
7388 String data, Bundle extras, boolean ordered,
7389 boolean sticky, int sendingUser) {
7390 synchronized (ActivityManagerService.this) {
7391 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7396 scheduleStartProfilesLocked();
7402 public void bootAnimationComplete() {
7403 final boolean callFinishBooting;
7404 synchronized (this) {
7405 callFinishBooting = mCallFinishBooting;
7406 mBootAnimationComplete = true;
7408 if (callFinishBooting) {
7409 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7411 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7415 final void ensureBootCompleted() {
7417 boolean enableScreen;
7418 synchronized (this) {
7421 enableScreen = !mBooted;
7426 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7428 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7432 enableScreenAfterBoot();
7437 public final void activityResumed(IBinder token) {
7438 final long origId = Binder.clearCallingIdentity();
7439 synchronized(this) {
7440 ActivityRecord.activityResumedLocked(token);
7441 mWindowManager.notifyAppResumedFinished(token);
7443 Binder.restoreCallingIdentity(origId);
7447 public final void activityPaused(IBinder token) {
7448 final long origId = Binder.clearCallingIdentity();
7449 synchronized(this) {
7450 ActivityStack stack = ActivityRecord.getStackLocked(token);
7451 if (stack != null) {
7452 stack.activityPausedLocked(token, false);
7455 Binder.restoreCallingIdentity(origId);
7459 public final void activityStopped(IBinder token, Bundle icicle,
7460 PersistableBundle persistentState, CharSequence description) {
7461 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7463 // Refuse possible leaked file descriptors
7464 if (icicle != null && icicle.hasFileDescriptors()) {
7465 throw new IllegalArgumentException("File descriptors passed in Bundle");
7468 final long origId = Binder.clearCallingIdentity();
7470 synchronized (this) {
7471 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7473 r.activityStoppedLocked(icicle, persistentState, description);
7479 Binder.restoreCallingIdentity(origId);
7483 public final void activityDestroyed(IBinder token) {
7484 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7485 synchronized (this) {
7486 ActivityStack stack = ActivityRecord.getStackLocked(token);
7487 if (stack != null) {
7488 stack.activityDestroyedLocked(token, "activityDestroyed");
7494 public final void activityRelaunched(IBinder token) {
7495 final long origId = Binder.clearCallingIdentity();
7496 synchronized (this) {
7497 mStackSupervisor.activityRelaunchedLocked(token);
7499 Binder.restoreCallingIdentity(origId);
7503 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7504 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7505 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7506 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7507 synchronized (this) {
7508 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7509 if (record == null) {
7510 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7511 + "found for: " + token);
7513 record.setSizeConfigurations(horizontalSizeConfiguration,
7514 verticalSizeConfigurations, smallestSizeConfigurations);
7519 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7520 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7524 public final void notifyEnterAnimationComplete(IBinder token) {
7525 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7529 public String getCallingPackage(IBinder token) {
7530 synchronized (this) {
7531 ActivityRecord r = getCallingRecordLocked(token);
7532 return r != null ? r.info.packageName : null;
7537 public ComponentName getCallingActivity(IBinder token) {
7538 synchronized (this) {
7539 ActivityRecord r = getCallingRecordLocked(token);
7540 return r != null ? r.intent.getComponent() : null;
7544 private ActivityRecord getCallingRecordLocked(IBinder token) {
7545 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7553 public ComponentName getActivityClassForToken(IBinder token) {
7554 synchronized(this) {
7555 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7559 return r.intent.getComponent();
7564 public String getPackageForToken(IBinder token) {
7565 synchronized(this) {
7566 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7570 return r.packageName;
7575 public boolean isRootVoiceInteraction(IBinder token) {
7576 synchronized(this) {
7577 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7581 return r.rootVoiceInteraction;
7586 public IIntentSender getIntentSender(int type,
7587 String packageName, IBinder token, String resultWho,
7588 int requestCode, Intent[] intents, String[] resolvedTypes,
7589 int flags, Bundle bOptions, int userId) {
7590 enforceNotIsolatedCaller("getIntentSender");
7591 // Refuse possible leaked file descriptors
7592 if (intents != null) {
7593 if (intents.length < 1) {
7594 throw new IllegalArgumentException("Intents array length must be >= 1");
7596 for (int i=0; i<intents.length; i++) {
7597 Intent intent = intents[i];
7598 if (intent != null) {
7599 if (intent.hasFileDescriptors()) {
7600 throw new IllegalArgumentException("File descriptors passed in Intent");
7602 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7603 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7604 throw new IllegalArgumentException(
7605 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7607 intents[i] = new Intent(intent);
7610 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7611 throw new IllegalArgumentException(
7612 "Intent array length does not match resolvedTypes length");
7615 if (bOptions != null) {
7616 if (bOptions.hasFileDescriptors()) {
7617 throw new IllegalArgumentException("File descriptors passed in options");
7621 synchronized(this) {
7622 int callingUid = Binder.getCallingUid();
7623 int origUserId = userId;
7624 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7625 type == ActivityManager.INTENT_SENDER_BROADCAST,
7626 ALLOW_NON_FULL, "getIntentSender", null);
7627 if (origUserId == UserHandle.USER_CURRENT) {
7628 // We don't want to evaluate this until the pending intent is
7629 // actually executed. However, we do want to always do the
7630 // security checking for it above.
7631 userId = UserHandle.USER_CURRENT;
7634 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7635 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7636 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7637 if (!UserHandle.isSameApp(callingUid, uid)) {
7638 String msg = "Permission Denial: getIntentSender() from pid="
7639 + Binder.getCallingPid()
7640 + ", uid=" + Binder.getCallingUid()
7641 + ", (need uid=" + uid + ")"
7642 + " is not allowed to send as package " + packageName;
7644 throw new SecurityException(msg);
7648 return getIntentSenderLocked(type, packageName, callingUid, userId,
7649 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7651 } catch (RemoteException e) {
7652 throw new SecurityException(e);
7657 IIntentSender getIntentSenderLocked(int type, String packageName,
7658 int callingUid, int userId, IBinder token, String resultWho,
7659 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7661 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7662 ActivityRecord activity = null;
7663 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7664 activity = ActivityRecord.isInStackLocked(token);
7665 if (activity == null) {
7666 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7669 if (activity.finishing) {
7670 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7675 // We're going to be splicing together extras before sending, so we're
7676 // okay poking into any contained extras.
7677 if (intents != null) {
7678 for (int i = 0; i < intents.length; i++) {
7679 intents[i].setDefusable(true);
7682 Bundle.setDefusable(bOptions, true);
7684 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7685 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7686 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7687 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7688 |PendingIntent.FLAG_UPDATE_CURRENT);
7690 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7691 type, packageName, activity, resultWho,
7692 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7693 WeakReference<PendingIntentRecord> ref;
7694 ref = mIntentSenderRecords.get(key);
7695 PendingIntentRecord rec = ref != null ? ref.get() : null;
7697 if (!cancelCurrent) {
7698 if (updateCurrent) {
7699 if (rec.key.requestIntent != null) {
7700 rec.key.requestIntent.replaceExtras(intents != null ?
7701 intents[intents.length - 1] : null);
7703 if (intents != null) {
7704 intents[intents.length-1] = rec.key.requestIntent;
7705 rec.key.allIntents = intents;
7706 rec.key.allResolvedTypes = resolvedTypes;
7708 rec.key.allIntents = null;
7709 rec.key.allResolvedTypes = null;
7714 makeIntentSenderCanceledLocked(rec);
7715 mIntentSenderRecords.remove(key);
7720 rec = new PendingIntentRecord(this, key, callingUid);
7721 mIntentSenderRecords.put(key, rec.ref);
7722 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7723 if (activity.pendingResults == null) {
7724 activity.pendingResults
7725 = new HashSet<WeakReference<PendingIntentRecord>>();
7727 activity.pendingResults.add(rec.ref);
7733 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7734 Intent intent, String resolvedType,
7735 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7736 if (target instanceof PendingIntentRecord) {
7737 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7738 whitelistToken, finishedReceiver, requiredPermission, options);
7740 if (intent == null) {
7741 // Weird case: someone has given us their own custom IIntentSender, and now
7742 // they have someone else trying to send to it but of course this isn't
7743 // really a PendingIntent, so there is no base Intent, and the caller isn't
7744 // supplying an Intent... but we never want to dispatch a null Intent to
7745 // a receiver, so um... let's make something up.
7746 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7747 intent = new Intent(Intent.ACTION_MAIN);
7750 target.send(code, intent, resolvedType, whitelistToken, null,
7751 requiredPermission, options);
7752 } catch (RemoteException e) {
7754 // Platform code can rely on getting a result back when the send is done, but if
7755 // this intent sender is from outside of the system we can't rely on it doing that.
7756 // So instead we don't give it the result receiver, and instead just directly
7757 // report the finish immediately.
7758 if (finishedReceiver != null) {
7760 finishedReceiver.performReceive(intent, 0,
7761 null, null, false, false, UserHandle.getCallingUserId());
7762 } catch (RemoteException e) {
7770 public void cancelIntentSender(IIntentSender sender) {
7771 if (!(sender instanceof PendingIntentRecord)) {
7774 synchronized(this) {
7775 PendingIntentRecord rec = (PendingIntentRecord)sender;
7777 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7778 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7779 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7780 String msg = "Permission Denial: cancelIntentSender() from pid="
7781 + Binder.getCallingPid()
7782 + ", uid=" + Binder.getCallingUid()
7783 + " is not allowed to cancel package "
7784 + rec.key.packageName;
7786 throw new SecurityException(msg);
7788 } catch (RemoteException e) {
7789 throw new SecurityException(e);
7791 cancelIntentSenderLocked(rec, true);
7795 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7796 makeIntentSenderCanceledLocked(rec);
7797 mIntentSenderRecords.remove(rec.key);
7798 if (cleanActivity && rec.key.activity != null) {
7799 rec.key.activity.pendingResults.remove(rec.ref);
7803 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7804 rec.canceled = true;
7805 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7806 if (callbacks != null) {
7807 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7812 public String getPackageForIntentSender(IIntentSender pendingResult) {
7813 if (!(pendingResult instanceof PendingIntentRecord)) {
7817 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7818 return res.key.packageName;
7819 } catch (ClassCastException e) {
7825 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7826 if (!(sender instanceof PendingIntentRecord)) {
7829 synchronized(this) {
7830 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7835 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7836 IResultReceiver receiver) {
7837 if (!(sender instanceof PendingIntentRecord)) {
7840 synchronized(this) {
7841 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7846 public int getUidForIntentSender(IIntentSender sender) {
7847 if (sender instanceof PendingIntentRecord) {
7849 PendingIntentRecord res = (PendingIntentRecord)sender;
7851 } catch (ClassCastException e) {
7858 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7859 if (!(pendingResult instanceof PendingIntentRecord)) {
7863 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7864 if (res.key.allIntents == null) {
7867 for (int i=0; i<res.key.allIntents.length; i++) {
7868 Intent intent = res.key.allIntents[i];
7869 if (intent.getPackage() != null && intent.getComponent() != null) {
7874 } catch (ClassCastException e) {
7880 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7881 if (!(pendingResult instanceof PendingIntentRecord)) {
7885 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7886 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7890 } catch (ClassCastException e) {
7896 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7897 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7898 "getIntentForIntentSender()");
7899 if (!(pendingResult instanceof PendingIntentRecord)) {
7903 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7904 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7905 } catch (ClassCastException e) {
7911 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7912 if (!(pendingResult instanceof PendingIntentRecord)) {
7916 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7917 synchronized (this) {
7918 return getTagForIntentSenderLocked(res, prefix);
7920 } catch (ClassCastException e) {
7925 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7926 final Intent intent = res.key.requestIntent;
7927 if (intent != null) {
7928 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7929 || res.lastTagPrefix.equals(prefix))) {
7932 res.lastTagPrefix = prefix;
7933 final StringBuilder sb = new StringBuilder(128);
7934 if (prefix != null) {
7937 if (intent.getAction() != null) {
7938 sb.append(intent.getAction());
7939 } else if (intent.getComponent() != null) {
7940 intent.getComponent().appendShortString(sb);
7944 return res.lastTag = sb.toString();
7950 public void setProcessLimit(int max) {
7951 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7952 "setProcessLimit()");
7953 synchronized (this) {
7954 mConstants.setOverrideMaxCachedProcesses(max);
7960 public int getProcessLimit() {
7961 synchronized (this) {
7962 return mConstants.getOverrideMaxCachedProcesses();
7966 void importanceTokenDied(ImportanceToken token) {
7967 synchronized (ActivityManagerService.this) {
7968 synchronized (mPidsSelfLocked) {
7970 = mImportantProcesses.get(token.pid);
7974 mImportantProcesses.remove(token.pid);
7975 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7979 pr.forcingToImportant = null;
7980 updateProcessForegroundLocked(pr, false, false);
7982 updateOomAdjLocked();
7987 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7988 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7989 "setProcessImportant()");
7990 synchronized(this) {
7991 boolean changed = false;
7993 synchronized (mPidsSelfLocked) {
7994 ProcessRecord pr = mPidsSelfLocked.get(pid);
7995 if (pr == null && isForeground) {
7996 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7999 ImportanceToken oldToken = mImportantProcesses.get(pid);
8000 if (oldToken != null) {
8001 oldToken.token.unlinkToDeath(oldToken, 0);
8002 mImportantProcesses.remove(pid);
8004 pr.forcingToImportant = null;
8008 if (isForeground && token != null) {
8009 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8011 public void binderDied() {
8012 importanceTokenDied(this);
8016 token.linkToDeath(newToken, 0);
8017 mImportantProcesses.put(pid, newToken);
8018 pr.forcingToImportant = newToken;
8020 } catch (RemoteException e) {
8021 // If the process died while doing this, we will later
8022 // do the cleanup with the process death link.
8028 updateOomAdjLocked();
8034 public boolean isAppForeground(int uid) throws RemoteException {
8035 synchronized (this) {
8036 UidRecord uidRec = mActiveUids.get(uid);
8037 if (uidRec == null || uidRec.idle) {
8040 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8044 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8045 // be guarded by permission checking.
8046 int getUidState(int uid) {
8047 synchronized (this) {
8048 return getUidStateLocked(uid);
8052 int getUidStateLocked(int uid) {
8053 UidRecord uidRec = mActiveUids.get(uid);
8054 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8058 public boolean isInMultiWindowMode(IBinder token) {
8059 final long origId = Binder.clearCallingIdentity();
8061 synchronized(this) {
8062 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8066 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8067 return !r.getTask().mFullscreen;
8070 Binder.restoreCallingIdentity(origId);
8075 public boolean isInPictureInPictureMode(IBinder token) {
8076 final long origId = Binder.clearCallingIdentity();
8078 synchronized(this) {
8079 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8082 Binder.restoreCallingIdentity(origId);
8086 private boolean isInPictureInPictureMode(ActivityRecord r) {
8087 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8088 r.getStack().isInStackLocked(r) == null) {
8092 // If we are animating to fullscreen then we have already dispatched the PIP mode
8093 // changed, so we should reflect that check here as well.
8094 final PinnedActivityStack stack = r.getStack();
8095 final PinnedStackWindowController windowController = stack.getWindowContainerController();
8096 return !windowController.isAnimatingBoundsToFullscreen();
8100 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8101 final long origId = Binder.clearCallingIdentity();
8103 synchronized(this) {
8104 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8105 "enterPictureInPictureMode", token, params);
8107 // If the activity is already in picture in picture mode, then just return early
8108 if (isInPictureInPictureMode(r)) {
8112 // Activity supports picture-in-picture, now check that we can enter PiP at this
8114 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8115 false /* beforeStopping */)) {
8119 final Runnable enterPipRunnable = () -> {
8120 // Only update the saved args from the args that are set
8121 r.pictureInPictureArgs.copyOnlySet(params);
8122 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8123 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8124 // Adjust the source bounds by the insets for the transition down
8125 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8126 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8127 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8128 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8129 stack.setPictureInPictureAspectRatio(aspectRatio);
8130 stack.setPictureInPictureActions(actions);
8132 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8133 r.supportsEnterPipOnTaskSwitch);
8134 logPictureInPictureArgs(params);
8137 if (isKeyguardLocked()) {
8138 // If the keyguard is showing or occluded, then try and dismiss it before
8139 // entering picture-in-picture (this will prompt the user to authenticate if the
8140 // device is currently locked).
8142 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8144 public void onDismissError() throws RemoteException {
8149 public void onDismissSucceeded() throws RemoteException {
8150 mHandler.post(enterPipRunnable);
8154 public void onDismissCancelled() throws RemoteException {
8158 } catch (RemoteException e) {
8162 // Enter picture in picture immediately otherwise
8163 enterPipRunnable.run();
8168 Binder.restoreCallingIdentity(origId);
8173 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8174 final long origId = Binder.clearCallingIdentity();
8176 synchronized(this) {
8177 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8178 "setPictureInPictureParams", token, params);
8180 // Only update the saved args from the args that are set
8181 r.pictureInPictureArgs.copyOnlySet(params);
8182 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8183 // If the activity is already in picture-in-picture, update the pinned stack now
8184 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8185 // be used the next time the activity enters PiP
8186 final PinnedActivityStack stack = r.getStack();
8187 if (!stack.isAnimatingBoundsToFullscreen()) {
8188 stack.setPictureInPictureAspectRatio(
8189 r.pictureInPictureArgs.getAspectRatio());
8190 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8193 logPictureInPictureArgs(params);
8196 Binder.restoreCallingIdentity(origId);
8201 public int getMaxNumPictureInPictureActions(IBinder token) {
8202 // Currently, this is a static constant, but later, we may change this to be dependent on
8203 // the context of the activity
8207 private void logPictureInPictureArgs(PictureInPictureParams params) {
8208 if (params.hasSetActions()) {
8209 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8210 params.getActions().size());
8212 if (params.hasSetAspectRatio()) {
8213 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8214 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8215 MetricsLogger.action(lm);
8220 * Checks the state of the system and the activity associated with the given {@param token} to
8221 * verify that picture-in-picture is supported for that activity.
8223 * @return the activity record for the given {@param token} if all the checks pass.
8225 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8226 IBinder token, PictureInPictureParams params) {
8227 if (!mSupportsPictureInPicture) {
8228 throw new IllegalStateException(caller
8229 + ": Device doesn't support picture-in-picture mode.");
8232 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8234 throw new IllegalStateException(caller
8235 + ": Can't find activity for token=" + token);
8238 if (!r.supportsPictureInPicture()) {
8239 throw new IllegalStateException(caller
8240 + ": Current activity does not support picture-in-picture.");
8243 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8244 throw new IllegalStateException(caller
8245 + ": Activities on the home, assistant, or recents stack not supported");
8248 if (params.hasSetAspectRatio()
8249 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8250 params.getAspectRatio())) {
8251 final float minAspectRatio = mContext.getResources().getFloat(
8252 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8253 final float maxAspectRatio = mContext.getResources().getFloat(
8254 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8255 throw new IllegalArgumentException(String.format(caller
8256 + ": Aspect ratio is too extreme (must be between %f and %f).",
8257 minAspectRatio, maxAspectRatio));
8260 // Truncate the number of actions if necessary
8261 params.truncateActions(getMaxNumPictureInPictureActions(token));
8266 // =========================================================
8268 // =========================================================
8270 static class ProcessInfoService extends IProcessInfoService.Stub {
8271 final ActivityManagerService mActivityManagerService;
8272 ProcessInfoService(ActivityManagerService activityManagerService) {
8273 mActivityManagerService = activityManagerService;
8277 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8278 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8279 /*in*/ pids, /*out*/ states, null);
8283 public void getProcessStatesAndOomScoresFromPids(
8284 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8285 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8286 /*in*/ pids, /*out*/ states, /*out*/ scores);
8291 * For each PID in the given input array, write the current process state
8292 * for that process into the states array, or -1 to indicate that no
8293 * process with the given PID exists. If scores array is provided, write
8294 * the oom score for the process into the scores array, with INVALID_ADJ
8295 * indicating the PID doesn't exist.
8297 public void getProcessStatesAndOomScoresForPIDs(
8298 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8299 if (scores != null) {
8300 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8301 "getProcessStatesAndOomScoresForPIDs()");
8305 throw new NullPointerException("pids");
8306 } else if (states == null) {
8307 throw new NullPointerException("states");
8308 } else if (pids.length != states.length) {
8309 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8310 } else if (scores != null && pids.length != scores.length) {
8311 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8314 synchronized (mPidsSelfLocked) {
8315 for (int i = 0; i < pids.length; i++) {
8316 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8317 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8319 if (scores != null) {
8320 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8326 // =========================================================
8328 // =========================================================
8330 static class PermissionController extends IPermissionController.Stub {
8331 ActivityManagerService mActivityManagerService;
8332 PermissionController(ActivityManagerService activityManagerService) {
8333 mActivityManagerService = activityManagerService;
8337 public boolean checkPermission(String permission, int pid, int uid) {
8338 return mActivityManagerService.checkPermission(permission, pid,
8339 uid) == PackageManager.PERMISSION_GRANTED;
8343 public String[] getPackagesForUid(int uid) {
8344 return mActivityManagerService.mContext.getPackageManager()
8345 .getPackagesForUid(uid);
8349 public boolean isRuntimePermission(String permission) {
8351 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8352 .getPermissionInfo(permission, 0);
8353 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8354 == PermissionInfo.PROTECTION_DANGEROUS;
8355 } catch (NameNotFoundException nnfe) {
8356 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8362 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8364 public int checkComponentPermission(String permission, int pid, int uid,
8365 int owningUid, boolean exported) {
8366 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8367 owningUid, exported);
8371 public Object getAMSLock() {
8372 return ActivityManagerService.this;
8377 * This can be called with or without the global lock held.
8379 int checkComponentPermission(String permission, int pid, int uid,
8380 int owningUid, boolean exported) {
8381 if (pid == MY_PID) {
8382 return PackageManager.PERMISSION_GRANTED;
8384 return ActivityManager.checkComponentPermission(permission, uid,
8385 owningUid, exported);
8389 * As the only public entry point for permissions checking, this method
8390 * can enforce the semantic that requesting a check on a null global
8391 * permission is automatically denied. (Internally a null permission
8392 * string is used when calling {@link #checkComponentPermission} in cases
8393 * when only uid-based security is needed.)
8395 * This can be called with or without the global lock held.
8398 public int checkPermission(String permission, int pid, int uid) {
8399 if (permission == null) {
8400 return PackageManager.PERMISSION_DENIED;
8402 return checkComponentPermission(permission, pid, uid, -1, true);
8406 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8407 if (permission == null) {
8408 return PackageManager.PERMISSION_DENIED;
8411 // We might be performing an operation on behalf of an indirect binder
8412 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8413 // client identity accordingly before proceeding.
8414 Identity tlsIdentity = sCallerIdentity.get();
8415 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8416 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8417 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8418 uid = tlsIdentity.uid;
8419 pid = tlsIdentity.pid;
8422 return checkComponentPermission(permission, pid, uid, -1, true);
8426 * Binder IPC calls go through the public entry point.
8427 * This can be called with or without the global lock held.
8429 int checkCallingPermission(String permission) {
8430 return checkPermission(permission,
8431 Binder.getCallingPid(),
8432 UserHandle.getAppId(Binder.getCallingUid()));
8436 * This can be called with or without the global lock held.
8438 void enforceCallingPermission(String permission, String func) {
8439 if (checkCallingPermission(permission)
8440 == PackageManager.PERMISSION_GRANTED) {
8444 String msg = "Permission Denial: " + func + " from pid="
8445 + Binder.getCallingPid()
8446 + ", uid=" + Binder.getCallingUid()
8447 + " requires " + permission;
8449 throw new SecurityException(msg);
8453 * Determine if UID is holding permissions required to access {@link Uri} in
8454 * the given {@link ProviderInfo}. Final permission checking is always done
8455 * in {@link ContentProvider}.
8457 private final boolean checkHoldingPermissionsLocked(
8458 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8459 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8460 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8461 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8462 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8463 != PERMISSION_GRANTED) {
8467 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8470 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8471 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8472 if (pi.applicationInfo.uid == uid) {
8474 } else if (!pi.exported) {
8478 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8479 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8481 // check if target holds top-level <provider> permissions
8482 if (!readMet && pi.readPermission != null && considerUidPermissions
8483 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8486 if (!writeMet && pi.writePermission != null && considerUidPermissions
8487 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8491 // track if unprotected read/write is allowed; any denied
8492 // <path-permission> below removes this ability
8493 boolean allowDefaultRead = pi.readPermission == null;
8494 boolean allowDefaultWrite = pi.writePermission == null;
8496 // check if target holds any <path-permission> that match uri
8497 final PathPermission[] pps = pi.pathPermissions;
8499 final String path = grantUri.uri.getPath();
8501 while (i > 0 && (!readMet || !writeMet)) {
8503 PathPermission pp = pps[i];
8504 if (pp.match(path)) {
8506 final String pprperm = pp.getReadPermission();
8507 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8508 "Checking read perm for " + pprperm + " for " + pp.getPath()
8509 + ": match=" + pp.match(path)
8510 + " check=" + pm.checkUidPermission(pprperm, uid));
8511 if (pprperm != null) {
8512 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8513 == PERMISSION_GRANTED) {
8516 allowDefaultRead = false;
8521 final String ppwperm = pp.getWritePermission();
8522 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8523 "Checking write perm " + ppwperm + " for " + pp.getPath()
8524 + ": match=" + pp.match(path)
8525 + " check=" + pm.checkUidPermission(ppwperm, uid));
8526 if (ppwperm != null) {
8527 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8528 == PERMISSION_GRANTED) {
8531 allowDefaultWrite = false;
8539 // grant unprotected <provider> read/write, if not blocked by
8540 // <path-permission> above
8541 if (allowDefaultRead) readMet = true;
8542 if (allowDefaultWrite) writeMet = true;
8544 } catch (RemoteException e) {
8548 return readMet && writeMet;
8551 public boolean isAppStartModeDisabled(int uid, String packageName) {
8552 synchronized (this) {
8553 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8554 == ActivityManager.APP_START_MODE_DISABLED;
8558 // Unified app-op and target sdk check
8559 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8560 // Apps that target O+ are always subject to background check
8561 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8562 if (DEBUG_BACKGROUND_CHECK) {
8563 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8565 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8567 // ...and legacy apps get an AppOp check
8568 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8570 if (DEBUG_BACKGROUND_CHECK) {
8571 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8574 case AppOpsManager.MODE_ALLOWED:
8575 return ActivityManager.APP_START_MODE_NORMAL;
8576 case AppOpsManager.MODE_IGNORED:
8577 return ActivityManager.APP_START_MODE_DELAYED;
8579 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8583 // Service launch is available to apps with run-in-background exemptions but
8584 // some other background operations are not. If we're doing a check
8585 // of service-launch policy, allow those callers to proceed unrestricted.
8586 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8588 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8589 if (DEBUG_BACKGROUND_CHECK) {
8590 Slog.i(TAG, "App " + uid + "/" + packageName
8591 + " is persistent; not restricted in background");
8593 return ActivityManager.APP_START_MODE_NORMAL;
8596 // Non-persistent but background whitelisted?
8597 if (uidOnBackgroundWhitelist(uid)) {
8598 if (DEBUG_BACKGROUND_CHECK) {
8599 Slog.i(TAG, "App " + uid + "/" + packageName
8600 + " on background whitelist; not restricted in background");
8602 return ActivityManager.APP_START_MODE_NORMAL;
8605 // Is this app on the battery whitelist?
8606 if (isOnDeviceIdleWhitelistLocked(uid)) {
8607 if (DEBUG_BACKGROUND_CHECK) {
8608 Slog.i(TAG, "App " + uid + "/" + packageName
8609 + " on idle whitelist; not restricted in background");
8611 return ActivityManager.APP_START_MODE_NORMAL;
8614 // None of the service-policy criteria apply, so we apply the common criteria
8615 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8618 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8619 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8620 UidRecord uidRec = mActiveUids.get(uid);
8621 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8622 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8623 + (uidRec != null ? uidRec.idle : false));
8624 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8626 if (uidRec == null) {
8627 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8628 UserHandle.getUserId(uid), packageName);
8630 ephemeral = uidRec.ephemeral;
8634 // We are hard-core about ephemeral apps not running in the background.
8635 return ActivityManager.APP_START_MODE_DISABLED;
8638 // The caller is only interested in whether app starts are completely
8639 // disabled for the given package (that is, it is an instant app). So
8640 // we don't need to go further, which is all just seeing if we should
8641 // apply a "delayed" mode for a regular app.
8642 return ActivityManager.APP_START_MODE_NORMAL;
8644 final int startMode = (alwaysRestrict)
8645 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8646 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8648 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8649 + " pkg=" + packageName + " startMode=" + startMode
8650 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8651 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8652 // This is an old app that has been forced into a "compatible as possible"
8653 // mode of background check. To increase compatibility, we will allow other
8654 // foreground apps to cause its services to start.
8655 if (callingPid >= 0) {
8657 synchronized (mPidsSelfLocked) {
8658 proc = mPidsSelfLocked.get(callingPid);
8661 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8662 // Whoever is instigating this is in the foreground, so we will allow it
8664 return ActivityManager.APP_START_MODE_NORMAL;
8671 return ActivityManager.APP_START_MODE_NORMAL;
8674 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8675 final int appId = UserHandle.getAppId(uid);
8676 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8677 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8678 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8681 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8682 ProviderInfo pi = null;
8683 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8688 pi = AppGlobals.getPackageManager().resolveContentProvider(
8689 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8691 } catch (RemoteException ex) {
8697 void grantEphemeralAccessLocked(int userId, Intent intent,
8698 int targetAppId, int ephemeralAppId) {
8699 getPackageManagerInternalLocked().
8700 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8703 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8704 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8705 if (targetUris != null) {
8706 return targetUris.get(grantUri);
8711 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8712 String targetPkg, int targetUid, GrantUri grantUri) {
8713 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8714 if (targetUris == null) {
8715 targetUris = Maps.newArrayMap();
8716 mGrantedUriPermissions.put(targetUid, targetUris);
8719 UriPermission perm = targetUris.get(grantUri);
8721 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8722 targetUris.put(grantUri, perm);
8728 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8729 final int modeFlags) {
8730 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8731 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8732 : UriPermission.STRENGTH_OWNED;
8734 // Root gets to do everything.
8739 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8740 if (perms == null) return false;
8742 // First look for exact match
8743 final UriPermission exactPerm = perms.get(grantUri);
8744 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8748 // No exact match, look for prefixes
8749 final int N = perms.size();
8750 for (int i = 0; i < N; i++) {
8751 final UriPermission perm = perms.valueAt(i);
8752 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8753 && perm.getStrength(modeFlags) >= minStrength) {
8762 * @param uri This uri must NOT contain an embedded userId.
8763 * @param userId The userId in which the uri is to be resolved.
8766 public int checkUriPermission(Uri uri, int pid, int uid,
8767 final int modeFlags, int userId, IBinder callerToken) {
8768 enforceNotIsolatedCaller("checkUriPermission");
8770 // Another redirected-binder-call permissions check as in
8771 // {@link checkPermissionWithToken}.
8772 Identity tlsIdentity = sCallerIdentity.get();
8773 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8774 uid = tlsIdentity.uid;
8775 pid = tlsIdentity.pid;
8778 // Our own process gets to do everything.
8779 if (pid == MY_PID) {
8780 return PackageManager.PERMISSION_GRANTED;
8782 synchronized (this) {
8783 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8784 ? PackageManager.PERMISSION_GRANTED
8785 : PackageManager.PERMISSION_DENIED;
8790 * Check if the targetPkg can be granted permission to access uri by
8791 * the callingUid using the given modeFlags. Throws a security exception
8792 * if callingUid is not allowed to do this. Returns the uid of the target
8793 * if the URI permission grant should be performed; returns -1 if it is not
8794 * needed (for example targetPkg already has permission to access the URI).
8795 * If you already know the uid of the target, you can supply it in
8796 * lastTargetUid else set that to -1.
8798 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8799 final int modeFlags, int lastTargetUid) {
8800 if (!Intent.isAccessUriMode(modeFlags)) {
8804 if (targetPkg != null) {
8805 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8806 "Checking grant " + targetPkg + " permission to " + grantUri);
8809 final IPackageManager pm = AppGlobals.getPackageManager();
8811 // If this is not a content: uri, we can't do anything with it.
8812 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8813 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8814 "Can't grant URI permission for non-content URI: " + grantUri);
8818 // Bail early if system is trying to hand out permissions directly; it
8819 // must always grant permissions on behalf of someone explicit.
8820 final int callingAppId = UserHandle.getAppId(callingUid);
8821 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8822 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8823 // Exempted authority for cropping user photos in Settings app
8825 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8826 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8831 final String authority = grantUri.uri.getAuthority();
8832 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8833 MATCH_DEBUG_TRIAGED_MISSING);
8835 Slog.w(TAG, "No content provider found for permission check: " +
8836 grantUri.uri.toSafeString());
8840 int targetUid = lastTargetUid;
8841 if (targetUid < 0 && targetPkg != null) {
8843 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8844 UserHandle.getUserId(callingUid));
8845 if (targetUid < 0) {
8846 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8847 "Can't grant URI permission no uid for: " + targetPkg);
8850 } catch (RemoteException ex) {
8855 // Figure out the value returned when access is allowed
8856 final int allowedResult;
8857 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8858 // If we're extending a persistable grant, then we need to return
8859 // "targetUid" so that we always create a grant data structure to
8860 // support take/release APIs
8861 allowedResult = targetUid;
8863 // Otherwise, we can return "-1" to indicate that no grant data
8864 // structures need to be created
8868 if (targetUid >= 0) {
8869 // First... does the target actually need this permission?
8870 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8871 // No need to grant the target this permission.
8872 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8873 "Target " + targetPkg + " already has full permission to " + grantUri);
8874 return allowedResult;
8877 // First... there is no target package, so can anyone access it?
8878 boolean allowed = pi.exported;
8879 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8880 if (pi.readPermission != null) {
8884 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8885 if (pi.writePermission != null) {
8890 return allowedResult;
8894 /* There is a special cross user grant if:
8895 * - The target is on another user.
8896 * - Apps on the current user can access the uri without any uid permissions.
8897 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8898 * grant uri permissions.
8900 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8901 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8902 modeFlags, false /*without considering the uid permissions*/);
8904 // Second... is the provider allowing granting of URI permissions?
8905 if (!specialCrossUserGrant) {
8906 if (!pi.grantUriPermissions) {
8907 throw new SecurityException("Provider " + pi.packageName
8909 + " does not allow granting of Uri permissions (uri "
8912 if (pi.uriPermissionPatterns != null) {
8913 final int N = pi.uriPermissionPatterns.length;
8914 boolean allowed = false;
8915 for (int i=0; i<N; i++) {
8916 if (pi.uriPermissionPatterns[i] != null
8917 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8923 throw new SecurityException("Provider " + pi.packageName
8925 + " does not allow granting of permission to path of Uri "
8931 // Third... does the caller itself have permission to access
8933 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8934 // Require they hold a strong enough Uri permission
8935 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8936 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8937 throw new SecurityException(
8938 "UID " + callingUid + " does not have permission to " + grantUri
8939 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8940 + "or related APIs");
8942 throw new SecurityException(
8943 "UID " + callingUid + " does not have permission to " + grantUri);
8951 * @param uri This uri must NOT contain an embedded userId.
8952 * @param userId The userId in which the uri is to be resolved.
8955 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8956 final int modeFlags, int userId) {
8957 enforceNotIsolatedCaller("checkGrantUriPermission");
8958 synchronized(this) {
8959 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8960 new GrantUri(userId, uri, false), modeFlags, -1);
8964 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8965 final int modeFlags, UriPermissionOwner owner) {
8966 if (!Intent.isAccessUriMode(modeFlags)) {
8970 // So here we are: the caller has the assumed permission
8971 // to the uri, and the target doesn't. Let's now give this to
8974 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8975 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8977 final String authority = grantUri.uri.getAuthority();
8978 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8979 MATCH_DEBUG_TRIAGED_MISSING);
8981 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8985 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8986 grantUri.prefix = true;
8988 final UriPermission perm = findOrCreateUriPermissionLocked(
8989 pi.packageName, targetPkg, targetUid, grantUri);
8990 perm.grantModes(modeFlags, owner);
8993 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8994 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8995 if (targetPkg == null) {
8996 throw new NullPointerException("targetPkg");
8999 final IPackageManager pm = AppGlobals.getPackageManager();
9001 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9002 } catch (RemoteException ex) {
9006 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9008 if (targetUid < 0) {
9012 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9016 static class NeededUriGrants extends ArrayList<GrantUri> {
9017 final String targetPkg;
9018 final int targetUid;
9021 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9022 this.targetPkg = targetPkg;
9023 this.targetUid = targetUid;
9029 * Like checkGrantUriPermissionLocked, but takes an Intent.
9031 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9032 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9033 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9034 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9035 + " clip=" + (intent != null ? intent.getClipData() : null)
9036 + " from " + intent + "; flags=0x"
9037 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9039 if (targetPkg == null) {
9040 throw new NullPointerException("targetPkg");
9043 if (intent == null) {
9046 Uri data = intent.getData();
9047 ClipData clip = intent.getClipData();
9048 if (data == null && clip == null) {
9051 // Default userId for uris in the intent (if they don't specify it themselves)
9052 int contentUserHint = intent.getContentUserHint();
9053 if (contentUserHint == UserHandle.USER_CURRENT) {
9054 contentUserHint = UserHandle.getUserId(callingUid);
9056 final IPackageManager pm = AppGlobals.getPackageManager();
9058 if (needed != null) {
9059 targetUid = needed.targetUid;
9062 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9064 } catch (RemoteException ex) {
9067 if (targetUid < 0) {
9068 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9069 "Can't grant URI permission no uid for: " + targetPkg
9070 + " on user " + targetUserId);
9075 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9076 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9078 if (targetUid > 0) {
9079 if (needed == null) {
9080 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9082 needed.add(grantUri);
9086 for (int i=0; i<clip.getItemCount(); i++) {
9087 Uri uri = clip.getItemAt(i).getUri();
9089 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9090 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9092 if (targetUid > 0) {
9093 if (needed == null) {
9094 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9096 needed.add(grantUri);
9099 Intent clipIntent = clip.getItemAt(i).getIntent();
9100 if (clipIntent != null) {
9101 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9102 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9103 if (newNeeded != null) {
9115 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9117 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9118 UriPermissionOwner owner) {
9119 if (needed != null) {
9120 for (int i=0; i<needed.size(); i++) {
9121 GrantUri grantUri = needed.get(i);
9122 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9123 grantUri, needed.flags, owner);
9128 void grantUriPermissionFromIntentLocked(int callingUid,
9129 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9130 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9131 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9132 if (needed == null) {
9136 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9140 * @param uri This uri must NOT contain an embedded userId.
9141 * @param userId The userId in which the uri is to be resolved.
9144 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9145 final int modeFlags, int userId) {
9146 enforceNotIsolatedCaller("grantUriPermission");
9147 GrantUri grantUri = new GrantUri(userId, uri, false);
9148 synchronized(this) {
9149 final ProcessRecord r = getRecordForAppLocked(caller);
9151 throw new SecurityException("Unable to find app for caller "
9153 + " when granting permission to uri " + grantUri);
9155 if (targetPkg == null) {
9156 throw new IllegalArgumentException("null target");
9158 if (grantUri == null) {
9159 throw new IllegalArgumentException("null uri");
9162 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9163 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9164 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9165 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9167 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9168 UserHandle.getUserId(r.uid));
9172 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9173 if (perm.modeFlags == 0) {
9174 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9176 if (perms != null) {
9177 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9178 "Removing " + perm.targetUid + " permission to " + perm.uri);
9180 perms.remove(perm.uri);
9181 if (perms.isEmpty()) {
9182 mGrantedUriPermissions.remove(perm.targetUid);
9188 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9189 final int modeFlags) {
9190 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9191 "Revoking all granted permissions to " + grantUri);
9193 final IPackageManager pm = AppGlobals.getPackageManager();
9194 final String authority = grantUri.uri.getAuthority();
9195 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9196 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9198 Slog.w(TAG, "No content provider found for permission revoke: "
9199 + grantUri.toSafeString());
9203 // Does the caller have this permission on the URI?
9204 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9205 // If they don't have direct access to the URI, then revoke any
9206 // ownerless URI permissions that have been granted to them.
9207 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9208 if (perms != null) {
9209 boolean persistChanged = false;
9210 for (int i = perms.size()-1; i >= 0; i--) {
9211 final UriPermission perm = perms.valueAt(i);
9212 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9215 if (perm.uri.sourceUserId == grantUri.sourceUserId
9216 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9217 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9218 "Revoking non-owned " + perm.targetUid
9219 + " permission to " + perm.uri);
9220 persistChanged |= perm.revokeModes(
9221 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9222 if (perm.modeFlags == 0) {
9227 if (perms.isEmpty()) {
9228 mGrantedUriPermissions.remove(callingUid);
9230 if (persistChanged) {
9231 schedulePersistUriGrants();
9237 boolean persistChanged = false;
9239 // Go through all of the permissions and remove any that match.
9240 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9241 final int targetUid = mGrantedUriPermissions.keyAt(i);
9242 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9244 for (int j = perms.size()-1; j >= 0; j--) {
9245 final UriPermission perm = perms.valueAt(j);
9246 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9249 if (perm.uri.sourceUserId == grantUri.sourceUserId
9250 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9251 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9252 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9253 persistChanged |= perm.revokeModes(
9254 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9255 targetPackage == null);
9256 if (perm.modeFlags == 0) {
9262 if (perms.isEmpty()) {
9263 mGrantedUriPermissions.removeAt(i);
9267 if (persistChanged) {
9268 schedulePersistUriGrants();
9273 * @param uri This uri must NOT contain an embedded userId.
9274 * @param userId The userId in which the uri is to be resolved.
9277 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9278 final int modeFlags, int userId) {
9279 enforceNotIsolatedCaller("revokeUriPermission");
9280 synchronized(this) {
9281 final ProcessRecord r = getRecordForAppLocked(caller);
9283 throw new SecurityException("Unable to find app for caller "
9285 + " when revoking permission to uri " + uri);
9288 Slog.w(TAG, "revokeUriPermission: null uri");
9292 if (!Intent.isAccessUriMode(modeFlags)) {
9296 final String authority = uri.getAuthority();
9297 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9298 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9300 Slog.w(TAG, "No content provider found for permission revoke: "
9301 + uri.toSafeString());
9305 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9311 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9314 * @param packageName Package name to match, or {@code null} to apply to all
9316 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9318 * @param persistable If persistable grants should be removed.
9320 private void removeUriPermissionsForPackageLocked(
9321 String packageName, int userHandle, boolean persistable) {
9322 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9323 throw new IllegalArgumentException("Must narrow by either package or user");
9326 boolean persistChanged = false;
9328 int N = mGrantedUriPermissions.size();
9329 for (int i = 0; i < N; i++) {
9330 final int targetUid = mGrantedUriPermissions.keyAt(i);
9331 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9333 // Only inspect grants matching user
9334 if (userHandle == UserHandle.USER_ALL
9335 || userHandle == UserHandle.getUserId(targetUid)) {
9336 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9337 final UriPermission perm = it.next();
9339 // Only inspect grants matching package
9340 if (packageName == null || perm.sourcePkg.equals(packageName)
9341 || perm.targetPkg.equals(packageName)) {
9342 // Hacky solution as part of fixing a security bug; ignore
9343 // grants associated with DownloadManager so we don't have
9344 // to immediately launch it to regrant the permissions
9345 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9346 && !persistable) continue;
9348 persistChanged |= perm.revokeModes(persistable
9349 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9351 // Only remove when no modes remain; any persisted grants
9352 // will keep this alive.
9353 if (perm.modeFlags == 0) {
9359 if (perms.isEmpty()) {
9360 mGrantedUriPermissions.remove(targetUid);
9367 if (persistChanged) {
9368 schedulePersistUriGrants();
9373 public IBinder newUriPermissionOwner(String name) {
9374 enforceNotIsolatedCaller("newUriPermissionOwner");
9375 synchronized(this) {
9376 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9377 return owner.getExternalTokenLocked();
9382 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9383 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9384 synchronized(this) {
9385 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9387 throw new IllegalArgumentException("Activity does not exist; token="
9390 return r.getUriPermissionsLocked().getExternalTokenLocked();
9394 * @param uri This uri must NOT contain an embedded userId.
9395 * @param sourceUserId The userId in which the uri is to be resolved.
9396 * @param targetUserId The userId of the app that receives the grant.
9399 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9400 final int modeFlags, int sourceUserId, int targetUserId) {
9401 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9402 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9403 "grantUriPermissionFromOwner", null);
9404 synchronized(this) {
9405 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9406 if (owner == null) {
9407 throw new IllegalArgumentException("Unknown owner: " + token);
9409 if (fromUid != Binder.getCallingUid()) {
9410 if (Binder.getCallingUid() != myUid()) {
9411 // Only system code can grant URI permissions on behalf
9413 throw new SecurityException("nice try");
9416 if (targetPkg == null) {
9417 throw new IllegalArgumentException("null target");
9420 throw new IllegalArgumentException("null uri");
9423 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9424 modeFlags, owner, targetUserId);
9429 * @param uri This uri must NOT contain an embedded userId.
9430 * @param userId The userId in which the uri is to be resolved.
9433 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9434 synchronized(this) {
9435 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9436 if (owner == null) {
9437 throw new IllegalArgumentException("Unknown owner: " + token);
9441 owner.removeUriPermissionsLocked(mode);
9443 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9444 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9449 private void schedulePersistUriGrants() {
9450 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9451 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9452 10 * DateUtils.SECOND_IN_MILLIS);
9456 private void writeGrantedUriPermissions() {
9457 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9459 // Snapshot permissions so we can persist without lock
9460 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9461 synchronized (this) {
9462 final int size = mGrantedUriPermissions.size();
9463 for (int i = 0; i < size; i++) {
9464 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9465 for (UriPermission perm : perms.values()) {
9466 if (perm.persistedModeFlags != 0) {
9467 persist.add(perm.snapshot());
9473 FileOutputStream fos = null;
9475 fos = mGrantFile.startWrite();
9477 XmlSerializer out = new FastXmlSerializer();
9478 out.setOutput(fos, StandardCharsets.UTF_8.name());
9479 out.startDocument(null, true);
9480 out.startTag(null, TAG_URI_GRANTS);
9481 for (UriPermission.Snapshot perm : persist) {
9482 out.startTag(null, TAG_URI_GRANT);
9483 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9484 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9485 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9486 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9487 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9488 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9489 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9490 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9491 out.endTag(null, TAG_URI_GRANT);
9493 out.endTag(null, TAG_URI_GRANTS);
9496 mGrantFile.finishWrite(fos);
9497 } catch (IOException e) {
9499 mGrantFile.failWrite(fos);
9504 private void readGrantedUriPermissionsLocked() {
9505 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9507 final long now = System.currentTimeMillis();
9509 FileInputStream fis = null;
9511 fis = mGrantFile.openRead();
9512 final XmlPullParser in = Xml.newPullParser();
9513 in.setInput(fis, StandardCharsets.UTF_8.name());
9516 while ((type = in.next()) != END_DOCUMENT) {
9517 final String tag = in.getName();
9518 if (type == START_TAG) {
9519 if (TAG_URI_GRANT.equals(tag)) {
9520 final int sourceUserId;
9521 final int targetUserId;
9522 final int userHandle = readIntAttribute(in,
9523 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9524 if (userHandle != UserHandle.USER_NULL) {
9525 // For backwards compatibility.
9526 sourceUserId = userHandle;
9527 targetUserId = userHandle;
9529 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9530 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9532 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9533 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9534 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9535 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9536 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9537 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9539 // Sanity check that provider still belongs to source package
9540 // Both direct boot aware and unaware packages are fine as we
9541 // will do filtering at query time to avoid multiple parsing.
9542 final ProviderInfo pi = getProviderInfoLocked(
9543 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9544 | MATCH_DIRECT_BOOT_UNAWARE);
9545 if (pi != null && sourcePkg.equals(pi.packageName)) {
9548 targetUid = AppGlobals.getPackageManager().getPackageUid(
9549 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9550 } catch (RemoteException e) {
9552 if (targetUid != -1) {
9553 final UriPermission perm = findOrCreateUriPermissionLocked(
9554 sourcePkg, targetPkg, targetUid,
9555 new GrantUri(sourceUserId, uri, prefix));
9556 perm.initPersistedModes(modeFlags, createdTime);
9559 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9560 + " but instead found " + pi);
9565 } catch (FileNotFoundException e) {
9566 // Missing grants is okay
9567 } catch (IOException e) {
9568 Slog.wtf(TAG, "Failed reading Uri grants", e);
9569 } catch (XmlPullParserException e) {
9570 Slog.wtf(TAG, "Failed reading Uri grants", e);
9572 IoUtils.closeQuietly(fis);
9577 * @param uri This uri must NOT contain an embedded userId.
9578 * @param userId The userId in which the uri is to be resolved.
9581 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9582 enforceNotIsolatedCaller("takePersistableUriPermission");
9584 Preconditions.checkFlagsArgument(modeFlags,
9585 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9587 synchronized (this) {
9588 final int callingUid = Binder.getCallingUid();
9589 boolean persistChanged = false;
9590 GrantUri grantUri = new GrantUri(userId, uri, false);
9592 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9593 new GrantUri(userId, uri, false));
9594 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9595 new GrantUri(userId, uri, true));
9597 final boolean exactValid = (exactPerm != null)
9598 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9599 final boolean prefixValid = (prefixPerm != null)
9600 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9602 if (!(exactValid || prefixValid)) {
9603 throw new SecurityException("No persistable permission grants found for UID "
9604 + callingUid + " and Uri " + grantUri.toSafeString());
9608 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9611 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9614 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9616 if (persistChanged) {
9617 schedulePersistUriGrants();
9623 * @param uri This uri must NOT contain an embedded userId.
9624 * @param userId The userId in which the uri is to be resolved.
9627 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9628 enforceNotIsolatedCaller("releasePersistableUriPermission");
9630 Preconditions.checkFlagsArgument(modeFlags,
9631 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9633 synchronized (this) {
9634 final int callingUid = Binder.getCallingUid();
9635 boolean persistChanged = false;
9637 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9638 new GrantUri(userId, uri, false));
9639 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9640 new GrantUri(userId, uri, true));
9641 if (exactPerm == null && prefixPerm == null) {
9642 throw new SecurityException("No permission grants found for UID " + callingUid
9643 + " and Uri " + uri.toSafeString());
9646 if (exactPerm != null) {
9647 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9648 removeUriPermissionIfNeededLocked(exactPerm);
9650 if (prefixPerm != null) {
9651 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9652 removeUriPermissionIfNeededLocked(prefixPerm);
9655 if (persistChanged) {
9656 schedulePersistUriGrants();
9662 * Prune any older {@link UriPermission} for the given UID until outstanding
9663 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9665 * @return if any mutations occured that require persisting.
9667 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9668 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9669 if (perms == null) return false;
9670 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9672 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9673 for (UriPermission perm : perms.values()) {
9674 if (perm.persistedModeFlags != 0) {
9675 persisted.add(perm);
9679 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9680 if (trimCount <= 0) return false;
9682 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9683 for (int i = 0; i < trimCount; i++) {
9684 final UriPermission perm = persisted.get(i);
9686 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9687 "Trimming grant created at " + perm.persistedCreateTime);
9689 perm.releasePersistableModes(~0);
9690 removeUriPermissionIfNeededLocked(perm);
9697 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9698 String packageName, boolean incoming) {
9699 enforceNotIsolatedCaller("getPersistedUriPermissions");
9700 Preconditions.checkNotNull(packageName, "packageName");
9702 final int callingUid = Binder.getCallingUid();
9703 final int callingUserId = UserHandle.getUserId(callingUid);
9704 final IPackageManager pm = AppGlobals.getPackageManager();
9706 final int packageUid = pm.getPackageUid(packageName,
9707 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9708 if (packageUid != callingUid) {
9709 throw new SecurityException(
9710 "Package " + packageName + " does not belong to calling UID " + callingUid);
9712 } catch (RemoteException e) {
9713 throw new SecurityException("Failed to verify package name ownership");
9716 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9717 synchronized (this) {
9719 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9721 if (perms == null) {
9722 Slog.w(TAG, "No permission grants found for " + packageName);
9724 for (UriPermission perm : perms.values()) {
9725 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9726 result.add(perm.buildPersistedPublicApiObject());
9731 final int size = mGrantedUriPermissions.size();
9732 for (int i = 0; i < size; i++) {
9733 final ArrayMap<GrantUri, UriPermission> perms =
9734 mGrantedUriPermissions.valueAt(i);
9735 for (UriPermission perm : perms.values()) {
9736 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9737 result.add(perm.buildPersistedPublicApiObject());
9743 return new ParceledListSlice<android.content.UriPermission>(result);
9747 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9748 String packageName, int userId) {
9749 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9750 "getGrantedUriPermissions");
9752 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9753 synchronized (this) {
9754 final int size = mGrantedUriPermissions.size();
9755 for (int i = 0; i < size; i++) {
9756 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9757 for (UriPermission perm : perms.values()) {
9758 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9759 && perm.persistedModeFlags != 0) {
9760 result.add(perm.buildPersistedPublicApiObject());
9765 return new ParceledListSlice<android.content.UriPermission>(result);
9769 public void clearGrantedUriPermissions(String packageName, int userId) {
9770 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9771 "clearGrantedUriPermissions");
9772 removeUriPermissionsForPackageLocked(packageName, userId, true);
9776 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9777 synchronized (this) {
9779 who != null ? getRecordForAppLocked(who) : null;
9780 if (app == null) return;
9782 Message msg = Message.obtain();
9783 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9785 msg.arg1 = waiting ? 1 : 0;
9786 mUiHandler.sendMessage(msg);
9791 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9792 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9793 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9794 outInfo.availMem = getFreeMemory();
9795 outInfo.totalMem = getTotalMemory();
9796 outInfo.threshold = homeAppMem;
9797 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9798 outInfo.hiddenAppThreshold = cachedAppMem;
9799 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9800 ProcessList.SERVICE_ADJ);
9801 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9802 ProcessList.VISIBLE_APP_ADJ);
9803 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9804 ProcessList.FOREGROUND_APP_ADJ);
9807 // =========================================================
9809 // =========================================================
9812 public List<IBinder> getAppTasks(String callingPackage) {
9813 int callingUid = Binder.getCallingUid();
9814 long ident = Binder.clearCallingIdentity();
9816 synchronized(this) {
9817 ArrayList<IBinder> list = new ArrayList<IBinder>();
9819 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9821 final int N = mRecentTasks.size();
9822 for (int i = 0; i < N; i++) {
9823 TaskRecord tr = mRecentTasks.get(i);
9824 // Skip tasks that do not match the caller. We don't need to verify
9825 // callingPackage, because we are also limiting to callingUid and know
9826 // that will limit to the correct security sandbox.
9827 if (tr.effectiveUid != callingUid) {
9830 Intent intent = tr.getBaseIntent();
9831 if (intent == null ||
9832 !callingPackage.equals(intent.getComponent().getPackageName())) {
9835 ActivityManager.RecentTaskInfo taskInfo =
9836 createRecentTaskInfoFromTaskRecord(tr);
9837 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9838 list.add(taskImpl.asBinder());
9841 Binder.restoreCallingIdentity(ident);
9848 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9849 final int callingUid = Binder.getCallingUid();
9850 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9852 synchronized(this) {
9853 if (DEBUG_ALL) Slog.v(
9854 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9856 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9859 // TODO: Improve with MRU list from all ActivityStacks.
9860 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9867 * Creates a new RecentTaskInfo from a TaskRecord.
9869 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9870 // Update the task description to reflect any changes in the task stack
9871 tr.updateTaskDescription();
9873 // Compose the recent task info
9874 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9875 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9876 rti.persistentId = tr.taskId;
9877 rti.baseIntent = new Intent(tr.getBaseIntent());
9878 rti.origActivity = tr.origActivity;
9879 rti.realActivity = tr.realActivity;
9880 rti.description = tr.lastDescription;
9881 rti.stackId = tr.getStackId();
9882 rti.userId = tr.userId;
9883 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9884 rti.firstActiveTime = tr.firstActiveTime;
9885 rti.lastActiveTime = tr.lastActiveTime;
9886 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9887 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9888 rti.numActivities = 0;
9889 if (tr.mBounds != null) {
9890 rti.bounds = new Rect(tr.mBounds);
9892 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9893 rti.resizeMode = tr.mResizeMode;
9895 ActivityRecord base = null;
9896 ActivityRecord top = null;
9899 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9900 tmp = tr.mActivities.get(i);
9901 if (tmp.finishing) {
9905 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9908 rti.numActivities++;
9911 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9912 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9917 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9918 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9919 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9921 if (checkPermission(android.Manifest.permission.GET_TASKS,
9922 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9923 // Temporary compatibility: some existing apps on the system image may
9924 // still be requesting the old permission and not switched to the new
9925 // one; if so, we'll still allow them full access. This means we need
9926 // to see if they are holding the old permission and are a system app.
9928 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9930 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9931 + " is using old GET_TASKS but privileged; allowing");
9933 } catch (RemoteException e) {
9938 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9939 + " does not hold REAL_GET_TASKS; limiting output");
9945 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9947 final int callingUid = Binder.getCallingUid();
9948 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9949 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9951 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9952 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9953 synchronized (this) {
9954 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9956 final boolean detailed = checkCallingPermission(
9957 android.Manifest.permission.GET_DETAILED_TASKS)
9958 == PackageManager.PERMISSION_GRANTED;
9960 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9961 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9962 return ParceledListSlice.emptyList();
9964 mRecentTasks.loadUserRecentsLocked(userId);
9966 final int recentsCount = mRecentTasks.size();
9967 ArrayList<ActivityManager.RecentTaskInfo> res =
9968 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9970 final Set<Integer> includedUsers;
9971 if (includeProfiles) {
9972 includedUsers = mUserController.getProfileIds(userId);
9974 includedUsers = new HashSet<>();
9976 includedUsers.add(Integer.valueOf(userId));
9978 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9979 TaskRecord tr = mRecentTasks.get(i);
9980 // Only add calling user or related users recent tasks
9981 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9982 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9986 if (tr.realActivitySuspended) {
9987 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9991 // Return the entry if desired by the caller. We always return
9992 // the first entry, because callers always expect this to be the
9993 // foreground app. We may filter others if the caller has
9994 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9995 // we should exclude the entry.
9999 || (tr.intent == null)
10000 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
10003 // If the caller doesn't have the GET_TASKS permission, then only
10004 // allow them to see a small subset of tasks -- their own and home.
10005 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
10006 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
10010 final ActivityStack stack = tr.getStack();
10011 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
10012 if (stack != null && stack.isHomeOrRecentsStack()) {
10013 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10014 "Skipping, home or recents stack task: " + tr);
10018 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10019 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10020 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10021 "Skipping, top task in docked stack: " + tr);
10025 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10026 if (stack != null && stack.isPinnedStack()) {
10027 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10028 "Skipping, pinned stack task: " + tr);
10032 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10033 // Don't include auto remove tasks that are finished or finishing.
10034 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10035 "Skipping, auto-remove without activity: " + tr);
10038 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10039 && !tr.isAvailable) {
10040 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10041 "Skipping, unavail real act: " + tr);
10045 if (!tr.mUserSetupComplete) {
10046 // Don't include task launched while user is not done setting-up.
10047 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10048 "Skipping, user setup not complete: " + tr);
10052 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10054 rti.baseIntent.replaceExtras((Bundle)null);
10061 return new ParceledListSlice<>(res);
10066 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10067 synchronized (this) {
10068 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10069 "getTaskThumbnail()");
10070 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10071 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10073 return tr.getTaskThumbnailLocked();
10080 public ActivityManager.TaskDescription getTaskDescription(int id) {
10081 synchronized (this) {
10082 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10083 "getTaskDescription()");
10084 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10085 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10087 return tr.lastTaskDescription;
10094 public int addAppTask(IBinder activityToken, Intent intent,
10095 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10096 final int callingUid = Binder.getCallingUid();
10097 final long callingIdent = Binder.clearCallingIdentity();
10100 synchronized (this) {
10101 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10103 throw new IllegalArgumentException("Activity does not exist; token="
10106 ComponentName comp = intent.getComponent();
10107 if (comp == null) {
10108 throw new IllegalArgumentException("Intent " + intent
10109 + " must specify explicit component");
10111 if (thumbnail.getWidth() != mThumbnailWidth
10112 || thumbnail.getHeight() != mThumbnailHeight) {
10113 throw new IllegalArgumentException("Bad thumbnail size: got "
10114 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10115 + mThumbnailWidth + "x" + mThumbnailHeight);
10117 if (intent.getSelector() != null) {
10118 intent.setSelector(null);
10120 if (intent.getSourceBounds() != null) {
10121 intent.setSourceBounds(null);
10123 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10124 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10125 // The caller has added this as an auto-remove task... that makes no
10126 // sense, so turn off auto-remove.
10127 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10130 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10131 mLastAddedTaskActivity = null;
10133 ActivityInfo ainfo = mLastAddedTaskActivity;
10134 if (ainfo == null) {
10135 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10136 comp, 0, UserHandle.getUserId(callingUid));
10137 if (ainfo.applicationInfo.uid != callingUid) {
10138 throw new SecurityException(
10139 "Can't add task for another application: target uid="
10140 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10144 TaskRecord task = new TaskRecord(this,
10145 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10146 ainfo, intent, description, new TaskThumbnailInfo());
10148 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10149 if (trimIdx >= 0) {
10150 // If this would have caused a trim, then we'll abort because that
10151 // means it would be added at the end of the list but then just removed.
10152 return INVALID_TASK_ID;
10155 final int N = mRecentTasks.size();
10156 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10157 final TaskRecord tr = mRecentTasks.remove(N - 1);
10158 tr.removedFromRecents();
10161 task.inRecents = true;
10162 mRecentTasks.add(task);
10163 r.getStack().addTask(task, false, "addAppTask");
10165 task.setLastThumbnailLocked(thumbnail);
10166 task.freeLastThumbnail();
10167 return task.taskId;
10170 Binder.restoreCallingIdentity(callingIdent);
10175 public Point getAppTaskThumbnailSize() {
10176 synchronized (this) {
10177 return new Point(mThumbnailWidth, mThumbnailHeight);
10182 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10183 synchronized (this) {
10184 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10186 r.setTaskDescription(td);
10187 final TaskRecord task = r.getTask();
10188 task.updateTaskDescription();
10189 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10195 public void setTaskResizeable(int taskId, int resizeableMode) {
10196 synchronized (this) {
10197 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10198 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10199 if (task == null) {
10200 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10203 task.setResizeMode(resizeableMode);
10208 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10209 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10210 long ident = Binder.clearCallingIdentity();
10212 synchronized (this) {
10213 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10214 if (task == null) {
10215 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10218 // Place the task in the right stack if it isn't there already based on
10219 // the requested bounds.
10220 // The stack transition logic is:
10221 // - a null bounds on a freeform task moves that task to fullscreen
10222 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10223 // that task to freeform
10224 // - otherwise the task is not moved
10225 int stackId = task.getStackId();
10226 if (!StackId.isTaskResizeAllowed(stackId)) {
10227 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10229 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10230 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10231 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10232 stackId = FREEFORM_WORKSPACE_STACK_ID;
10235 // Reparent the task to the right stack if necessary
10236 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10237 if (stackId != task.getStackId()) {
10238 // Defer resume until the task is resized below
10239 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10240 DEFER_RESUME, "resizeTask");
10241 preserveWindow = false;
10244 // After reparenting (which only resizes the task to the stack bounds), resize the
10245 // task to the actual bounds provided
10246 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10249 Binder.restoreCallingIdentity(ident);
10254 public Rect getTaskBounds(int taskId) {
10255 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10256 long ident = Binder.clearCallingIdentity();
10257 Rect rect = new Rect();
10259 synchronized (this) {
10260 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10261 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10262 if (task == null) {
10263 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10266 if (task.getStack() != null) {
10267 // Return the bounds from window manager since it will be adjusted for various
10268 // things like the presense of a docked stack for tasks that aren't resizeable.
10269 task.getWindowContainerBounds(rect);
10271 // Task isn't in window manager yet since it isn't associated with a stack.
10272 // Return the persist value from activity manager
10273 if (task.mBounds != null) {
10274 rect.set(task.mBounds);
10275 } else if (task.mLastNonFullscreenBounds != null) {
10276 rect.set(task.mLastNonFullscreenBounds);
10281 Binder.restoreCallingIdentity(ident);
10287 public void cancelTaskWindowTransition(int taskId) {
10288 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10289 final long ident = Binder.clearCallingIdentity();
10291 synchronized (this) {
10292 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10293 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10294 if (task == null) {
10295 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10298 task.cancelWindowTransition();
10301 Binder.restoreCallingIdentity(ident);
10306 public void cancelTaskThumbnailTransition(int taskId) {
10307 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10308 final long ident = Binder.clearCallingIdentity();
10310 synchronized (this) {
10311 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10312 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10313 if (task == null) {
10314 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10317 task.cancelThumbnailTransition();
10320 Binder.restoreCallingIdentity(ident);
10325 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10326 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10327 final long ident = Binder.clearCallingIdentity();
10329 final TaskRecord task;
10330 synchronized (this) {
10331 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10332 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10333 if (task == null) {
10334 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10338 // Don't call this while holding the lock as this operation might hit the disk.
10339 return task.getSnapshot(reducedResolution);
10341 Binder.restoreCallingIdentity(ident);
10346 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10347 if (userId != UserHandle.getCallingUserId()) {
10348 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10349 "getTaskDescriptionIcon");
10351 final File passedIconFile = new File(filePath);
10352 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10353 passedIconFile.getName());
10354 if (!legitIconFile.getPath().equals(filePath)
10355 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10356 throw new IllegalArgumentException("Bad file path: " + filePath
10357 + " passed for userId " + userId);
10359 return mRecentTasks.getTaskDescriptionIcon(filePath);
10363 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10364 throws RemoteException {
10365 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10366 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10367 activityOptions.getCustomInPlaceResId() == 0) {
10368 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10369 "with valid animation");
10371 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10372 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10373 activityOptions.getCustomInPlaceResId());
10374 mWindowManager.executeAppTransition();
10377 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10378 // Remove all tasks with activities in the specified package from the list of recent tasks
10379 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10380 TaskRecord tr = mRecentTasks.get(i);
10381 if (tr.userId != userId) continue;
10383 ComponentName cn = tr.intent.getComponent();
10384 if (cn != null && cn.getPackageName().equals(packageName)) {
10385 // If the package name matches, remove the task.
10386 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10391 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10394 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10395 TaskRecord tr = mRecentTasks.get(i);
10396 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10400 ComponentName cn = tr.intent.getComponent();
10401 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10402 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10403 if (sameComponent) {
10404 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10410 public void removeStack(int stackId) {
10411 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10412 if (StackId.isHomeOrRecentsStack(stackId)) {
10413 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10416 synchronized (this) {
10417 final long ident = Binder.clearCallingIdentity();
10419 mStackSupervisor.removeStackLocked(stackId);
10421 Binder.restoreCallingIdentity(ident);
10427 public void moveStackToDisplay(int stackId, int displayId) {
10428 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10430 synchronized (this) {
10431 final long ident = Binder.clearCallingIdentity();
10433 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10434 + " to displayId=" + displayId);
10435 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10437 Binder.restoreCallingIdentity(ident);
10443 public boolean removeTask(int taskId) {
10444 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10445 synchronized (this) {
10446 final long ident = Binder.clearCallingIdentity();
10448 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10450 Binder.restoreCallingIdentity(ident);
10456 * TODO: Add mController hook
10459 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10460 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10462 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10463 synchronized(this) {
10464 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10468 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10469 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10471 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10472 Binder.getCallingUid(), -1, -1, "Task to front")) {
10473 ActivityOptions.abort(options);
10476 final long origId = Binder.clearCallingIdentity();
10478 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10479 if (task == null) {
10480 Slog.d(TAG, "Could not find task for id: "+ taskId);
10483 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10484 mStackSupervisor.showLockTaskToast();
10485 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10488 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10489 if (prev != null) {
10490 task.setTaskToReturnTo(prev);
10492 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10493 false /* forceNonResizable */);
10495 final ActivityRecord topActivity = task.getTopActivity();
10496 if (topActivity != null) {
10498 // We are reshowing a task, use a starting window to hide the initial draw delay
10499 // so the transition can start earlier.
10500 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10501 true /* taskSwitch */, fromRecents);
10504 Binder.restoreCallingIdentity(origId);
10506 ActivityOptions.abort(options);
10510 * Attempts to move a task backwards in z-order (the order of activities within the task is
10513 * There are several possible results of this call:
10514 * - if the task is locked, then we will show the lock toast
10515 * - if there is a task behind the provided task, then that task is made visible and resumed as
10516 * this task is moved to the back
10517 * - otherwise, if there are no other tasks in the stack:
10518 * - if this task is in the pinned stack, then we remove the stack completely, which will
10519 * have the effect of moving the task to the top or bottom of the fullscreen stack
10520 * (depending on whether it is visible)
10521 * - otherwise, we simply return home and hide this task
10523 * @param token A reference to the activity we wish to move
10524 * @param nonRoot If false then this only works if the activity is the root
10525 * of a task; if true it will work for any activity in a task.
10526 * @return Returns true if the move completed, false if not.
10529 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10530 enforceNotIsolatedCaller("moveActivityTaskToBack");
10531 synchronized(this) {
10532 final long origId = Binder.clearCallingIdentity();
10534 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10535 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10536 if (task != null) {
10537 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10540 Binder.restoreCallingIdentity(origId);
10547 public void moveTaskBackwards(int task) {
10548 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10549 "moveTaskBackwards()");
10551 synchronized(this) {
10552 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10553 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10556 final long origId = Binder.clearCallingIdentity();
10557 moveTaskBackwardsLocked(task);
10558 Binder.restoreCallingIdentity(origId);
10562 private final void moveTaskBackwardsLocked(int task) {
10563 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10567 public int createStackOnDisplay(int displayId) throws RemoteException {
10568 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10569 synchronized (this) {
10570 final int stackId = mStackSupervisor.getNextStackId();
10571 final ActivityStack stack =
10572 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10573 if (stack == null) {
10574 return INVALID_STACK_ID;
10576 return stack.mStackId;
10581 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10582 synchronized (this) {
10583 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10584 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10585 return stack.mDisplayId;
10587 return DEFAULT_DISPLAY;
10592 public int getActivityStackId(IBinder token) throws RemoteException {
10593 synchronized (this) {
10594 ActivityStack stack = ActivityRecord.getStackLocked(token);
10595 if (stack == null) {
10596 return INVALID_STACK_ID;
10598 return stack.mStackId;
10603 public void exitFreeformMode(IBinder token) throws RemoteException {
10604 synchronized (this) {
10605 long ident = Binder.clearCallingIdentity();
10607 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10609 throw new IllegalArgumentException(
10610 "exitFreeformMode: No activity record matching token=" + token);
10613 final ActivityStack stack = r.getStack();
10614 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10615 throw new IllegalStateException(
10616 "exitFreeformMode: You can only go fullscreen from freeform.");
10619 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10620 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10621 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10623 Binder.restoreCallingIdentity(ident);
10629 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10630 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10631 if (StackId.isHomeOrRecentsStack(stackId)) {
10632 throw new IllegalArgumentException(
10633 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10635 synchronized (this) {
10636 long ident = Binder.clearCallingIdentity();
10638 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10639 if (task == null) {
10640 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10644 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10645 + " to stackId=" + stackId + " toTop=" + toTop);
10646 if (stackId == DOCKED_STACK_ID) {
10647 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10648 null /* initialBounds */);
10650 task.reparent(stackId, toTop,
10651 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10653 Binder.restoreCallingIdentity(ident);
10659 public void swapDockedAndFullscreenStack() throws RemoteException {
10660 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10661 synchronized (this) {
10662 long ident = Binder.clearCallingIdentity();
10664 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10665 FULLSCREEN_WORKSPACE_STACK_ID);
10666 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10668 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10669 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10671 if (topTask == null || tasks == null || tasks.size() == 0) {
10673 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10677 // TODO: App transition
10678 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10680 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10681 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10682 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10683 final int size = tasks.size();
10684 for (int i = 0; i < size; i++) {
10685 final int id = tasks.get(i).taskId;
10686 if (id == topTask.taskId) {
10690 // Defer the resume until after all the tasks have been moved
10691 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10692 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10693 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10696 // Because we deferred the resume to avoid conflicts with stack switches while
10697 // resuming, we need to do it after all the tasks are moved.
10698 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10699 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10701 mWindowManager.executeAppTransition();
10703 Binder.restoreCallingIdentity(ident);
10709 * Moves the input task to the docked stack.
10711 * @param taskId Id of task to move.
10712 * @param createMode The mode the docked stack should be created in if it doesn't exist
10714 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10716 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10717 * @param toTop If the task and stack should be moved to the top.
10718 * @param animate Whether we should play an animation for the moving the task
10719 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10720 * docked stack. Pass {@code null} to use default bounds.
10723 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10724 Rect initialBounds) {
10725 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10726 synchronized (this) {
10727 long ident = Binder.clearCallingIdentity();
10729 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10730 if (task == null) {
10731 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10735 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10736 + " to createMode=" + createMode + " toTop=" + toTop);
10737 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10739 // Defer resuming until we move the home stack to the front below
10740 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10741 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10742 "moveTaskToDockedStack");
10744 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10748 Binder.restoreCallingIdentity(ident);
10754 * Moves the top activity in the input stackId to the pinned stack.
10756 * @param stackId Id of stack to move the top activity to pinned stack.
10757 * @param bounds Bounds to use for pinned stack.
10759 * @return True if the top activity of the input stack was successfully moved to the pinned
10763 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10764 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10765 synchronized (this) {
10766 if (!mSupportsPictureInPicture) {
10767 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10768 + "Device doesn't support picture-in-picture mode");
10771 long ident = Binder.clearCallingIdentity();
10773 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10775 Binder.restoreCallingIdentity(ident);
10781 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10782 boolean preserveWindows, boolean animate, int animationDuration) {
10783 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10784 long ident = Binder.clearCallingIdentity();
10786 synchronized (this) {
10788 if (stackId == PINNED_STACK_ID) {
10789 final PinnedActivityStack pinnedStack =
10790 mStackSupervisor.getStack(PINNED_STACK_ID);
10791 if (pinnedStack != null) {
10792 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10793 destBounds, animationDuration, false /* fromFullscreen */);
10796 throw new IllegalArgumentException("Stack: " + stackId
10797 + " doesn't support animated resize.");
10800 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10801 null /* tempTaskInsetBounds */, preserveWindows,
10802 allowResizeInDockedMode, !DEFER_RESUME);
10806 Binder.restoreCallingIdentity(ident);
10811 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10812 Rect tempDockedTaskInsetBounds,
10813 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10814 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10815 "resizeDockedStack()");
10816 long ident = Binder.clearCallingIdentity();
10818 synchronized (this) {
10819 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10820 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10824 Binder.restoreCallingIdentity(ident);
10829 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10830 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10831 "resizePinnedStack()");
10832 final long ident = Binder.clearCallingIdentity();
10834 synchronized (this) {
10835 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10838 Binder.restoreCallingIdentity(ident);
10843 * Try to place task to provided position. The final position might be different depending on
10844 * current user and stacks state. The task will be moved to target stack if it's currently in
10848 public void positionTaskInStack(int taskId, int stackId, int position) {
10849 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10850 if (StackId.isHomeOrRecentsStack(stackId)) {
10851 throw new IllegalArgumentException(
10852 "positionTaskInStack: Attempt to change the position of task "
10853 + taskId + " in/to home/recents stack");
10855 synchronized (this) {
10856 long ident = Binder.clearCallingIdentity();
10858 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10859 + taskId + " in stackId=" + stackId + " at position=" + position);
10860 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10861 if (task == null) {
10862 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10866 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10869 // TODO: Have the callers of this API call a separate reparent method if that is
10870 // what they intended to do vs. having this method also do reparenting.
10871 if (task.getStack() == stack) {
10872 // Change position in current stack.
10873 stack.positionChildAt(task, position);
10875 // Reparent to new stack.
10876 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10877 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10880 Binder.restoreCallingIdentity(ident);
10886 public List<StackInfo> getAllStackInfos() {
10887 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10888 long ident = Binder.clearCallingIdentity();
10890 synchronized (this) {
10891 return mStackSupervisor.getAllStackInfosLocked();
10894 Binder.restoreCallingIdentity(ident);
10899 public StackInfo getStackInfo(int stackId) {
10900 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10901 long ident = Binder.clearCallingIdentity();
10903 synchronized (this) {
10904 return mStackSupervisor.getStackInfoLocked(stackId);
10907 Binder.restoreCallingIdentity(ident);
10912 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10913 synchronized(this) {
10914 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10919 public void updateDeviceOwner(String packageName) {
10920 final int callingUid = Binder.getCallingUid();
10921 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10922 throw new SecurityException("updateDeviceOwner called from non-system process");
10924 synchronized (this) {
10925 mDeviceOwnerName = packageName;
10930 public void updateLockTaskPackages(int userId, String[] packages) {
10931 final int callingUid = Binder.getCallingUid();
10932 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10933 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10934 "updateLockTaskPackages()");
10936 synchronized (this) {
10937 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10938 Arrays.toString(packages));
10939 mLockTaskPackages.put(userId, packages);
10940 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10945 void startLockTaskModeLocked(TaskRecord task) {
10946 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10947 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10951 // When a task is locked, dismiss the pinned stack if it exists
10952 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10954 if (pinnedStack != null) {
10955 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10958 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10959 // is initiated by system after the pinning request was shown and locked mode is initiated
10960 // by an authorized app directly
10961 final int callingUid = Binder.getCallingUid();
10962 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10963 long ident = Binder.clearCallingIdentity();
10965 if (!isSystemInitiated) {
10966 task.mLockTaskUid = callingUid;
10967 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10968 // startLockTask() called by app and task mode is lockTaskModeDefault.
10969 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10970 StatusBarManagerInternal statusBarManager =
10971 LocalServices.getService(StatusBarManagerInternal.class);
10972 if (statusBarManager != null) {
10973 statusBarManager.showScreenPinningRequest(task.taskId);
10978 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10979 if (stack == null || task != stack.topTask()) {
10980 throw new IllegalArgumentException("Invalid task, not in foreground");
10983 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10985 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10986 ActivityManager.LOCK_TASK_MODE_PINNED :
10987 ActivityManager.LOCK_TASK_MODE_LOCKED,
10988 "startLockTask", true);
10990 Binder.restoreCallingIdentity(ident);
10995 public void startLockTaskModeById(int taskId) {
10996 synchronized (this) {
10997 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10998 if (task != null) {
10999 startLockTaskModeLocked(task);
11005 public void startLockTaskModeByToken(IBinder token) {
11006 synchronized (this) {
11007 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11011 final TaskRecord task = r.getTask();
11012 if (task != null) {
11013 startLockTaskModeLocked(task);
11019 public void startSystemLockTaskMode(int taskId) throws RemoteException {
11020 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11021 // This makes inner call to look as if it was initiated by system.
11022 long ident = Binder.clearCallingIdentity();
11024 synchronized (this) {
11025 startLockTaskModeById(taskId);
11028 Binder.restoreCallingIdentity(ident);
11033 public void stopLockTaskMode() {
11034 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11035 if (lockTask == null) {
11036 // Our work here is done.
11040 final int callingUid = Binder.getCallingUid();
11041 final int lockTaskUid = lockTask.mLockTaskUid;
11042 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11043 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11047 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11048 // It is possible lockTaskMode was started by the system process because
11049 // android:lockTaskMode is set to a locking value in the application manifest
11050 // instead of the app calling startLockTaskMode. In this case
11051 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11052 // {@link TaskRecord.effectiveUid} instead. Also caller with
11053 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11054 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11055 && callingUid != lockTaskUid
11056 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11057 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11058 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11061 long ident = Binder.clearCallingIdentity();
11063 Log.d(TAG, "stopLockTaskMode");
11065 synchronized (this) {
11066 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11067 "stopLockTask", true);
11069 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11071 tm.showInCallScreen(false);
11074 Binder.restoreCallingIdentity(ident);
11079 * This API should be called by SystemUI only when user perform certain action to dismiss
11080 * lock task mode. We should only dismiss pinned lock task mode in this case.
11083 public void stopSystemLockTaskMode() throws RemoteException {
11084 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11085 stopLockTaskMode();
11087 mStackSupervisor.showLockTaskToast();
11092 public boolean isInLockTaskMode() {
11093 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11097 public int getLockTaskModeState() {
11098 synchronized (this) {
11099 return mStackSupervisor.getLockTaskModeState();
11104 public void showLockTaskEscapeMessage(IBinder token) {
11105 synchronized (this) {
11106 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11110 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11115 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11116 throws RemoteException {
11117 synchronized (this) {
11118 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11120 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11124 final long origId = Binder.clearCallingIdentity();
11126 r.setDisablePreviewScreenshots(disable);
11128 Binder.restoreCallingIdentity(origId);
11133 // =========================================================
11134 // CONTENT PROVIDERS
11135 // =========================================================
11137 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11138 List<ProviderInfo> providers = null;
11140 providers = AppGlobals.getPackageManager()
11141 .queryContentProviders(app.processName, app.uid,
11142 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11143 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11145 } catch (RemoteException ex) {
11147 if (DEBUG_MU) Slog.v(TAG_MU,
11148 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11149 int userId = app.userId;
11150 if (providers != null) {
11151 int N = providers.size();
11152 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11153 for (int i=0; i<N; i++) {
11154 // TODO: keep logic in sync with installEncryptionUnawareProviders
11156 (ProviderInfo)providers.get(i);
11157 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11158 cpi.name, cpi.flags);
11159 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11160 // This is a singleton provider, but a user besides the
11161 // default user is asking to initialize a process it runs
11162 // in... well, no, it doesn't actually run in this process,
11163 // it runs in the process of the default user. Get rid of it.
11164 providers.remove(i);
11170 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11171 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11173 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11174 mProviderMap.putProviderByClass(comp, cpr);
11176 if (DEBUG_MU) Slog.v(TAG_MU,
11177 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11178 app.pubProviders.put(cpi.name, cpr);
11179 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11180 // Don't add this if it is a platform component that is marked
11181 // to run in multiple processes, because this is actually
11182 // part of the framework so doesn't make sense to track as a
11183 // separate apk in the process.
11184 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11187 notifyPackageUse(cpi.applicationInfo.packageName,
11188 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11195 * Check if the calling UID has a possible chance at accessing the provider
11196 * at the given authority and user.
11198 public String checkContentProviderAccess(String authority, int userId) {
11199 if (userId == UserHandle.USER_ALL) {
11200 mContext.enforceCallingOrSelfPermission(
11201 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11202 userId = UserHandle.getCallingUserId();
11205 ProviderInfo cpi = null;
11207 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11208 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11209 | PackageManager.MATCH_DISABLED_COMPONENTS
11210 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11211 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11213 } catch (RemoteException ignored) {
11216 return "Failed to find provider " + authority + " for user " + userId
11217 + "; expected to find a valid ContentProvider for this authority";
11220 ProcessRecord r = null;
11221 synchronized (mPidsSelfLocked) {
11222 r = mPidsSelfLocked.get(Binder.getCallingPid());
11225 return "Failed to find PID " + Binder.getCallingPid();
11228 synchronized (this) {
11229 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11234 * Check if {@link ProcessRecord} has a possible chance at accessing the
11235 * given {@link ProviderInfo}. Final permission checking is always done
11236 * in {@link ContentProvider}.
11238 private final String checkContentProviderPermissionLocked(
11239 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11240 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11241 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11242 boolean checkedGrants = false;
11244 // Looking for cross-user grants before enforcing the typical cross-users permissions
11245 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11246 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11247 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11250 checkedGrants = true;
11252 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11253 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11254 if (userId != tmpTargetUserId) {
11255 // When we actually went to determine the final targer user ID, this ended
11256 // up different than our initial check for the authority. This is because
11257 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11258 // SELF. So we need to re-check the grants again.
11259 checkedGrants = false;
11262 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11263 cpi.applicationInfo.uid, cpi.exported)
11264 == PackageManager.PERMISSION_GRANTED) {
11267 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11268 cpi.applicationInfo.uid, cpi.exported)
11269 == PackageManager.PERMISSION_GRANTED) {
11273 PathPermission[] pps = cpi.pathPermissions;
11275 int i = pps.length;
11278 PathPermission pp = pps[i];
11279 String pprperm = pp.getReadPermission();
11280 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11281 cpi.applicationInfo.uid, cpi.exported)
11282 == PackageManager.PERMISSION_GRANTED) {
11285 String ppwperm = pp.getWritePermission();
11286 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11287 cpi.applicationInfo.uid, cpi.exported)
11288 == PackageManager.PERMISSION_GRANTED) {
11293 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11297 final String suffix;
11298 if (!cpi.exported) {
11299 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11300 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11301 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11303 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11305 final String msg = "Permission Denial: opening provider " + cpi.name
11306 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11307 + ", uid=" + callingUid + ")" + suffix;
11313 * Returns if the ContentProvider has granted a uri to callingUid
11315 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11316 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11317 if (perms != null) {
11318 for (int i=perms.size()-1; i>=0; i--) {
11319 GrantUri grantUri = perms.keyAt(i);
11320 if (grantUri.sourceUserId == userId || !checkUser) {
11321 if (matchesProvider(grantUri.uri, cpi)) {
11331 * Returns true if the uri authority is one of the authorities specified in the provider.
11333 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11334 String uriAuth = uri.getAuthority();
11335 String cpiAuth = cpi.authority;
11336 if (cpiAuth.indexOf(';') == -1) {
11337 return cpiAuth.equals(uriAuth);
11339 String[] cpiAuths = cpiAuth.split(";");
11340 int length = cpiAuths.length;
11341 for (int i = 0; i < length; i++) {
11342 if (cpiAuths[i].equals(uriAuth)) return true;
11347 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11348 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11350 for (int i=0; i<r.conProviders.size(); i++) {
11351 ContentProviderConnection conn = r.conProviders.get(i);
11352 if (conn.provider == cpr) {
11353 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11354 "Adding provider requested by "
11355 + r.processName + " from process "
11356 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11357 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11359 conn.stableCount++;
11360 conn.numStableIncs++;
11362 conn.unstableCount++;
11363 conn.numUnstableIncs++;
11368 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11370 conn.stableCount = 1;
11371 conn.numStableIncs = 1;
11373 conn.unstableCount = 1;
11374 conn.numUnstableIncs = 1;
11376 cpr.connections.add(conn);
11377 r.conProviders.add(conn);
11378 startAssociationLocked(r.uid, r.processName, r.curProcState,
11379 cpr.uid, cpr.name, cpr.info.processName);
11382 cpr.addExternalProcessHandleLocked(externalProcessToken);
11386 boolean decProviderCountLocked(ContentProviderConnection conn,
11387 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11388 if (conn != null) {
11389 cpr = conn.provider;
11390 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11391 "Removing provider requested by "
11392 + conn.client.processName + " from process "
11393 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11394 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11396 conn.stableCount--;
11398 conn.unstableCount--;
11400 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11401 cpr.connections.remove(conn);
11402 conn.client.conProviders.remove(conn);
11403 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11404 // The client is more important than last activity -- note the time this
11405 // is happening, so we keep the old provider process around a bit as last
11406 // activity to avoid thrashing it.
11407 if (cpr.proc != null) {
11408 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11411 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11416 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11420 private void checkTime(long startTime, String where) {
11421 long now = SystemClock.uptimeMillis();
11422 if ((now-startTime) > 50) {
11423 // If we are taking more than 50ms, log about it.
11424 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11428 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11430 PROC_SPACE_TERM|PROC_PARENS,
11431 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11434 private final long[] mProcessStateStatsLongs = new long[1];
11436 boolean isProcessAliveLocked(ProcessRecord proc) {
11437 if (proc.procStatFile == null) {
11438 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11440 mProcessStateStatsLongs[0] = 0;
11441 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11442 mProcessStateStatsLongs, null)) {
11443 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11446 final long state = mProcessStateStatsLongs[0];
11447 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11449 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11452 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11453 String name, IBinder token, boolean stable, int userId) {
11454 ContentProviderRecord cpr;
11455 ContentProviderConnection conn = null;
11456 ProviderInfo cpi = null;
11458 synchronized(this) {
11459 long startTime = SystemClock.uptimeMillis();
11461 ProcessRecord r = null;
11462 if (caller != null) {
11463 r = getRecordForAppLocked(caller);
11465 throw new SecurityException(
11466 "Unable to find app for caller " + caller
11467 + " (pid=" + Binder.getCallingPid()
11468 + ") when getting content provider " + name);
11472 boolean checkCrossUser = true;
11474 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11476 // First check if this content provider has been published...
11477 cpr = mProviderMap.getProviderByName(name, userId);
11478 // If that didn't work, check if it exists for user 0 and then
11479 // verify that it's a singleton provider before using it.
11480 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11481 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11484 if (isSingleton(cpi.processName, cpi.applicationInfo,
11485 cpi.name, cpi.flags)
11486 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11487 userId = UserHandle.USER_SYSTEM;
11488 checkCrossUser = false;
11496 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11497 if (providerRunning) {
11500 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11501 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11503 throw new SecurityException(msg);
11505 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11507 if (r != null && cpr.canRunHere(r)) {
11508 // This provider has been published or is in the process
11509 // of being published... but it is also allowed to run
11510 // in the caller's process, so don't make a connection
11511 // and just let the caller instantiate its own instance.
11512 ContentProviderHolder holder = cpr.newHolder(null);
11513 // don't give caller the provider object, it needs
11514 // to make its own.
11515 holder.provider = null;
11518 // Don't expose providers between normal apps and instant apps
11520 if (AppGlobals.getPackageManager()
11521 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11524 } catch (RemoteException e) {
11527 final long origId = Binder.clearCallingIdentity();
11529 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11531 // In this case the provider instance already exists, so we can
11532 // return it right away.
11533 conn = incProviderCountLocked(r, cpr, token, stable);
11534 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11535 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11536 // If this is a perceptible app accessing the provider,
11537 // make sure to count it as being accessed and thus
11538 // back up on the LRU list. This is good because
11539 // content providers are often expensive to start.
11540 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11541 updateLruProcessLocked(cpr.proc, false, null);
11542 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11546 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11547 final int verifiedAdj = cpr.proc.verifiedAdj;
11548 boolean success = updateOomAdjLocked(cpr.proc, true);
11549 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11550 // if the process has been successfully adjusted. So to reduce races with
11551 // it, we will check whether the process still exists. Note that this doesn't
11552 // completely get rid of races with LMK killing the process, but should make
11553 // them much smaller.
11554 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11557 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11558 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11559 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11560 // NOTE: there is still a race here where a signal could be
11561 // pending on the process even though we managed to update its
11562 // adj level. Not sure what to do about this, but at least
11563 // the race is now smaller.
11565 // Uh oh... it looks like the provider's process
11566 // has been killed on us. We need to wait for a new
11567 // process to be started, and make sure its death
11568 // doesn't kill our process.
11569 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11570 + " is crashing; detaching " + r);
11571 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11572 checkTime(startTime, "getContentProviderImpl: before appDied");
11573 appDiedLocked(cpr.proc);
11574 checkTime(startTime, "getContentProviderImpl: after appDied");
11576 // This wasn't the last ref our process had on
11577 // the provider... we have now been killed, bail.
11580 providerRunning = false;
11583 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11586 Binder.restoreCallingIdentity(origId);
11589 if (!providerRunning) {
11591 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11592 cpi = AppGlobals.getPackageManager().
11593 resolveContentProvider(name,
11594 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11595 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11596 } catch (RemoteException ex) {
11601 // If the provider is a singleton AND
11602 // (it's a call within the same user || the provider is a
11604 // Then allow connecting to the singleton provider
11605 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11606 cpi.name, cpi.flags)
11607 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11609 userId = UserHandle.USER_SYSTEM;
11611 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11612 checkTime(startTime, "getContentProviderImpl: got app info for user");
11615 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11616 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11618 throw new SecurityException(msg);
11620 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11622 if (!mProcessesReady
11623 && !cpi.processName.equals("system")) {
11624 // If this content provider does not run in the system
11625 // process, and the system is not yet ready to run other
11626 // processes, then fail fast instead of hanging.
11627 throw new IllegalArgumentException(
11628 "Attempt to launch content provider before system ready");
11631 // Make sure that the user who owns this provider is running. If not,
11632 // we don't want to allow it to run.
11633 if (!mUserController.isUserRunningLocked(userId, 0)) {
11634 Slog.w(TAG, "Unable to launch app "
11635 + cpi.applicationInfo.packageName + "/"
11636 + cpi.applicationInfo.uid + " for provider "
11637 + name + ": user " + userId + " is stopped");
11641 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11642 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11643 cpr = mProviderMap.getProviderByClass(comp, userId);
11644 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11645 final boolean firstClass = cpr == null;
11647 final long ident = Binder.clearCallingIdentity();
11649 // If permissions need a review before any of the app components can run,
11650 // we return no provider and launch a review activity if the calling app
11651 // is in the foreground.
11652 if (mPermissionReviewRequired) {
11653 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11659 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11660 ApplicationInfo ai =
11661 AppGlobals.getPackageManager().
11662 getApplicationInfo(
11663 cpi.applicationInfo.packageName,
11664 STOCK_PM_FLAGS, userId);
11665 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11667 Slog.w(TAG, "No package info for content provider "
11671 ai = getAppInfoForUser(ai, userId);
11672 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11673 } catch (RemoteException ex) {
11674 // pm is in same process, this will never happen.
11676 Binder.restoreCallingIdentity(ident);
11680 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11682 if (r != null && cpr.canRunHere(r)) {
11683 // If this is a multiprocess provider, then just return its
11684 // info and allow the caller to instantiate it. Only do
11685 // this if the provider is the same user as the caller's
11686 // process, or can run as root (so can be in any process).
11687 return cpr.newHolder(null);
11690 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11691 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11692 + cpr.info.name + " callers=" + Debug.getCallers(6));
11694 // This is single process, and our app is now connecting to it.
11695 // See if we are already in the process of launching this
11697 final int N = mLaunchingProviders.size();
11699 for (i = 0; i < N; i++) {
11700 if (mLaunchingProviders.get(i) == cpr) {
11705 // If the provider is not already being launched, then get it
11708 final long origId = Binder.clearCallingIdentity();
11711 // Content provider is now in use, its package can't be stopped.
11713 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11714 AppGlobals.getPackageManager().setPackageStoppedState(
11715 cpr.appInfo.packageName, false, userId);
11716 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11717 } catch (RemoteException e) {
11718 } catch (IllegalArgumentException e) {
11719 Slog.w(TAG, "Failed trying to unstop package "
11720 + cpr.appInfo.packageName + ": " + e);
11723 // Use existing process if already started
11724 checkTime(startTime, "getContentProviderImpl: looking for process record");
11725 ProcessRecord proc = getProcessRecordLocked(
11726 cpi.processName, cpr.appInfo.uid, false);
11727 if (proc != null && proc.thread != null && !proc.killed) {
11728 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11729 "Installing in existing process " + proc);
11730 if (!proc.pubProviders.containsKey(cpi.name)) {
11731 checkTime(startTime, "getContentProviderImpl: scheduling install");
11732 proc.pubProviders.put(cpi.name, cpr);
11734 proc.thread.scheduleInstallProvider(cpi);
11735 } catch (RemoteException e) {
11739 checkTime(startTime, "getContentProviderImpl: before start process");
11740 proc = startProcessLocked(cpi.processName,
11741 cpr.appInfo, false, 0, "content provider",
11742 new ComponentName(cpi.applicationInfo.packageName,
11743 cpi.name), false, false, false);
11744 checkTime(startTime, "getContentProviderImpl: after start process");
11745 if (proc == null) {
11746 Slog.w(TAG, "Unable to launch app "
11747 + cpi.applicationInfo.packageName + "/"
11748 + cpi.applicationInfo.uid + " for provider "
11749 + name + ": process is bad");
11753 cpr.launchingApp = proc;
11754 mLaunchingProviders.add(cpr);
11756 Binder.restoreCallingIdentity(origId);
11760 checkTime(startTime, "getContentProviderImpl: updating data structures");
11762 // Make sure the provider is published (the same provider class
11763 // may be published under multiple names).
11765 mProviderMap.putProviderByClass(comp, cpr);
11768 mProviderMap.putProviderByName(name, cpr);
11769 conn = incProviderCountLocked(r, cpr, token, stable);
11770 if (conn != null) {
11771 conn.waiting = true;
11774 checkTime(startTime, "getContentProviderImpl: done!");
11776 grantEphemeralAccessLocked(userId, null /*intent*/,
11777 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11780 // Wait for the provider to be published...
11781 synchronized (cpr) {
11782 while (cpr.provider == null) {
11783 if (cpr.launchingApp == null) {
11784 Slog.w(TAG, "Unable to launch app "
11785 + cpi.applicationInfo.packageName + "/"
11786 + cpi.applicationInfo.uid + " for provider "
11787 + name + ": launching app became null");
11788 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11789 UserHandle.getUserId(cpi.applicationInfo.uid),
11790 cpi.applicationInfo.packageName,
11791 cpi.applicationInfo.uid, name);
11795 if (DEBUG_MU) Slog.v(TAG_MU,
11796 "Waiting to start provider " + cpr
11797 + " launchingApp=" + cpr.launchingApp);
11798 if (conn != null) {
11799 conn.waiting = true;
11802 } catch (InterruptedException ex) {
11804 if (conn != null) {
11805 conn.waiting = false;
11810 return cpr != null ? cpr.newHolder(conn) : null;
11813 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11814 ProcessRecord r, final int userId) {
11815 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11816 cpi.packageName, userId)) {
11818 final boolean callerForeground = r == null || r.setSchedGroup
11819 != ProcessList.SCHED_GROUP_BACKGROUND;
11821 // Show a permission review UI only for starting from a foreground app
11822 if (!callerForeground) {
11823 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11824 + cpi.packageName + " requires a permissions review");
11828 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11829 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11830 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11831 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11833 if (DEBUG_PERMISSIONS_REVIEW) {
11834 Slog.i(TAG, "u" + userId + " Launching permission review "
11835 + "for package " + cpi.packageName);
11838 final UserHandle userHandle = new UserHandle(userId);
11839 mHandler.post(new Runnable() {
11841 public void run() {
11842 mContext.startActivityAsUser(intent, userHandle);
11852 PackageManagerInternal getPackageManagerInternalLocked() {
11853 if (mPackageManagerInt == null) {
11854 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11856 return mPackageManagerInt;
11860 public final ContentProviderHolder getContentProvider(
11861 IApplicationThread caller, String name, int userId, boolean stable) {
11862 enforceNotIsolatedCaller("getContentProvider");
11863 if (caller == null) {
11864 String msg = "null IApplicationThread when getting content provider "
11867 throw new SecurityException(msg);
11869 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11870 // with cross-user grant.
11871 return getContentProviderImpl(caller, name, null, stable, userId);
11874 public ContentProviderHolder getContentProviderExternal(
11875 String name, int userId, IBinder token) {
11876 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11877 "Do not have permission in call getContentProviderExternal()");
11878 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11879 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11880 return getContentProviderExternalUnchecked(name, token, userId);
11883 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11884 IBinder token, int userId) {
11885 return getContentProviderImpl(null, name, token, true, userId);
11889 * Drop a content provider from a ProcessRecord's bookkeeping
11891 public void removeContentProvider(IBinder connection, boolean stable) {
11892 enforceNotIsolatedCaller("removeContentProvider");
11893 long ident = Binder.clearCallingIdentity();
11895 synchronized (this) {
11896 ContentProviderConnection conn;
11898 conn = (ContentProviderConnection)connection;
11899 } catch (ClassCastException e) {
11900 String msg ="removeContentProvider: " + connection
11901 + " not a ContentProviderConnection";
11903 throw new IllegalArgumentException(msg);
11905 if (conn == null) {
11906 throw new NullPointerException("connection is null");
11908 if (decProviderCountLocked(conn, null, null, stable)) {
11909 updateOomAdjLocked();
11913 Binder.restoreCallingIdentity(ident);
11917 public void removeContentProviderExternal(String name, IBinder token) {
11918 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11919 "Do not have permission in call removeContentProviderExternal()");
11920 int userId = UserHandle.getCallingUserId();
11921 long ident = Binder.clearCallingIdentity();
11923 removeContentProviderExternalUnchecked(name, token, userId);
11925 Binder.restoreCallingIdentity(ident);
11929 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11930 synchronized (this) {
11931 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11933 //remove from mProvidersByClass
11934 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11938 //update content provider record entry info
11939 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11940 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11941 if (localCpr.hasExternalProcessHandles()) {
11942 if (localCpr.removeExternalProcessHandleLocked(token)) {
11943 updateOomAdjLocked();
11945 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11946 + " with no external reference for token: "
11950 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11951 + " with no external references.");
11956 public final void publishContentProviders(IApplicationThread caller,
11957 List<ContentProviderHolder> providers) {
11958 if (providers == null) {
11962 enforceNotIsolatedCaller("publishContentProviders");
11963 synchronized (this) {
11964 final ProcessRecord r = getRecordForAppLocked(caller);
11965 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11967 throw new SecurityException(
11968 "Unable to find app for caller " + caller
11969 + " (pid=" + Binder.getCallingPid()
11970 + ") when publishing content providers");
11973 final long origId = Binder.clearCallingIdentity();
11975 final int N = providers.size();
11976 for (int i = 0; i < N; i++) {
11977 ContentProviderHolder src = providers.get(i);
11978 if (src == null || src.info == null || src.provider == null) {
11981 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11982 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11984 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11985 mProviderMap.putProviderByClass(comp, dst);
11986 String names[] = dst.info.authority.split(";");
11987 for (int j = 0; j < names.length; j++) {
11988 mProviderMap.putProviderByName(names[j], dst);
11991 int launchingCount = mLaunchingProviders.size();
11993 boolean wasInLaunchingProviders = false;
11994 for (j = 0; j < launchingCount; j++) {
11995 if (mLaunchingProviders.get(j) == dst) {
11996 mLaunchingProviders.remove(j);
11997 wasInLaunchingProviders = true;
12002 if (wasInLaunchingProviders) {
12003 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12005 synchronized (dst) {
12006 dst.provider = src.provider;
12010 updateOomAdjLocked(r, true);
12011 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12012 src.info.authority);
12016 Binder.restoreCallingIdentity(origId);
12020 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12021 ContentProviderConnection conn;
12023 conn = (ContentProviderConnection)connection;
12024 } catch (ClassCastException e) {
12025 String msg ="refContentProvider: " + connection
12026 + " not a ContentProviderConnection";
12028 throw new IllegalArgumentException(msg);
12030 if (conn == null) {
12031 throw new NullPointerException("connection is null");
12034 synchronized (this) {
12036 conn.numStableIncs += stable;
12038 stable = conn.stableCount + stable;
12040 throw new IllegalStateException("stableCount < 0: " + stable);
12043 if (unstable > 0) {
12044 conn.numUnstableIncs += unstable;
12046 unstable = conn.unstableCount + unstable;
12047 if (unstable < 0) {
12048 throw new IllegalStateException("unstableCount < 0: " + unstable);
12051 if ((stable+unstable) <= 0) {
12052 throw new IllegalStateException("ref counts can't go to zero here: stable="
12053 + stable + " unstable=" + unstable);
12055 conn.stableCount = stable;
12056 conn.unstableCount = unstable;
12061 public void unstableProviderDied(IBinder connection) {
12062 ContentProviderConnection conn;
12064 conn = (ContentProviderConnection)connection;
12065 } catch (ClassCastException e) {
12066 String msg ="refContentProvider: " + connection
12067 + " not a ContentProviderConnection";
12069 throw new IllegalArgumentException(msg);
12071 if (conn == null) {
12072 throw new NullPointerException("connection is null");
12075 // Safely retrieve the content provider associated with the connection.
12076 IContentProvider provider;
12077 synchronized (this) {
12078 provider = conn.provider.provider;
12081 if (provider == null) {
12082 // Um, yeah, we're way ahead of you.
12086 // Make sure the caller is being honest with us.
12087 if (provider.asBinder().pingBinder()) {
12088 // Er, no, still looks good to us.
12089 synchronized (this) {
12090 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12091 + " says " + conn + " died, but we don't agree");
12096 // Well look at that! It's dead!
12097 synchronized (this) {
12098 if (conn.provider.provider != provider) {
12099 // But something changed... good enough.
12103 ProcessRecord proc = conn.provider.proc;
12104 if (proc == null || proc.thread == null) {
12105 // Seems like the process is already cleaned up.
12109 // As far as we're concerned, this is just like receiving a
12110 // death notification... just a bit prematurely.
12111 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12112 + ") early provider death");
12113 final long ident = Binder.clearCallingIdentity();
12115 appDiedLocked(proc);
12117 Binder.restoreCallingIdentity(ident);
12123 public void appNotRespondingViaProvider(IBinder connection) {
12124 enforceCallingPermission(
12125 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12127 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12128 if (conn == null) {
12129 Slog.w(TAG, "ContentProviderConnection is null");
12133 final ProcessRecord host = conn.provider.proc;
12134 if (host == null) {
12135 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12139 mHandler.post(new Runnable() {
12141 public void run() {
12142 mAppErrors.appNotResponding(host, null, null, false,
12143 "ContentProvider not responding");
12148 public final void installSystemProviders() {
12149 List<ProviderInfo> providers;
12150 synchronized (this) {
12151 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12152 providers = generateApplicationProvidersLocked(app);
12153 if (providers != null) {
12154 for (int i=providers.size()-1; i>=0; i--) {
12155 ProviderInfo pi = (ProviderInfo)providers.get(i);
12156 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12157 Slog.w(TAG, "Not installing system proc provider " + pi.name
12158 + ": not system .apk");
12159 providers.remove(i);
12164 if (providers != null) {
12165 mSystemThread.installSystemProviders(providers);
12168 mConstants.start(mContext.getContentResolver());
12169 mCoreSettingsObserver = new CoreSettingsObserver(this);
12170 mFontScaleSettingObserver = new FontScaleSettingObserver();
12172 // Now that the settings provider is published we can consider sending
12173 // in a rescue party.
12174 RescueParty.onSettingsProviderPublished(mContext);
12176 //mUsageStatsService.monitorPackages();
12179 private void startPersistentApps(int matchFlags) {
12180 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12182 synchronized (this) {
12184 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12185 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12186 for (ApplicationInfo app : apps) {
12187 if (!"android".equals(app.packageName)) {
12188 addAppLocked(app, null, false, null /* ABI override */);
12191 } catch (RemoteException ex) {
12197 * When a user is unlocked, we need to install encryption-unaware providers
12198 * belonging to any running apps.
12200 private void installEncryptionUnawareProviders(int userId) {
12201 // We're only interested in providers that are encryption unaware, and
12202 // we don't care about uninstalled apps, since there's no way they're
12203 // running at this point.
12204 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12206 synchronized (this) {
12207 final int NP = mProcessNames.getMap().size();
12208 for (int ip = 0; ip < NP; ip++) {
12209 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12210 final int NA = apps.size();
12211 for (int ia = 0; ia < NA; ia++) {
12212 final ProcessRecord app = apps.valueAt(ia);
12213 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12215 final int NG = app.pkgList.size();
12216 for (int ig = 0; ig < NG; ig++) {
12218 final String pkgName = app.pkgList.keyAt(ig);
12219 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12220 .getPackageInfo(pkgName, matchFlags, userId);
12221 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12222 for (ProviderInfo pi : pkgInfo.providers) {
12223 // TODO: keep in sync with generateApplicationProvidersLocked
12224 final boolean processMatch = Objects.equals(pi.processName,
12225 app.processName) || pi.multiprocess;
12226 final boolean userMatch = isSingleton(pi.processName,
12227 pi.applicationInfo, pi.name, pi.flags)
12228 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12229 if (processMatch && userMatch) {
12230 Log.v(TAG, "Installing " + pi);
12231 app.thread.scheduleInstallProvider(pi);
12233 Log.v(TAG, "Skipping " + pi);
12237 } catch (RemoteException ignored) {
12246 * Allows apps to retrieve the MIME type of a URI.
12247 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12248 * users, then it does not need permission to access the ContentProvider.
12249 * Either, it needs cross-user uri grants.
12251 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12253 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12254 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12256 public String getProviderMimeType(Uri uri, int userId) {
12257 enforceNotIsolatedCaller("getProviderMimeType");
12258 final String name = uri.getAuthority();
12259 int callingUid = Binder.getCallingUid();
12260 int callingPid = Binder.getCallingPid();
12262 boolean clearedIdentity = false;
12263 synchronized (this) {
12264 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12266 if (canClearIdentity(callingPid, callingUid, userId)) {
12267 clearedIdentity = true;
12268 ident = Binder.clearCallingIdentity();
12270 ContentProviderHolder holder = null;
12272 holder = getContentProviderExternalUnchecked(name, null, userId);
12273 if (holder != null) {
12274 return holder.provider.getType(uri);
12276 } catch (RemoteException e) {
12277 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12279 } catch (Exception e) {
12280 Log.w(TAG, "Exception while determining type of " + uri, e);
12283 // We need to clear the identity to call removeContentProviderExternalUnchecked
12284 if (!clearedIdentity) {
12285 ident = Binder.clearCallingIdentity();
12288 if (holder != null) {
12289 removeContentProviderExternalUnchecked(name, null, userId);
12292 Binder.restoreCallingIdentity(ident);
12299 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12300 if (UserHandle.getUserId(callingUid) == userId) {
12303 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12304 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12305 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12306 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12312 // =========================================================
12313 // GLOBAL MANAGEMENT
12314 // =========================================================
12316 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12317 boolean isolated, int isolatedUid) {
12318 String proc = customProcess != null ? customProcess : info.processName;
12319 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12320 final int userId = UserHandle.getUserId(info.uid);
12321 int uid = info.uid;
12323 if (isolatedUid == 0) {
12324 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12326 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12327 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12328 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12330 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12331 mNextIsolatedProcessUid++;
12332 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12333 // No process for this uid, use it.
12337 if (stepsLeft <= 0) {
12342 // Special case for startIsolatedProcess (internal only), where
12343 // the uid of the isolated process is specified by the caller.
12346 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12348 // Register the isolated UID with this application so BatteryStats knows to
12349 // attribute resource usage to the application.
12351 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12352 // about the process state of the isolated UID *before* it is registered with the
12353 // owning application.
12354 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12356 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12357 if (!mBooted && !mBooting
12358 && userId == UserHandle.USER_SYSTEM
12359 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12360 r.persistent = true;
12361 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12363 addProcessNameLocked(r);
12367 private boolean uidOnBackgroundWhitelist(final int uid) {
12368 final int appId = UserHandle.getAppId(uid);
12369 final int[] whitelist = mBackgroundAppIdWhitelist;
12370 final int N = whitelist.length;
12371 for (int i = 0; i < N; i++) {
12372 if (appId == whitelist[i]) {
12380 public void backgroundWhitelistUid(final int uid) {
12381 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12382 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12385 if (DEBUG_BACKGROUND_CHECK) {
12386 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12388 synchronized (this) {
12389 final int N = mBackgroundAppIdWhitelist.length;
12390 int[] newList = new int[N+1];
12391 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12392 newList[N] = UserHandle.getAppId(uid);
12393 mBackgroundAppIdWhitelist = newList;
12397 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12398 String abiOverride) {
12401 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12408 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12409 updateLruProcessLocked(app, false, null);
12410 updateOomAdjLocked();
12413 // This package really, really can not be stopped.
12415 AppGlobals.getPackageManager().setPackageStoppedState(
12416 info.packageName, false, UserHandle.getUserId(app.uid));
12417 } catch (RemoteException e) {
12418 } catch (IllegalArgumentException e) {
12419 Slog.w(TAG, "Failed trying to unstop package "
12420 + info.packageName + ": " + e);
12423 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12424 app.persistent = true;
12425 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12427 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12428 mPersistentStartingProcesses.add(app);
12429 startProcessLocked(app, "added application",
12430 customProcess != null ? customProcess : app.processName, abiOverride,
12431 null /* entryPoint */, null /* entryPointArgs */);
12437 public void unhandledBack() {
12438 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12439 "unhandledBack()");
12441 synchronized(this) {
12442 final long origId = Binder.clearCallingIdentity();
12444 getFocusedStack().unhandledBackLocked();
12446 Binder.restoreCallingIdentity(origId);
12451 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12452 enforceNotIsolatedCaller("openContentUri");
12453 final int userId = UserHandle.getCallingUserId();
12454 final Uri uri = Uri.parse(uriString);
12455 String name = uri.getAuthority();
12456 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12457 ParcelFileDescriptor pfd = null;
12459 // We record the binder invoker's uid in thread-local storage before
12460 // going to the content provider to open the file. Later, in the code
12461 // that handles all permissions checks, we look for this uid and use
12462 // that rather than the Activity Manager's own uid. The effect is that
12463 // we do the check against the caller's permissions even though it looks
12464 // to the content provider like the Activity Manager itself is making
12466 Binder token = new Binder();
12467 sCallerIdentity.set(new Identity(
12468 token, Binder.getCallingPid(), Binder.getCallingUid()));
12470 pfd = cph.provider.openFile(null, uri, "r", null, token);
12471 } catch (FileNotFoundException e) {
12472 // do nothing; pfd will be returned null
12474 // Ensure that whatever happens, we clean up the identity state
12475 sCallerIdentity.remove();
12476 // Ensure we're done with the provider.
12477 removeContentProviderExternalUnchecked(name, null, userId);
12480 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12485 // Actually is sleeping or shutting down or whatever else in the future
12486 // is an inactive state.
12487 boolean isSleepingOrShuttingDownLocked() {
12488 return isSleepingLocked() || mShuttingDown;
12491 boolean isShuttingDownLocked() {
12492 return mShuttingDown;
12495 boolean isSleepingLocked() {
12499 void onWakefulnessChanged(int wakefulness) {
12500 synchronized(this) {
12501 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12502 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12503 mWakefulness = wakefulness;
12505 if (wasAwake != isAwake) {
12506 // Also update state in a special way for running foreground services UI.
12507 mServices.updateScreenStateLocked(isAwake);
12508 sendNotifyVrManagerOfSleepState(!isAwake);
12513 void finishRunningVoiceLocked() {
12514 if (mRunningVoice != null) {
12515 mRunningVoice = null;
12516 mVoiceWakeLock.release();
12517 updateSleepIfNeededLocked();
12521 void startTimeTrackingFocusedActivityLocked() {
12522 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12523 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12524 mCurAppTimeTracker.start(resumedActivity.packageName);
12528 void updateSleepIfNeededLocked() {
12529 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12530 final boolean wasSleeping = mSleeping;
12532 if (!shouldSleep) {
12533 // If wasSleeping is true, we need to wake up activity manager state from when
12534 // we started sleeping. In either case, we need to apply the sleep tokens, which
12535 // will wake up stacks or put them to sleep as appropriate.
12538 startTimeTrackingFocusedActivityLocked();
12539 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12540 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12542 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12544 updateOomAdjLocked();
12546 } else if (!mSleeping && shouldSleep) {
12548 if (mCurAppTimeTracker != null) {
12549 mCurAppTimeTracker.stop();
12551 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12552 mStackSupervisor.goingToSleepLocked();
12553 updateOomAdjLocked();
12557 /** Pokes the task persister. */
12558 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12559 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12563 * Notifies all listeners when the pinned stack animation starts.
12566 public void notifyPinnedStackAnimationStarted() {
12567 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12571 * Notifies all listeners when the pinned stack animation ends.
12574 public void notifyPinnedStackAnimationEnded() {
12575 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12579 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12580 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12584 public boolean shutdown(int timeout) {
12585 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12586 != PackageManager.PERMISSION_GRANTED) {
12587 throw new SecurityException("Requires permission "
12588 + android.Manifest.permission.SHUTDOWN);
12591 boolean timedout = false;
12593 synchronized(this) {
12594 mShuttingDown = true;
12595 mStackSupervisor.prepareForShutdownLocked();
12596 updateEventDispatchingLocked();
12597 timedout = mStackSupervisor.shutdownLocked(timeout);
12600 mAppOpsService.shutdown();
12601 if (mUsageStatsService != null) {
12602 mUsageStatsService.prepareShutdown();
12604 mBatteryStatsService.shutdown();
12605 synchronized (this) {
12606 mProcessStats.shutdownLocked();
12607 notifyTaskPersisterLocked(null, true);
12613 public final void activitySlept(IBinder token) {
12614 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12616 final long origId = Binder.clearCallingIdentity();
12618 synchronized (this) {
12619 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12621 mStackSupervisor.activitySleptLocked(r);
12625 Binder.restoreCallingIdentity(origId);
12628 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12629 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12630 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12631 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12632 boolean wasRunningVoice = mRunningVoice != null;
12633 mRunningVoice = session;
12634 if (!wasRunningVoice) {
12635 mVoiceWakeLock.acquire();
12636 updateSleepIfNeededLocked();
12641 private void updateEventDispatchingLocked() {
12642 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12646 public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12647 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12648 != PackageManager.PERMISSION_GRANTED) {
12649 throw new SecurityException("Requires permission "
12650 + android.Manifest.permission.DEVICE_POWER);
12653 synchronized(this) {
12654 long ident = Binder.clearCallingIdentity();
12656 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12658 Binder.restoreCallingIdentity(ident);
12661 sendNotifyVrManagerOfKeyguardState(showing);
12665 public void notifyLockedProfile(@UserIdInt int userId) {
12667 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12668 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12670 } catch (RemoteException ex) {
12671 throw new SecurityException("Fail to check is caller a privileged app", ex);
12674 synchronized (this) {
12675 final long ident = Binder.clearCallingIdentity();
12677 if (mUserController.shouldConfirmCredentials(userId)) {
12678 if (mKeyguardController.isKeyguardLocked()) {
12679 // Showing launcher to avoid user entering credential twice.
12680 final int currentUserId = mUserController.getCurrentUserIdLocked();
12681 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12683 mStackSupervisor.lockAllProfileTasks(userId);
12686 Binder.restoreCallingIdentity(ident);
12692 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12693 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12694 synchronized (this) {
12695 final long ident = Binder.clearCallingIdentity();
12697 mActivityStarter.startConfirmCredentialIntent(intent, options);
12699 Binder.restoreCallingIdentity(ident);
12705 public void stopAppSwitches() {
12706 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12707 != PackageManager.PERMISSION_GRANTED) {
12708 throw new SecurityException("viewquires permission "
12709 + android.Manifest.permission.STOP_APP_SWITCHES);
12712 synchronized(this) {
12713 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12714 + APP_SWITCH_DELAY_TIME;
12715 mDidAppSwitch = false;
12716 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12717 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12718 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12722 public void resumeAppSwitches() {
12723 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12724 != PackageManager.PERMISSION_GRANTED) {
12725 throw new SecurityException("Requires permission "
12726 + android.Manifest.permission.STOP_APP_SWITCHES);
12729 synchronized(this) {
12730 // Note that we don't execute any pending app switches... we will
12731 // let those wait until either the timeout, or the next start
12732 // activity request.
12733 mAppSwitchesAllowedTime = 0;
12737 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12738 int callingPid, int callingUid, String name) {
12739 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12743 int perm = checkComponentPermission(
12744 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12745 sourceUid, -1, true);
12746 if (perm == PackageManager.PERMISSION_GRANTED) {
12750 // If the actual IPC caller is different from the logical source, then
12751 // also see if they are allowed to control app switches.
12752 if (callingUid != -1 && callingUid != sourceUid) {
12753 perm = checkComponentPermission(
12754 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12755 callingUid, -1, true);
12756 if (perm == PackageManager.PERMISSION_GRANTED) {
12761 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12765 public void setDebugApp(String packageName, boolean waitForDebugger,
12766 boolean persistent) {
12767 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12770 long ident = Binder.clearCallingIdentity();
12772 // Note that this is not really thread safe if there are multiple
12773 // callers into it at the same time, but that's not a situation we
12776 final ContentResolver resolver = mContext.getContentResolver();
12777 Settings.Global.putString(
12778 resolver, Settings.Global.DEBUG_APP,
12780 Settings.Global.putInt(
12781 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12782 waitForDebugger ? 1 : 0);
12785 synchronized (this) {
12787 mOrigDebugApp = mDebugApp;
12788 mOrigWaitForDebugger = mWaitForDebugger;
12790 mDebugApp = packageName;
12791 mWaitForDebugger = waitForDebugger;
12792 mDebugTransient = !persistent;
12793 if (packageName != null) {
12794 forceStopPackageLocked(packageName, -1, false, false, true, true,
12795 false, UserHandle.USER_ALL, "set debug app");
12799 Binder.restoreCallingIdentity(ident);
12803 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12804 synchronized (this) {
12805 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12806 if (!isDebuggable) {
12807 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12808 throw new SecurityException("Process not debuggable: " + app.packageName);
12812 mTrackAllocationApp = processName;
12816 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12817 synchronized (this) {
12818 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12819 if (!isDebuggable) {
12820 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12821 throw new SecurityException("Process not debuggable: " + app.packageName);
12824 mProfileApp = processName;
12826 if (mProfilerInfo != null) {
12827 if (mProfilerInfo.profileFd != null) {
12829 mProfilerInfo.profileFd.close();
12830 } catch (IOException e) {
12834 mProfilerInfo = new ProfilerInfo(profilerInfo);
12839 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12840 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12841 if (!isDebuggable) {
12842 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12843 throw new SecurityException("Process not debuggable: " + app.packageName);
12846 mNativeDebuggingApp = processName;
12850 public void setAlwaysFinish(boolean enabled) {
12851 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12852 "setAlwaysFinish()");
12854 long ident = Binder.clearCallingIdentity();
12856 Settings.Global.putInt(
12857 mContext.getContentResolver(),
12858 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12860 synchronized (this) {
12861 mAlwaysFinishActivities = enabled;
12864 Binder.restoreCallingIdentity(ident);
12869 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12870 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12871 "setActivityController()");
12872 synchronized (this) {
12873 mController = controller;
12874 mControllerIsAMonkey = imAMonkey;
12875 Watchdog.getInstance().setActivityController(controller);
12880 public void setUserIsMonkey(boolean userIsMonkey) {
12881 synchronized (this) {
12882 synchronized (mPidsSelfLocked) {
12883 final int callingPid = Binder.getCallingPid();
12884 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12885 if (proc == null) {
12886 throw new SecurityException("Unknown process: " + callingPid);
12888 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12889 throw new SecurityException("Only an instrumentation process "
12890 + "with a UiAutomation can call setUserIsMonkey");
12893 mUserIsMonkey = userIsMonkey;
12898 public boolean isUserAMonkey() {
12899 synchronized (this) {
12900 // If there is a controller also implies the user is a monkey.
12901 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12906 * @deprecated This method is only used by a few internal components and it will soon be
12907 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12908 * No new code should be calling it.
12912 public void requestBugReport(int bugreportType) {
12913 String extraOptions = null;
12914 switch (bugreportType) {
12915 case ActivityManager.BUGREPORT_OPTION_FULL:
12916 // Default options.
12918 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12919 extraOptions = "bugreportplus";
12921 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12922 extraOptions = "bugreportremote";
12924 case ActivityManager.BUGREPORT_OPTION_WEAR:
12925 extraOptions = "bugreportwear";
12927 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12928 extraOptions = "bugreporttelephony";
12931 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12934 // Always log caller, even if it does not have permission to dump.
12935 String type = extraOptions == null ? "bugreport" : extraOptions;
12936 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12938 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12939 if (extraOptions != null) {
12940 SystemProperties.set("dumpstate.options", extraOptions);
12942 SystemProperties.set("ctl.start", "bugreport");
12946 * @deprecated This method is only used by a few internal components and it will soon be
12947 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12948 * No new code should be calling it.
12952 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12954 if (!TextUtils.isEmpty(shareTitle)) {
12955 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12956 String errorStr = "shareTitle should be less than " +
12957 MAX_BUGREPORT_TITLE_SIZE + " characters";
12958 throw new IllegalArgumentException(errorStr);
12960 if (!TextUtils.isEmpty(shareDescription)) {
12963 length = shareDescription.getBytes("UTF-8").length;
12964 } catch (UnsupportedEncodingException e) {
12965 String errorStr = "shareDescription: UnsupportedEncodingException";
12966 throw new IllegalArgumentException(errorStr);
12968 if (length > SystemProperties.PROP_VALUE_MAX) {
12969 String errorStr = "shareTitle should be less than " +
12970 SystemProperties.PROP_VALUE_MAX + " bytes";
12971 throw new IllegalArgumentException(errorStr);
12973 SystemProperties.set("dumpstate.options.description", shareDescription);
12976 SystemProperties.set("dumpstate.options.title", shareTitle);
12980 Slog.d(TAG, "Bugreport notification title " + shareTitle
12981 + " description " + shareDescription);
12982 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12985 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12986 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12989 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12990 if (r != null && (r.instr != null || r.usingWrapper)) {
12991 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12993 return KEY_DISPATCHING_TIMEOUT;
12997 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12998 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12999 != PackageManager.PERMISSION_GRANTED) {
13000 throw new SecurityException("Requires permission "
13001 + android.Manifest.permission.FILTER_EVENTS);
13003 ProcessRecord proc;
13005 synchronized (this) {
13006 synchronized (mPidsSelfLocked) {
13007 proc = mPidsSelfLocked.get(pid);
13009 timeout = getInputDispatchingTimeoutLocked(proc);
13012 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13020 * Handle input dispatching timeouts.
13021 * Returns whether input dispatching should be aborted or not.
13023 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13024 final ActivityRecord activity, final ActivityRecord parent,
13025 final boolean aboveSystem, String reason) {
13026 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13027 != PackageManager.PERMISSION_GRANTED) {
13028 throw new SecurityException("Requires permission "
13029 + android.Manifest.permission.FILTER_EVENTS);
13032 final String annotation;
13033 if (reason == null) {
13034 annotation = "Input dispatching timed out";
13036 annotation = "Input dispatching timed out (" + reason + ")";
13039 if (proc != null) {
13040 synchronized (this) {
13041 if (proc.debugging) {
13045 if (proc.instr != null) {
13046 Bundle info = new Bundle();
13047 info.putString("shortMsg", "keyDispatchingTimedOut");
13048 info.putString("longMsg", annotation);
13049 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13053 mHandler.post(new Runnable() {
13055 public void run() {
13056 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13065 public Bundle getAssistContextExtras(int requestType) {
13066 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13067 null, null, true /* focused */, true /* newSessionId */,
13068 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13072 synchronized (pae) {
13073 while (!pae.haveResult) {
13076 } catch (InterruptedException e) {
13080 synchronized (this) {
13081 buildAssistBundleLocked(pae, pae.result);
13082 mPendingAssistExtras.remove(pae);
13083 mUiHandler.removeCallbacks(pae);
13089 public boolean isAssistDataAllowedOnCurrentActivity() {
13091 synchronized (this) {
13092 final ActivityStack focusedStack = getFocusedStack();
13093 if (focusedStack == null || focusedStack.isAssistantStack()) {
13097 final ActivityRecord activity = focusedStack.topActivity();
13098 if (activity == null) {
13101 userId = activity.userId;
13103 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13104 Context.DEVICE_POLICY_SERVICE);
13105 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13109 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13110 long ident = Binder.clearCallingIdentity();
13112 synchronized (this) {
13113 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13114 ActivityRecord top = getFocusedStack().topActivity();
13115 if (top != caller) {
13116 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13117 + " is not current top " + top);
13120 if (!top.nowVisible) {
13121 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13122 + " is not visible");
13126 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13129 Binder.restoreCallingIdentity(ident);
13134 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13135 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13136 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13137 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13138 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13142 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13143 IBinder activityToken, int flags) {
13144 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13145 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13146 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13149 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13150 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13151 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13153 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13154 "enqueueAssistContext()");
13156 synchronized (this) {
13157 ActivityRecord activity = getFocusedStack().topActivity();
13158 if (activity == null) {
13159 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13162 if (activity.app == null || activity.app.thread == null) {
13163 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13167 if (activityToken != null) {
13168 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13169 if (activity != caller) {
13170 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13171 + " is not current top " + activity);
13176 activity = ActivityRecord.forTokenLocked(activityToken);
13177 if (activity == null) {
13178 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13179 + " couldn't be found");
13182 if (activity.app == null || activity.app.thread == null) {
13183 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13188 PendingAssistExtras pae;
13189 Bundle extras = new Bundle();
13190 if (args != null) {
13191 extras.putAll(args);
13193 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13194 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13196 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13198 pae.isHome = activity.isHomeActivity();
13200 // Increment the sessionId if necessary
13201 if (newSessionId) {
13205 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13206 mViSessionId, flags);
13207 mPendingAssistExtras.add(pae);
13208 mUiHandler.postDelayed(pae, timeout);
13209 } catch (RemoteException e) {
13210 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13217 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13218 IResultReceiver receiver;
13219 synchronized (this) {
13220 mPendingAssistExtras.remove(pae);
13221 receiver = pae.receiver;
13223 if (receiver != null) {
13224 // Caller wants result sent back to them.
13225 Bundle sendBundle = new Bundle();
13226 // At least return the receiver extras
13227 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13228 pae.receiverExtras);
13230 pae.receiver.send(0, sendBundle);
13231 } catch (RemoteException e) {
13236 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13237 if (result != null) {
13238 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13240 if (pae.hint != null) {
13241 pae.extras.putBoolean(pae.hint, true);
13245 /** Called from an app when assist data is ready. */
13247 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13248 AssistContent content, Uri referrer) {
13249 PendingAssistExtras pae = (PendingAssistExtras)token;
13250 synchronized (pae) {
13251 pae.result = extras;
13252 pae.structure = structure;
13253 pae.content = content;
13254 if (referrer != null) {
13255 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13257 if (structure != null) {
13258 structure.setHomeActivity(pae.isHome);
13260 pae.haveResult = true;
13262 if (pae.intent == null && pae.receiver == null) {
13263 // Caller is just waiting for the result.
13267 // We are now ready to launch the assist activity.
13268 IResultReceiver sendReceiver = null;
13269 Bundle sendBundle = null;
13270 synchronized (this) {
13271 buildAssistBundleLocked(pae, extras);
13272 boolean exists = mPendingAssistExtras.remove(pae);
13273 mUiHandler.removeCallbacks(pae);
13278 if ((sendReceiver=pae.receiver) != null) {
13279 // Caller wants result sent back to them.
13280 sendBundle = new Bundle();
13281 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13282 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13283 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13284 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13285 pae.receiverExtras);
13288 if (sendReceiver != null) {
13290 sendReceiver.send(0, sendBundle);
13291 } catch (RemoteException e) {
13296 final long ident = Binder.clearCallingIdentity();
13298 if (TextUtils.equals(pae.intent.getAction(),
13299 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13300 pae.intent.putExtras(pae.extras);
13301 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13303 pae.intent.replaceExtras(pae.extras);
13304 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13305 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13306 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13307 closeSystemDialogs("assist");
13310 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13311 } catch (ActivityNotFoundException e) {
13312 Slog.w(TAG, "No activity to handle assist action.", e);
13316 Binder.restoreCallingIdentity(ident);
13320 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13322 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13323 true /* focused */, true /* newSessionId */, userHandle, args,
13324 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13327 public void registerProcessObserver(IProcessObserver observer) {
13328 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13329 "registerProcessObserver()");
13330 synchronized (this) {
13331 mProcessObservers.register(observer);
13336 public void unregisterProcessObserver(IProcessObserver observer) {
13337 synchronized (this) {
13338 mProcessObservers.unregister(observer);
13343 public int getUidProcessState(int uid, String callingPackage) {
13344 if (!hasUsageStatsPermission(callingPackage)) {
13345 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13346 "getUidProcessState");
13349 synchronized (this) {
13350 UidRecord uidRec = mActiveUids.get(uid);
13351 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13356 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13357 String callingPackage) {
13358 if (!hasUsageStatsPermission(callingPackage)) {
13359 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13360 "registerUidObserver");
13362 synchronized (this) {
13363 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13364 callingPackage, which, cutpoint));
13369 public void unregisterUidObserver(IUidObserver observer) {
13370 synchronized (this) {
13371 mUidObservers.unregister(observer);
13376 public boolean convertFromTranslucent(IBinder token) {
13377 final long origId = Binder.clearCallingIdentity();
13379 synchronized (this) {
13380 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13384 final boolean translucentChanged = r.changeWindowTranslucency(true);
13385 if (translucentChanged) {
13386 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13388 mWindowManager.setAppFullscreen(token, true);
13389 return translucentChanged;
13392 Binder.restoreCallingIdentity(origId);
13397 public boolean convertToTranslucent(IBinder token, Bundle options) {
13398 final long origId = Binder.clearCallingIdentity();
13400 synchronized (this) {
13401 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13405 final TaskRecord task = r.getTask();
13406 int index = task.mActivities.lastIndexOf(r);
13408 ActivityRecord under = task.mActivities.get(index - 1);
13409 under.returningOptions = ActivityOptions.fromBundle(options);
13411 final boolean translucentChanged = r.changeWindowTranslucency(false);
13412 if (translucentChanged) {
13413 r.getStack().convertActivityToTranslucent(r);
13415 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13416 mWindowManager.setAppFullscreen(token, false);
13417 return translucentChanged;
13420 Binder.restoreCallingIdentity(origId);
13425 public Bundle getActivityOptions(IBinder token) {
13426 final long origId = Binder.clearCallingIdentity();
13428 synchronized (this) {
13429 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13431 final ActivityOptions activityOptions = r.takeOptionsLocked();
13432 return activityOptions == null ? null : activityOptions.toBundle();
13437 Binder.restoreCallingIdentity(origId);
13442 public void setImmersive(IBinder token, boolean immersive) {
13443 synchronized(this) {
13444 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13446 throw new IllegalArgumentException();
13448 r.immersive = immersive;
13450 // update associated state if we're frontmost
13451 if (r == mStackSupervisor.getResumedActivityLocked()) {
13452 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13453 applyUpdateLockStateLocked(r);
13459 public boolean isImmersive(IBinder token) {
13460 synchronized (this) {
13461 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13463 throw new IllegalArgumentException();
13465 return r.immersive;
13470 public void setVrThread(int tid) {
13471 enforceSystemHasVrFeature();
13472 synchronized (this) {
13473 synchronized (mPidsSelfLocked) {
13474 final int pid = Binder.getCallingPid();
13475 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13476 mVrController.setVrThreadLocked(tid, pid, proc);
13482 public void setPersistentVrThread(int tid) {
13483 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13484 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13485 + Binder.getCallingPid()
13486 + ", uid=" + Binder.getCallingUid()
13487 + " requires " + permission.RESTRICTED_VR_ACCESS;
13489 throw new SecurityException(msg);
13491 enforceSystemHasVrFeature();
13492 synchronized (this) {
13493 synchronized (mPidsSelfLocked) {
13494 final int pid = Binder.getCallingPid();
13495 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13496 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13502 * Schedule the given thread a normal scheduling priority.
13504 * @param tid the tid of the thread to adjust the scheduling of.
13505 * @param suppressLogs {@code true} if any error logging should be disabled.
13507 * @return {@code true} if this succeeded.
13509 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13511 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13513 } catch (IllegalArgumentException e) {
13514 if (!suppressLogs) {
13515 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13517 } catch (SecurityException e) {
13518 if (!suppressLogs) {
13519 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13526 * Schedule the given thread an FIFO scheduling priority.
13528 * @param tid the tid of the thread to adjust the scheduling of.
13529 * @param suppressLogs {@code true} if any error logging should be disabled.
13531 * @return {@code true} if this succeeded.
13533 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13535 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13537 } catch (IllegalArgumentException e) {
13538 if (!suppressLogs) {
13539 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13541 } catch (SecurityException e) {
13542 if (!suppressLogs) {
13543 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13550 * Check that we have the features required for VR-related API calls, and throw an exception if
13553 private void enforceSystemHasVrFeature() {
13554 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13555 throw new UnsupportedOperationException("VR mode not supported on this device!");
13560 public void setRenderThread(int tid) {
13561 synchronized (this) {
13562 ProcessRecord proc;
13563 int pid = Binder.getCallingPid();
13564 if (pid == Process.myPid()) {
13565 demoteSystemServerRenderThread(tid);
13568 synchronized (mPidsSelfLocked) {
13569 proc = mPidsSelfLocked.get(pid);
13570 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13571 // ensure the tid belongs to the process
13572 if (!isThreadInProcess(pid, tid)) {
13573 throw new IllegalArgumentException(
13574 "Render thread does not belong to process");
13576 proc.renderThreadTid = tid;
13577 if (DEBUG_OOM_ADJ) {
13578 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13580 // promote to FIFO now
13581 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13582 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13583 if (mUseFifoUiScheduling) {
13584 setThreadScheduler(proc.renderThreadTid,
13585 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13587 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13591 if (DEBUG_OOM_ADJ) {
13592 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13593 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13594 mUseFifoUiScheduling);
13602 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13603 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13605 * @param tid the tid of the RenderThread
13607 private void demoteSystemServerRenderThread(int tid) {
13608 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13612 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13613 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13614 throw new UnsupportedOperationException("VR mode not supported on this device!");
13617 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13620 synchronized (this) {
13621 r = ActivityRecord.isInStackLocked(token);
13625 throw new IllegalArgumentException();
13629 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13630 VrManagerInternal.NO_ERROR) {
13634 synchronized(this) {
13635 r.requestedVrComponent = (enabled) ? packageName : null;
13637 // Update associated state if this activity is currently focused
13638 if (r == mStackSupervisor.getResumedActivityLocked()) {
13639 applyUpdateVrModeLocked(r);
13646 public boolean isVrModePackageEnabled(ComponentName packageName) {
13647 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13648 throw new UnsupportedOperationException("VR mode not supported on this device!");
13651 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13653 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13654 VrManagerInternal.NO_ERROR;
13657 public boolean isTopActivityImmersive() {
13658 enforceNotIsolatedCaller("startActivity");
13659 synchronized (this) {
13660 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13661 return (r != null) ? r.immersive : false;
13666 * @return whether the system should disable UI modes incompatible with VR mode.
13668 boolean shouldDisableNonVrUiLocked() {
13669 return mVrController.shouldDisableNonVrUiLocked();
13673 public boolean isTopOfTask(IBinder token) {
13674 synchronized (this) {
13675 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13677 throw new IllegalArgumentException();
13679 return r.getTask().getTopActivity() == r;
13684 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13685 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13686 String msg = "Permission Denial: setHasTopUi() from pid="
13687 + Binder.getCallingPid()
13688 + ", uid=" + Binder.getCallingUid()
13689 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13691 throw new SecurityException(msg);
13693 final int pid = Binder.getCallingPid();
13694 final long origId = Binder.clearCallingIdentity();
13696 synchronized (this) {
13697 boolean changed = false;
13699 synchronized (mPidsSelfLocked) {
13700 pr = mPidsSelfLocked.get(pid);
13702 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13705 if (pr.hasTopUi != hasTopUi) {
13706 if (DEBUG_OOM_ADJ) {
13707 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13709 pr.hasTopUi = hasTopUi;
13714 updateOomAdjLocked(pr, true);
13718 Binder.restoreCallingIdentity(origId);
13722 public final void enterSafeMode() {
13723 synchronized(this) {
13724 // It only makes sense to do this before the system is ready
13725 // and started launching other packages.
13726 if (!mSystemReady) {
13728 AppGlobals.getPackageManager().enterSafeMode();
13729 } catch (RemoteException e) {
13737 public final void showSafeModeOverlay() {
13738 View v = LayoutInflater.from(mContext).inflate(
13739 com.android.internal.R.layout.safe_mode, null);
13740 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13741 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13742 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13743 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13744 lp.gravity = Gravity.BOTTOM | Gravity.START;
13745 lp.format = v.getBackground().getOpacity();
13746 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13747 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13748 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13749 ((WindowManager)mContext.getSystemService(
13750 Context.WINDOW_SERVICE)).addView(v, lp);
13753 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13754 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13757 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13758 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13759 synchronized (stats) {
13760 if (mBatteryStatsService.isOnBattery()) {
13761 mBatteryStatsService.enforceCallingPermission();
13762 int MY_UID = Binder.getCallingUid();
13764 if (sender == null) {
13767 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13769 BatteryStatsImpl.Uid.Pkg pkg =
13770 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13771 sourcePkg != null ? sourcePkg : rec.key.packageName);
13772 pkg.noteWakeupAlarmLocked(tag);
13777 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13778 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13781 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13782 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13783 synchronized (stats) {
13784 mBatteryStatsService.enforceCallingPermission();
13785 int MY_UID = Binder.getCallingUid();
13787 if (sender == null) {
13790 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13792 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13796 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13797 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13800 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13801 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13802 synchronized (stats) {
13803 mBatteryStatsService.enforceCallingPermission();
13804 int MY_UID = Binder.getCallingUid();
13806 if (sender == null) {
13809 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13811 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13815 public boolean killPids(int[] pids, String pReason, boolean secure) {
13816 if (Binder.getCallingUid() != SYSTEM_UID) {
13817 throw new SecurityException("killPids only available to the system");
13819 String reason = (pReason == null) ? "Unknown" : pReason;
13820 // XXX Note: don't acquire main activity lock here, because the window
13821 // manager calls in with its locks held.
13823 boolean killed = false;
13824 synchronized (mPidsSelfLocked) {
13826 for (int i=0; i<pids.length; i++) {
13827 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13828 if (proc != null) {
13829 int type = proc.setAdj;
13830 if (type > worstType) {
13836 // If the worst oom_adj is somewhere in the cached proc LRU range,
13837 // then constrain it so we will kill all cached procs.
13838 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13839 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13840 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13843 // If this is not a secure call, don't let it kill processes that
13845 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13846 worstType = ProcessList.SERVICE_ADJ;
13849 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13850 for (int i=0; i<pids.length; i++) {
13851 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13852 if (proc == null) {
13855 int adj = proc.setAdj;
13856 if (adj >= worstType && !proc.killedByAm) {
13857 proc.kill(reason, true);
13866 public void killUid(int appId, int userId, String reason) {
13867 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13868 synchronized (this) {
13869 final long identity = Binder.clearCallingIdentity();
13871 killPackageProcessesLocked(null, appId, userId,
13872 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13873 reason != null ? reason : "kill uid");
13875 Binder.restoreCallingIdentity(identity);
13881 public boolean killProcessesBelowForeground(String reason) {
13882 if (Binder.getCallingUid() != SYSTEM_UID) {
13883 throw new SecurityException("killProcessesBelowForeground() only available to system");
13886 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13889 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13890 if (Binder.getCallingUid() != SYSTEM_UID) {
13891 throw new SecurityException("killProcessesBelowAdj() only available to system");
13894 boolean killed = false;
13895 synchronized (mPidsSelfLocked) {
13896 final int size = mPidsSelfLocked.size();
13897 for (int i = 0; i < size; i++) {
13898 final int pid = mPidsSelfLocked.keyAt(i);
13899 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13900 if (proc == null) continue;
13902 final int adj = proc.setAdj;
13903 if (adj > belowAdj && !proc.killedByAm) {
13904 proc.kill(reason, true);
13913 public void hang(final IBinder who, boolean allowRestart) {
13914 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13915 != PackageManager.PERMISSION_GRANTED) {
13916 throw new SecurityException("Requires permission "
13917 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13920 final IBinder.DeathRecipient death = new DeathRecipient() {
13922 public void binderDied() {
13923 synchronized (this) {
13930 who.linkToDeath(death, 0);
13931 } catch (RemoteException e) {
13932 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13936 synchronized (this) {
13937 Watchdog.getInstance().setAllowRestart(allowRestart);
13938 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13939 synchronized (death) {
13940 while (who.isBinderAlive()) {
13943 } catch (InterruptedException e) {
13947 Watchdog.getInstance().setAllowRestart(true);
13952 public void restart() {
13953 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13954 != PackageManager.PERMISSION_GRANTED) {
13955 throw new SecurityException("Requires permission "
13956 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13959 Log.i(TAG, "Sending shutdown broadcast...");
13961 BroadcastReceiver br = new BroadcastReceiver() {
13962 @Override public void onReceive(Context context, Intent intent) {
13963 // Now the broadcast is done, finish up the low-level shutdown.
13964 Log.i(TAG, "Shutting down activity manager...");
13966 Log.i(TAG, "Shutdown complete, restarting!");
13967 killProcess(myPid());
13972 // First send the high-level shut down broadcast.
13973 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13974 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13975 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13976 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13977 mContext.sendOrderedBroadcastAsUser(intent,
13978 UserHandle.ALL, null, br, mHandler, 0, null, null);
13980 br.onReceive(mContext, intent);
13983 private long getLowRamTimeSinceIdle(long now) {
13984 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13988 public void performIdleMaintenance() {
13989 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13990 != PackageManager.PERMISSION_GRANTED) {
13991 throw new SecurityException("Requires permission "
13992 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13995 synchronized (this) {
13996 final long now = SystemClock.uptimeMillis();
13997 final long timeSinceLastIdle = now - mLastIdleTime;
13998 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13999 mLastIdleTime = now;
14000 mLowRamTimeSinceLastIdle = 0;
14001 if (mLowRamStartTime != 0) {
14002 mLowRamStartTime = now;
14005 StringBuilder sb = new StringBuilder(128);
14006 sb.append("Idle maintenance over ");
14007 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14008 sb.append(" low RAM for ");
14009 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14010 Slog.i(TAG, sb.toString());
14012 // If at least 1/3 of our time since the last idle period has been spent
14013 // with RAM low, then we want to kill processes.
14014 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14016 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14017 ProcessRecord proc = mLruProcesses.get(i);
14018 if (proc.notCachedSinceIdle) {
14019 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14020 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14021 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14022 if (doKilling && proc.initialIdlePss != 0
14023 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14024 sb = new StringBuilder(128);
14026 sb.append(proc.processName);
14027 sb.append(" in idle maint: pss=");
14028 sb.append(proc.lastPss);
14029 sb.append(", swapPss=");
14030 sb.append(proc.lastSwapPss);
14031 sb.append(", initialPss=");
14032 sb.append(proc.initialIdlePss);
14033 sb.append(", period=");
14034 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14035 sb.append(", lowRamPeriod=");
14036 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14037 Slog.wtfQuiet(TAG, sb.toString());
14038 proc.kill("idle maint (pss " + proc.lastPss
14039 + " from " + proc.initialIdlePss + ")", true);
14042 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14043 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14044 proc.notCachedSinceIdle = true;
14045 proc.initialIdlePss = 0;
14046 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14047 mTestPssMode, isSleepingLocked(), now);
14051 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14052 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14057 public void sendIdleJobTrigger() {
14058 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14059 != PackageManager.PERMISSION_GRANTED) {
14060 throw new SecurityException("Requires permission "
14061 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14064 final long ident = Binder.clearCallingIdentity();
14066 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14067 .setPackage("android")
14068 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14069 broadcastIntent(null, intent, null, null, 0, null, null, null,
14070 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14072 Binder.restoreCallingIdentity(ident);
14076 private void retrieveSettings() {
14077 final ContentResolver resolver = mContext.getContentResolver();
14078 final boolean freeformWindowManagement =
14079 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14080 || Settings.Global.getInt(
14081 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14083 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14084 final boolean supportsPictureInPicture = supportsMultiWindow &&
14085 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14086 final boolean supportsSplitScreenMultiWindow =
14087 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14088 final boolean supportsMultiDisplay = mContext.getPackageManager()
14089 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14090 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14091 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14092 final boolean alwaysFinishActivities =
14093 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14094 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14095 final boolean forceResizable = Settings.Global.getInt(
14096 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14097 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14098 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14099 final boolean supportsLeanbackOnly =
14100 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14102 // Transfer any global setting for forcing RTL layout, into a System Property
14103 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14105 final Configuration configuration = new Configuration();
14106 Settings.System.getConfiguration(resolver, configuration);
14108 // This will take care of setting the correct layout direction flags
14109 configuration.setLayoutDirection(configuration.locale);
14112 synchronized (this) {
14113 mDebugApp = mOrigDebugApp = debugApp;
14114 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14115 mAlwaysFinishActivities = alwaysFinishActivities;
14116 mSupportsLeanbackOnly = supportsLeanbackOnly;
14117 mForceResizableActivities = forceResizable;
14118 final boolean multiWindowFormEnabled = freeformWindowManagement
14119 || supportsSplitScreenMultiWindow
14120 || supportsPictureInPicture
14121 || supportsMultiDisplay;
14122 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14123 mSupportsMultiWindow = true;
14124 mSupportsFreeformWindowManagement = freeformWindowManagement;
14125 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14126 mSupportsPictureInPicture = supportsPictureInPicture;
14127 mSupportsMultiDisplay = supportsMultiDisplay;
14129 mSupportsMultiWindow = false;
14130 mSupportsFreeformWindowManagement = false;
14131 mSupportsSplitScreenMultiWindow = false;
14132 mSupportsPictureInPicture = false;
14133 mSupportsMultiDisplay = false;
14135 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14136 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14137 // This happens before any activities are started, so we can change global configuration
14139 updateConfigurationLocked(configuration, null, true);
14140 final Configuration globalConfig = getGlobalConfiguration();
14141 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14143 // Load resources only after the current configuration has been set.
14144 final Resources res = mContext.getResources();
14145 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14146 mThumbnailWidth = res.getDimensionPixelSize(
14147 com.android.internal.R.dimen.thumbnail_width);
14148 mThumbnailHeight = res.getDimensionPixelSize(
14149 com.android.internal.R.dimen.thumbnail_height);
14150 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14151 com.android.internal.R.string.config_appsNotReportingCrashes));
14152 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14153 com.android.internal.R.bool.config_customUserSwitchUi);
14154 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14155 mFullscreenThumbnailScale = (float) res
14156 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14157 (float) globalConfig.screenWidthDp;
14159 mFullscreenThumbnailScale = res.getFraction(
14160 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14162 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14166 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14167 traceLog.traceBegin("PhaseActivityManagerReady");
14168 synchronized(this) {
14169 if (mSystemReady) {
14170 // If we're done calling all the receivers, run the next "boot phase" passed in
14171 // by the SystemServer
14172 if (goingCallback != null) {
14173 goingCallback.run();
14178 mLocalDeviceIdleController
14179 = LocalServices.getService(DeviceIdleController.LocalService.class);
14180 mAssistUtils = new AssistUtils(mContext);
14181 mVrController.onSystemReady();
14182 // Make sure we have the current profile info, since it is needed for security checks.
14183 mUserController.onSystemReady();
14184 mRecentTasks.onSystemReadyLocked();
14185 mAppOpsService.systemReady();
14186 mSystemReady = true;
14190 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14191 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14193 } catch (RemoteException e) {}
14195 ArrayList<ProcessRecord> procsToKill = null;
14196 synchronized(mPidsSelfLocked) {
14197 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14198 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14199 if (!isAllowedWhileBooting(proc.info)){
14200 if (procsToKill == null) {
14201 procsToKill = new ArrayList<ProcessRecord>();
14203 procsToKill.add(proc);
14208 synchronized(this) {
14209 if (procsToKill != null) {
14210 for (int i=procsToKill.size()-1; i>=0; i--) {
14211 ProcessRecord proc = procsToKill.get(i);
14212 Slog.i(TAG, "Removing system update proc: " + proc);
14213 removeProcessLocked(proc, true, false, "system update done");
14217 // Now that we have cleaned up any update processes, we
14218 // are ready to start launching real processes and know that
14219 // we won't trample on them any more.
14220 mProcessesReady = true;
14223 Slog.i(TAG, "System now ready");
14224 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14225 SystemClock.uptimeMillis());
14227 synchronized(this) {
14228 // Make sure we have no pre-ready processes sitting around.
14230 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14231 ResolveInfo ri = mContext.getPackageManager()
14232 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14234 CharSequence errorMsg = null;
14236 ActivityInfo ai = ri.activityInfo;
14237 ApplicationInfo app = ai.applicationInfo;
14238 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14239 mTopAction = Intent.ACTION_FACTORY_TEST;
14241 mTopComponent = new ComponentName(app.packageName,
14244 errorMsg = mContext.getResources().getText(
14245 com.android.internal.R.string.factorytest_not_system);
14248 errorMsg = mContext.getResources().getText(
14249 com.android.internal.R.string.factorytest_no_action);
14251 if (errorMsg != null) {
14254 mTopComponent = null;
14255 Message msg = Message.obtain();
14256 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14257 msg.getData().putCharSequence("msg", errorMsg);
14258 mUiHandler.sendMessage(msg);
14263 retrieveSettings();
14264 final int currentUserId;
14265 synchronized (this) {
14266 currentUserId = mUserController.getCurrentUserIdLocked();
14267 readGrantedUriPermissionsLocked();
14270 if (goingCallback != null) goingCallback.run();
14271 traceLog.traceBegin("ActivityManagerStartApps");
14272 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14273 Integer.toString(currentUserId), currentUserId);
14274 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14275 Integer.toString(currentUserId), currentUserId);
14276 mSystemServiceManager.startUser(currentUserId);
14278 synchronized (this) {
14279 // Only start up encryption-aware persistent apps; once user is
14280 // unlocked we'll come back around and start unaware apps
14281 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14283 // Start up initial activity.
14285 // Enable home activity for system user, so that the system can always boot. We don't
14286 // do this when the system user is not setup since the setup wizard should be the one
14287 // to handle home activity in this case.
14288 if (UserManager.isSplitSystemUser() &&
14289 Settings.Secure.getInt(mContext.getContentResolver(),
14290 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14291 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14293 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14294 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14295 UserHandle.USER_SYSTEM);
14296 } catch (RemoteException e) {
14297 throw e.rethrowAsRuntimeException();
14300 startHomeActivityLocked(currentUserId, "systemReady");
14303 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14304 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14305 + " data partition or your device will be unstable.");
14306 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14308 } catch (RemoteException e) {
14311 if (!Build.isBuildConsistent()) {
14312 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14313 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14316 long ident = Binder.clearCallingIdentity();
14318 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14320 | Intent.FLAG_RECEIVER_FOREGROUND);
14321 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14322 broadcastIntentLocked(null, null, intent,
14323 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14324 null, false, false, MY_PID, SYSTEM_UID,
14326 intent = new Intent(Intent.ACTION_USER_STARTING);
14327 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14328 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14329 broadcastIntentLocked(null, null, intent,
14330 null, new IIntentReceiver.Stub() {
14332 public void performReceive(Intent intent, int resultCode, String data,
14333 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14334 throws RemoteException {
14337 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14338 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14339 } catch (Throwable t) {
14340 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14342 Binder.restoreCallingIdentity(ident);
14344 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14345 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14346 traceLog.traceEnd(); // ActivityManagerStartApps
14347 traceLog.traceEnd(); // PhaseActivityManagerReady
14351 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14352 synchronized (this) {
14353 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14357 void skipCurrentReceiverLocked(ProcessRecord app) {
14358 for (BroadcastQueue queue : mBroadcastQueues) {
14359 queue.skipCurrentReceiverLocked(app);
14364 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14365 * The application process will exit immediately after this call returns.
14366 * @param app object of the crashing app, null for the system server
14367 * @param crashInfo describing the exception
14369 public void handleApplicationCrash(IBinder app,
14370 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14371 ProcessRecord r = findAppProcess(app, "Crash");
14372 final String processName = app == null ? "system_server"
14373 : (r == null ? "unknown" : r.processName);
14375 handleApplicationCrashInner("crash", r, processName, crashInfo);
14378 /* Native crash reporting uses this inner version because it needs to be somewhat
14379 * decoupled from the AM-managed cleanup lifecycle
14381 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14382 ApplicationErrorReport.CrashInfo crashInfo) {
14383 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14384 UserHandle.getUserId(Binder.getCallingUid()), processName,
14385 r == null ? -1 : r.info.flags,
14386 crashInfo.exceptionClassName,
14387 crashInfo.exceptionMessage,
14388 crashInfo.throwFileName,
14389 crashInfo.throwLineNumber);
14391 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14393 mAppErrors.crashApplication(r, crashInfo);
14396 public void handleApplicationStrictModeViolation(
14399 StrictMode.ViolationInfo info) {
14400 ProcessRecord r = findAppProcess(app, "StrictMode");
14405 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14406 Integer stackFingerprint = info.hashCode();
14407 boolean logIt = true;
14408 synchronized (mAlreadyLoggedViolatedStacks) {
14409 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14411 // TODO: sub-sample into EventLog for these, with
14412 // the info.durationMillis? Then we'd get
14413 // the relative pain numbers, without logging all
14414 // the stack traces repeatedly. We'd want to do
14415 // likewise in the client code, which also does
14416 // dup suppression, before the Binder call.
14418 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14419 mAlreadyLoggedViolatedStacks.clear();
14421 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14425 logStrictModeViolationToDropBox(r, info);
14429 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14430 AppErrorResult result = new AppErrorResult();
14431 synchronized (this) {
14432 final long origId = Binder.clearCallingIdentity();
14434 Message msg = Message.obtain();
14435 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14436 HashMap<String, Object> data = new HashMap<String, Object>();
14437 data.put("result", result);
14438 data.put("app", r);
14439 data.put("violationMask", violationMask);
14440 data.put("info", info);
14442 mUiHandler.sendMessage(msg);
14444 Binder.restoreCallingIdentity(origId);
14446 int res = result.get();
14447 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14451 // Depending on the policy in effect, there could be a bunch of
14452 // these in quick succession so we try to batch these together to
14453 // minimize disk writes, number of dropbox entries, and maximize
14454 // compression, by having more fewer, larger records.
14455 private void logStrictModeViolationToDropBox(
14456 ProcessRecord process,
14457 StrictMode.ViolationInfo info) {
14458 if (info == null) {
14461 final boolean isSystemApp = process == null ||
14462 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14463 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14464 final String processName = process == null ? "unknown" : process.processName;
14465 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14466 final DropBoxManager dbox = (DropBoxManager)
14467 mContext.getSystemService(Context.DROPBOX_SERVICE);
14469 // Exit early if the dropbox isn't configured to accept this report type.
14470 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14472 boolean bufferWasEmpty;
14473 boolean needsFlush;
14474 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14475 synchronized (sb) {
14476 bufferWasEmpty = sb.length() == 0;
14477 appendDropBoxProcessHeaders(process, processName, sb);
14478 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14479 sb.append("System-App: ").append(isSystemApp).append("\n");
14480 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14481 if (info.violationNumThisLoop != 0) {
14482 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14484 if (info.numAnimationsRunning != 0) {
14485 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14487 if (info.broadcastIntentAction != null) {
14488 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14490 if (info.durationMillis != -1) {
14491 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14493 if (info.numInstances != -1) {
14494 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14496 if (info.tags != null) {
14497 for (String tag : info.tags) {
14498 sb.append("Span-Tag: ").append(tag).append("\n");
14502 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14503 sb.append(info.crashInfo.stackTrace);
14506 if (info.message != null) {
14507 sb.append(info.message);
14511 // Only buffer up to ~64k. Various logging bits truncate
14513 needsFlush = (sb.length() > 64 * 1024);
14516 // Flush immediately if the buffer's grown too large, or this
14517 // is a non-system app. Non-system apps are isolated with a
14518 // different tag & policy and not batched.
14520 // Batching is useful during internal testing with
14521 // StrictMode settings turned up high. Without batching,
14522 // thousands of separate files could be created on boot.
14523 if (!isSystemApp || needsFlush) {
14524 new Thread("Error dump: " + dropboxTag) {
14526 public void run() {
14528 synchronized (sb) {
14529 report = sb.toString();
14530 sb.delete(0, sb.length());
14533 if (report.length() != 0) {
14534 dbox.addText(dropboxTag, report);
14541 // System app batching:
14542 if (!bufferWasEmpty) {
14543 // An existing dropbox-writing thread is outstanding, so
14544 // we don't need to start it up. The existing thread will
14545 // catch the buffer appends we just did.
14549 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14550 // (After this point, we shouldn't access AMS internal data structures.)
14551 new Thread("Error dump: " + dropboxTag) {
14553 public void run() {
14554 // 5 second sleep to let stacks arrive and be batched together
14556 Thread.sleep(5000); // 5 seconds
14557 } catch (InterruptedException e) {}
14559 String errorReport;
14560 synchronized (mStrictModeBuffer) {
14561 errorReport = mStrictModeBuffer.toString();
14562 if (errorReport.length() == 0) {
14565 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14566 mStrictModeBuffer.trimToSize();
14568 dbox.addText(dropboxTag, errorReport);
14574 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14575 * @param app object of the crashing app, null for the system server
14576 * @param tag reported by the caller
14577 * @param system whether this wtf is coming from the system
14578 * @param crashInfo describing the context of the error
14579 * @return true if the process should exit immediately (WTF is fatal)
14581 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14582 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14583 final int callingUid = Binder.getCallingUid();
14584 final int callingPid = Binder.getCallingPid();
14587 // If this is coming from the system, we could very well have low-level
14588 // system locks held, so we want to do this all asynchronously. And we
14589 // never want this to become fatal, so there is that too.
14590 mHandler.post(new Runnable() {
14591 @Override public void run() {
14592 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14598 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14601 final boolean isFatal = Build.IS_ENG || Settings.Global
14602 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14603 final boolean isSystem = (r == null) || r.persistent;
14605 if (isFatal && !isSystem) {
14606 mAppErrors.crashApplication(r, crashInfo);
14613 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14614 final ApplicationErrorReport.CrashInfo crashInfo) {
14615 final ProcessRecord r = findAppProcess(app, "WTF");
14616 final String processName = app == null ? "system_server"
14617 : (r == null ? "unknown" : r.processName);
14619 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14620 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14622 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14628 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14629 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14631 private ProcessRecord findAppProcess(IBinder app, String reason) {
14636 synchronized (this) {
14637 final int NP = mProcessNames.getMap().size();
14638 for (int ip=0; ip<NP; ip++) {
14639 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14640 final int NA = apps.size();
14641 for (int ia=0; ia<NA; ia++) {
14642 ProcessRecord p = apps.valueAt(ia);
14643 if (p.thread != null && p.thread.asBinder() == app) {
14649 Slog.w(TAG, "Can't find mystery application for " + reason
14650 + " from pid=" + Binder.getCallingPid()
14651 + " uid=" + Binder.getCallingUid() + ": " + app);
14657 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14658 * to append various headers to the dropbox log text.
14660 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14661 StringBuilder sb) {
14662 // Watchdog thread ends up invoking this function (with
14663 // a null ProcessRecord) to add the stack file to dropbox.
14664 // Do not acquire a lock on this (am) in such cases, as it
14665 // could cause a potential deadlock, if and when watchdog
14666 // is invoked due to unavailability of lock on am and it
14667 // would prevent watchdog from killing system_server.
14668 if (process == null) {
14669 sb.append("Process: ").append(processName).append("\n");
14672 // Note: ProcessRecord 'process' is guarded by the service
14673 // instance. (notably process.pkgList, which could otherwise change
14674 // concurrently during execution of this method)
14675 synchronized (this) {
14676 sb.append("Process: ").append(processName).append("\n");
14677 sb.append("PID: ").append(process.pid).append("\n");
14678 int flags = process.info.flags;
14679 IPackageManager pm = AppGlobals.getPackageManager();
14680 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14681 for (int ip=0; ip<process.pkgList.size(); ip++) {
14682 String pkg = process.pkgList.keyAt(ip);
14683 sb.append("Package: ").append(pkg);
14685 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14687 sb.append(" v").append(pi.versionCode);
14688 if (pi.versionName != null) {
14689 sb.append(" (").append(pi.versionName).append(")");
14692 } catch (RemoteException e) {
14693 Slog.e(TAG, "Error getting package info: " + pkg, e);
14697 if (process.info.isInstantApp()) {
14698 sb.append("Instant-App: true\n");
14703 private static String processClass(ProcessRecord process) {
14704 if (process == null || process.pid == MY_PID) {
14705 return "system_server";
14706 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14707 return "system_app";
14713 private volatile long mWtfClusterStart;
14714 private volatile int mWtfClusterCount;
14717 * Write a description of an error (crash, WTF, ANR) to the drop box.
14718 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14719 * @param process which caused the error, null means the system server
14720 * @param activity which triggered the error, null if unknown
14721 * @param parent activity related to the error, null if unknown
14722 * @param subject line related to the error, null if absent
14723 * @param report in long form describing the error, null if absent
14724 * @param dataFile text file to include in the report, null if none
14725 * @param crashInfo giving an application stack trace, null if absent
14727 public void addErrorToDropBox(String eventType,
14728 ProcessRecord process, String processName, ActivityRecord activity,
14729 ActivityRecord parent, String subject,
14730 final String report, final File dataFile,
14731 final ApplicationErrorReport.CrashInfo crashInfo) {
14732 // NOTE -- this must never acquire the ActivityManagerService lock,
14733 // otherwise the watchdog may be prevented from resetting the system.
14735 // Bail early if not published yet
14736 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14737 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14739 // Exit early if the dropbox isn't configured to accept this report type.
14740 final String dropboxTag = processClass(process) + "_" + eventType;
14741 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14743 // Rate-limit how often we're willing to do the heavy lifting below to
14744 // collect and record logs; currently 5 logs per 10 second period.
14745 final long now = SystemClock.elapsedRealtime();
14746 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14747 mWtfClusterStart = now;
14748 mWtfClusterCount = 1;
14750 if (mWtfClusterCount++ >= 5) return;
14753 final StringBuilder sb = new StringBuilder(1024);
14754 appendDropBoxProcessHeaders(process, processName, sb);
14755 if (process != null) {
14756 sb.append("Foreground: ")
14757 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14760 if (activity != null) {
14761 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14763 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14764 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14766 if (parent != null && parent != activity) {
14767 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14769 if (subject != null) {
14770 sb.append("Subject: ").append(subject).append("\n");
14772 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14773 if (Debug.isDebuggerConnected()) {
14774 sb.append("Debugger: Connected\n");
14778 // Do the rest in a worker thread to avoid blocking the caller on I/O
14779 // (After this point, we shouldn't access AMS internal data structures.)
14780 Thread worker = new Thread("Error dump: " + dropboxTag) {
14782 public void run() {
14783 if (report != null) {
14787 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14788 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14789 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14790 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14792 if (dataFile != null && maxDataFileSize > 0) {
14794 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14795 "\n\n[[TRUNCATED]]"));
14796 } catch (IOException e) {
14797 Slog.e(TAG, "Error reading " + dataFile, e);
14800 if (crashInfo != null && crashInfo.stackTrace != null) {
14801 sb.append(crashInfo.stackTrace);
14807 // Merge several logcat streams, and take the last N lines
14808 InputStreamReader input = null;
14810 java.lang.Process logcat = new ProcessBuilder(
14811 "/system/bin/timeout", "-k", "15s", "10s",
14812 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14813 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14814 .redirectErrorStream(true).start();
14816 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14817 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14818 input = new InputStreamReader(logcat.getInputStream());
14821 char[] buf = new char[8192];
14822 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14823 } catch (IOException e) {
14824 Slog.e(TAG, "Error running logcat", e);
14826 if (input != null) try { input.close(); } catch (IOException e) {}
14830 dbox.addText(dropboxTag, sb.toString());
14834 if (process == null) {
14835 // If process is null, we are being called from some internal code
14836 // and may be about to die -- run this synchronously.
14844 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14845 enforceNotIsolatedCaller("getProcessesInErrorState");
14846 // assume our apps are happy - lazy create the list
14847 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14849 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14850 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14851 int userId = UserHandle.getUserId(Binder.getCallingUid());
14853 synchronized (this) {
14855 // iterate across all processes
14856 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14857 ProcessRecord app = mLruProcesses.get(i);
14858 if (!allUsers && app.userId != userId) {
14861 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14862 // This one's in trouble, so we'll generate a report for it
14863 // crashes are higher priority (in case there's a crash *and* an anr)
14864 ActivityManager.ProcessErrorStateInfo report = null;
14865 if (app.crashing) {
14866 report = app.crashingReport;
14867 } else if (app.notResponding) {
14868 report = app.notRespondingReport;
14871 if (report != null) {
14872 if (errList == null) {
14873 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14875 errList.add(report);
14877 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14878 " crashing = " + app.crashing +
14879 " notResponding = " + app.notResponding);
14888 static int procStateToImportance(int procState, int memAdj,
14889 ActivityManager.RunningAppProcessInfo currApp,
14890 int clientTargetSdk) {
14891 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14892 procState, clientTargetSdk);
14893 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14894 currApp.lru = memAdj;
14901 private void fillInProcMemInfo(ProcessRecord app,
14902 ActivityManager.RunningAppProcessInfo outInfo,
14903 int clientTargetSdk) {
14904 outInfo.pid = app.pid;
14905 outInfo.uid = app.info.uid;
14906 if (mHeavyWeightProcess == app) {
14907 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14909 if (app.persistent) {
14910 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14912 if (app.activities.size() > 0) {
14913 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14915 outInfo.lastTrimLevel = app.trimMemoryLevel;
14916 int adj = app.curAdj;
14917 int procState = app.curProcState;
14918 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14919 outInfo.importanceReasonCode = app.adjTypeCode;
14920 outInfo.processState = app.curProcState;
14924 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14925 enforceNotIsolatedCaller("getRunningAppProcesses");
14927 final int callingUid = Binder.getCallingUid();
14928 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14930 // Lazy instantiation of list
14931 List<ActivityManager.RunningAppProcessInfo> runList = null;
14932 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14933 callingUid) == PackageManager.PERMISSION_GRANTED;
14934 final int userId = UserHandle.getUserId(callingUid);
14935 final boolean allUids = isGetTasksAllowed(
14936 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14938 synchronized (this) {
14939 // Iterate across all processes
14940 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14941 ProcessRecord app = mLruProcesses.get(i);
14942 if ((!allUsers && app.userId != userId)
14943 || (!allUids && app.uid != callingUid)) {
14946 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14947 // Generate process state info for running application
14948 ActivityManager.RunningAppProcessInfo currApp =
14949 new ActivityManager.RunningAppProcessInfo(app.processName,
14950 app.pid, app.getPackageList());
14951 fillInProcMemInfo(app, currApp, clientTargetSdk);
14952 if (app.adjSource instanceof ProcessRecord) {
14953 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14954 currApp.importanceReasonImportance =
14955 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14956 app.adjSourceProcState);
14957 } else if (app.adjSource instanceof ActivityRecord) {
14958 ActivityRecord r = (ActivityRecord)app.adjSource;
14959 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14961 if (app.adjTarget instanceof ComponentName) {
14962 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14964 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14965 // + " lru=" + currApp.lru);
14966 if (runList == null) {
14967 runList = new ArrayList<>();
14969 runList.add(currApp);
14977 public List<ApplicationInfo> getRunningExternalApplications() {
14978 enforceNotIsolatedCaller("getRunningExternalApplications");
14979 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14980 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14981 if (runningApps != null && runningApps.size() > 0) {
14982 Set<String> extList = new HashSet<String>();
14983 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14984 if (app.pkgList != null) {
14985 for (String pkg : app.pkgList) {
14990 IPackageManager pm = AppGlobals.getPackageManager();
14991 for (String pkg : extList) {
14993 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14994 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14997 } catch (RemoteException e) {
15005 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15006 enforceNotIsolatedCaller("getMyMemoryState");
15008 final int callingUid = Binder.getCallingUid();
15009 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15011 synchronized (this) {
15012 ProcessRecord proc;
15013 synchronized (mPidsSelfLocked) {
15014 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15016 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15021 public int getMemoryTrimLevel() {
15022 enforceNotIsolatedCaller("getMyMemoryState");
15023 synchronized (this) {
15024 return mLastMemoryLevel;
15029 public void onShellCommand(FileDescriptor in, FileDescriptor out,
15030 FileDescriptor err, String[] args, ShellCallback callback,
15031 ResultReceiver resultReceiver) {
15032 (new ActivityManagerShellCommand(this, false)).exec(
15033 this, in, out, err, args, callback, resultReceiver);
15036 SleepToken acquireSleepToken(String tag, int displayId) {
15037 synchronized (this) {
15038 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15039 updateSleepIfNeededLocked();
15045 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15046 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15048 boolean dumpAll = false;
15049 boolean dumpClient = false;
15050 boolean dumpCheckin = false;
15051 boolean dumpCheckinFormat = false;
15052 boolean dumpVisibleStacksOnly = false;
15053 boolean dumpFocusedStackOnly = false;
15054 String dumpPackage = null;
15057 while (opti < args.length) {
15058 String opt = args[opti];
15059 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15063 if ("-a".equals(opt)) {
15065 } else if ("-c".equals(opt)) {
15067 } else if ("-v".equals(opt)) {
15068 dumpVisibleStacksOnly = true;
15069 } else if ("-f".equals(opt)) {
15070 dumpFocusedStackOnly = true;
15071 } else if ("-p".equals(opt)) {
15072 if (opti < args.length) {
15073 dumpPackage = args[opti];
15076 pw.println("Error: -p option requires package argument");
15080 } else if ("--checkin".equals(opt)) {
15081 dumpCheckin = dumpCheckinFormat = true;
15082 } else if ("-C".equals(opt)) {
15083 dumpCheckinFormat = true;
15084 } else if ("-h".equals(opt)) {
15085 ActivityManagerShellCommand.dumpHelp(pw, true);
15088 pw.println("Unknown argument: " + opt + "; use -h for help");
15092 long origId = Binder.clearCallingIdentity();
15093 boolean more = false;
15094 // Is the caller requesting to dump a particular piece of data?
15095 if (opti < args.length) {
15096 String cmd = args[opti];
15098 if ("activities".equals(cmd) || "a".equals(cmd)) {
15099 synchronized (this) {
15100 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15102 } else if ("lastanr".equals(cmd)) {
15103 synchronized (this) {
15104 dumpLastANRLocked(pw);
15106 } else if ("starter".equals(cmd)) {
15107 synchronized (this) {
15108 dumpActivityStarterLocked(pw, dumpPackage);
15110 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15111 synchronized (this) {
15112 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15114 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15117 if (opti >= args.length) {
15119 newArgs = EMPTY_STRING_ARRAY;
15121 dumpPackage = args[opti];
15123 newArgs = new String[args.length - opti];
15124 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15125 args.length - opti);
15127 synchronized (this) {
15128 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15130 } else if ("broadcast-stats".equals(cmd)) {
15133 if (opti >= args.length) {
15135 newArgs = EMPTY_STRING_ARRAY;
15137 dumpPackage = args[opti];
15139 newArgs = new String[args.length - opti];
15140 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15141 args.length - opti);
15143 synchronized (this) {
15144 if (dumpCheckinFormat) {
15145 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15148 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15151 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15154 if (opti >= args.length) {
15156 newArgs = EMPTY_STRING_ARRAY;
15158 dumpPackage = args[opti];
15160 newArgs = new String[args.length - opti];
15161 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15162 args.length - opti);
15164 synchronized (this) {
15165 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15167 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15170 if (opti >= args.length) {
15172 newArgs = EMPTY_STRING_ARRAY;
15174 dumpPackage = args[opti];
15176 newArgs = new String[args.length - opti];
15177 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15178 args.length - opti);
15180 synchronized (this) {
15181 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15183 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15184 synchronized (this) {
15185 dumpOomLocked(fd, pw, args, opti, true);
15187 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15188 synchronized (this) {
15189 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15191 } else if ("provider".equals(cmd)) {
15194 if (opti >= args.length) {
15196 newArgs = EMPTY_STRING_ARRAY;
15200 newArgs = new String[args.length - opti];
15201 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15203 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15204 pw.println("No providers match: " + name);
15205 pw.println("Use -h for help.");
15207 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15208 synchronized (this) {
15209 dumpProvidersLocked(fd, pw, args, opti, true, null);
15211 } else if ("service".equals(cmd)) {
15214 if (opti >= args.length) {
15216 newArgs = EMPTY_STRING_ARRAY;
15220 newArgs = new String[args.length - opti];
15221 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15222 args.length - opti);
15224 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15225 pw.println("No services match: " + name);
15226 pw.println("Use -h for help.");
15228 } else if ("package".equals(cmd)) {
15230 if (opti >= args.length) {
15231 pw.println("package: no package name specified");
15232 pw.println("Use -h for help.");
15234 dumpPackage = args[opti];
15236 newArgs = new String[args.length - opti];
15237 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15238 args.length - opti);
15243 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15244 synchronized (this) {
15245 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15247 } else if ("settings".equals(cmd)) {
15248 synchronized (this) {
15249 mConstants.dump(pw);
15251 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15253 ActiveServices.ServiceDumper dumper;
15254 synchronized (this) {
15255 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15258 dumper.dumpWithClient();
15260 synchronized (this) {
15261 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15262 dumpPackage).dumpLocked();
15265 } else if ("locks".equals(cmd)) {
15266 LockGuard.dump(fd, pw, args);
15268 // Dumping a single activity?
15269 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15270 dumpFocusedStackOnly)) {
15271 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15272 int res = shell.exec(this, null, fd, null, args, null,
15273 new ResultReceiver(null));
15275 pw.println("Bad activity command, or no activities match: " + cmd);
15276 pw.println("Use -h for help.");
15281 Binder.restoreCallingIdentity(origId);
15286 // No piece of data specified, dump everything.
15287 if (dumpCheckinFormat) {
15288 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15289 } else if (dumpClient) {
15290 ActiveServices.ServiceDumper sdumper;
15291 synchronized (this) {
15292 mConstants.dump(pw);
15295 pw.println("-------------------------------------------------------------------------------");
15297 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15300 pw.println("-------------------------------------------------------------------------------");
15302 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15305 pw.println("-------------------------------------------------------------------------------");
15307 if (dumpAll || dumpPackage != null) {
15308 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15311 pw.println("-------------------------------------------------------------------------------");
15314 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15317 pw.println("-------------------------------------------------------------------------------");
15319 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15322 pw.println("-------------------------------------------------------------------------------");
15324 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15327 sdumper.dumpWithClient();
15329 synchronized (this) {
15331 pw.println("-------------------------------------------------------------------------------");
15333 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15336 pw.println("-------------------------------------------------------------------------------");
15338 dumpLastANRLocked(pw);
15341 pw.println("-------------------------------------------------------------------------------");
15343 dumpActivityStarterLocked(pw, dumpPackage);
15346 pw.println("-------------------------------------------------------------------------------");
15348 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15349 if (mAssociations.size() > 0) {
15352 pw.println("-------------------------------------------------------------------------------");
15354 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15358 pw.println("-------------------------------------------------------------------------------");
15360 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15364 synchronized (this) {
15365 mConstants.dump(pw);
15368 pw.println("-------------------------------------------------------------------------------");
15370 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15373 pw.println("-------------------------------------------------------------------------------");
15375 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15378 pw.println("-------------------------------------------------------------------------------");
15380 if (dumpAll || dumpPackage != null) {
15381 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15384 pw.println("-------------------------------------------------------------------------------");
15387 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15390 pw.println("-------------------------------------------------------------------------------");
15392 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15395 pw.println("-------------------------------------------------------------------------------");
15397 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15401 pw.println("-------------------------------------------------------------------------------");
15403 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15406 pw.println("-------------------------------------------------------------------------------");
15408 dumpLastANRLocked(pw);
15411 pw.println("-------------------------------------------------------------------------------");
15413 dumpActivityStarterLocked(pw, dumpPackage);
15416 pw.println("-------------------------------------------------------------------------------");
15418 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15419 if (mAssociations.size() > 0) {
15422 pw.println("-------------------------------------------------------------------------------");
15424 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15428 pw.println("-------------------------------------------------------------------------------");
15430 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15433 Binder.restoreCallingIdentity(origId);
15436 private void dumpLastANRLocked(PrintWriter pw) {
15437 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15438 if (mLastANRState == null) {
15439 pw.println(" <no ANR has occurred since boot>");
15441 pw.println(mLastANRState);
15445 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15446 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15447 mActivityStarter.dump(pw, "", dumpPackage);
15450 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15451 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15452 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15453 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15456 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15457 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15458 pw.println(header);
15460 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15462 boolean needSep = printedAnything;
15464 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15465 mStackSupervisor.getResumedActivityLocked(),
15466 dumpPackage, needSep, " ResumedActivity: ");
15468 printedAnything = true;
15472 if (dumpPackage == null) {
15476 printedAnything = true;
15477 mStackSupervisor.dump(pw, " ");
15480 if (!printedAnything) {
15481 pw.println(" (nothing)");
15485 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15486 int opti, boolean dumpAll, String dumpPackage) {
15487 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15489 boolean printedAnything = false;
15491 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15492 boolean printedHeader = false;
15494 final int N = mRecentTasks.size();
15495 for (int i=0; i<N; i++) {
15496 TaskRecord tr = mRecentTasks.get(i);
15497 if (dumpPackage != null) {
15498 if (tr.realActivity == null ||
15499 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15503 if (!printedHeader) {
15504 pw.println(" Recent tasks:");
15505 printedHeader = true;
15506 printedAnything = true;
15508 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15511 mRecentTasks.get(i).dump(pw, " ");
15516 if (!printedAnything) {
15517 pw.println(" (nothing)");
15521 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15522 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15523 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15526 if (dumpPackage != null) {
15527 IPackageManager pm = AppGlobals.getPackageManager();
15529 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15530 } catch (RemoteException e) {
15534 boolean printedAnything = false;
15536 final long now = SystemClock.uptimeMillis();
15538 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15539 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15540 = mAssociations.valueAt(i1);
15541 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15542 SparseArray<ArrayMap<String, Association>> sourceUids
15543 = targetComponents.valueAt(i2);
15544 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15545 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15546 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15547 Association ass = sourceProcesses.valueAt(i4);
15548 if (dumpPackage != null) {
15549 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15550 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15554 printedAnything = true;
15556 pw.print(ass.mTargetProcess);
15558 UserHandle.formatUid(pw, ass.mTargetUid);
15560 pw.print(ass.mSourceProcess);
15562 UserHandle.formatUid(pw, ass.mSourceUid);
15565 pw.print(ass.mTargetComponent.flattenToShortString());
15568 long dur = ass.mTime;
15569 if (ass.mNesting > 0) {
15570 dur += now - ass.mStartTime;
15572 TimeUtils.formatDuration(dur, pw);
15574 pw.print(ass.mCount);
15575 pw.print(" times)");
15577 for (int i=0; i<ass.mStateTimes.length; i++) {
15578 long amt = ass.mStateTimes[i];
15579 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15580 amt += now - ass.mLastStateUptime;
15584 pw.print(ProcessList.makeProcStateString(
15585 i + ActivityManager.MIN_PROCESS_STATE));
15587 TimeUtils.formatDuration(amt, pw);
15588 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15594 if (ass.mNesting > 0) {
15595 pw.print(" Currently active: ");
15596 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15605 if (!printedAnything) {
15606 pw.println(" (nothing)");
15610 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15611 String header, boolean needSep) {
15612 boolean printed = false;
15613 int whichAppId = -1;
15614 if (dumpPackage != null) {
15616 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15618 whichAppId = UserHandle.getAppId(info.uid);
15619 } catch (NameNotFoundException e) {
15620 e.printStackTrace();
15623 for (int i=0; i<uids.size(); i++) {
15624 UidRecord uidRec = uids.valueAt(i);
15625 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15634 pw.println(header);
15637 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15638 pw.print(": "); pw.println(uidRec);
15643 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15644 int opti, boolean dumpAll, String dumpPackage) {
15645 boolean needSep = false;
15646 boolean printedAnything = false;
15649 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15652 final int NP = mProcessNames.getMap().size();
15653 for (int ip=0; ip<NP; ip++) {
15654 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15655 final int NA = procs.size();
15656 for (int ia=0; ia<NA; ia++) {
15657 ProcessRecord r = procs.valueAt(ia);
15658 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15662 pw.println(" All known processes:");
15664 printedAnything = true;
15666 pw.print(r.persistent ? " *PERS*" : " *APP*");
15667 pw.print(" UID "); pw.print(procs.keyAt(ia));
15668 pw.print(" "); pw.println(r);
15670 if (r.persistent) {
15677 if (mIsolatedProcesses.size() > 0) {
15678 boolean printed = false;
15679 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15680 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15681 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15688 pw.println(" Isolated process list (sorted by uid):");
15689 printedAnything = true;
15693 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15698 if (mActiveInstrumentation.size() > 0) {
15699 boolean printed = false;
15700 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15701 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15702 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15703 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15710 pw.println(" Active instrumentation:");
15711 printedAnything = true;
15715 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15721 if (mActiveUids.size() > 0) {
15722 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15723 printedAnything = needSep = true;
15727 if (mValidateUids.size() > 0) {
15728 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15729 printedAnything = needSep = true;
15734 if (mLruProcesses.size() > 0) {
15738 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15739 pw.print(" total, non-act at ");
15740 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15741 pw.print(", non-svc at ");
15742 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15744 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15746 printedAnything = true;
15749 if (dumpAll || dumpPackage != null) {
15750 synchronized (mPidsSelfLocked) {
15751 boolean printed = false;
15752 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15753 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15754 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15758 if (needSep) pw.println();
15760 pw.println(" PID mappings:");
15762 printedAnything = true;
15764 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15765 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15770 if (mImportantProcesses.size() > 0) {
15771 synchronized (mPidsSelfLocked) {
15772 boolean printed = false;
15773 for (int i = 0; i< mImportantProcesses.size(); i++) {
15774 ProcessRecord r = mPidsSelfLocked.get(
15775 mImportantProcesses.valueAt(i).pid);
15776 if (dumpPackage != null && (r == null
15777 || !r.pkgList.containsKey(dumpPackage))) {
15781 if (needSep) pw.println();
15783 pw.println(" Foreground Processes:");
15785 printedAnything = true;
15787 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15788 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15793 if (mPersistentStartingProcesses.size() > 0) {
15794 if (needSep) pw.println();
15796 printedAnything = true;
15797 pw.println(" Persisent processes that are starting:");
15798 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15799 "Starting Norm", "Restarting PERS", dumpPackage);
15802 if (mRemovedProcesses.size() > 0) {
15803 if (needSep) pw.println();
15805 printedAnything = true;
15806 pw.println(" Processes that are being removed:");
15807 dumpProcessList(pw, this, mRemovedProcesses, " ",
15808 "Removed Norm", "Removed PERS", dumpPackage);
15811 if (mProcessesOnHold.size() > 0) {
15812 if (needSep) pw.println();
15814 printedAnything = true;
15815 pw.println(" Processes that are on old until the system is ready:");
15816 dumpProcessList(pw, this, mProcessesOnHold, " ",
15817 "OnHold Norm", "OnHold PERS", dumpPackage);
15820 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15822 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15824 printedAnything = true;
15827 if (dumpPackage == null) {
15830 mUserController.dump(pw, dumpAll);
15832 if (mHomeProcess != null && (dumpPackage == null
15833 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15838 pw.println(" mHomeProcess: " + mHomeProcess);
15840 if (mPreviousProcess != null && (dumpPackage == null
15841 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15846 pw.println(" mPreviousProcess: " + mPreviousProcess);
15849 StringBuilder sb = new StringBuilder(128);
15850 sb.append(" mPreviousProcessVisibleTime: ");
15851 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15854 if (mHeavyWeightProcess != null && (dumpPackage == null
15855 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15860 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15862 if (dumpPackage == null) {
15863 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15864 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15867 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15868 if (mCompatModePackages.getPackages().size() > 0) {
15869 boolean printed = false;
15870 for (Map.Entry<String, Integer> entry
15871 : mCompatModePackages.getPackages().entrySet()) {
15872 String pkg = entry.getKey();
15873 int mode = entry.getValue();
15874 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15878 pw.println(" mScreenCompatPackages:");
15881 pw.print(" "); pw.print(pkg); pw.print(": ");
15882 pw.print(mode); pw.println();
15885 final int NI = mUidObservers.getRegisteredCallbackCount();
15886 boolean printed = false;
15887 for (int i=0; i<NI; i++) {
15888 final UidObserverRegistration reg = (UidObserverRegistration)
15889 mUidObservers.getRegisteredCallbackCookie(i);
15890 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15892 pw.println(" mUidObservers:");
15895 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15896 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15897 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15900 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15903 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15906 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15907 pw.print(" STATE");
15908 pw.print(" (cut="); pw.print(reg.cutpoint);
15912 if (reg.lastProcStates != null) {
15913 final int NJ = reg.lastProcStates.size();
15914 for (int j=0; j<NJ; j++) {
15915 pw.print(" Last ");
15916 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15917 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15922 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15923 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15924 if (mPendingTempWhitelist.size() > 0) {
15925 pw.println(" mPendingTempWhitelist:");
15926 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15927 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15929 UserHandle.formatUid(pw, ptw.targetUid);
15931 TimeUtils.formatDuration(ptw.duration, pw);
15933 pw.println(ptw.tag);
15937 if (dumpPackage == null) {
15938 pw.println(" mWakefulness="
15939 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15940 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
15941 pw.println(" mSleeping=" + mSleeping);
15942 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15943 if (mRunningVoice != null) {
15944 pw.println(" mRunningVoice=" + mRunningVoice);
15945 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15948 pw.println(" mVrController=" + mVrController);
15949 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15950 || mOrigWaitForDebugger) {
15951 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15952 || dumpPackage.equals(mOrigDebugApp)) {
15957 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15958 + " mDebugTransient=" + mDebugTransient
15959 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15962 if (mCurAppTimeTracker != null) {
15963 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15965 if (mMemWatchProcesses.getMap().size() > 0) {
15966 pw.println(" Mem watch processes:");
15967 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15968 = mMemWatchProcesses.getMap();
15969 for (int i=0; i<procs.size(); i++) {
15970 final String proc = procs.keyAt(i);
15971 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15972 for (int j=0; j<uids.size(); j++) {
15977 StringBuilder sb = new StringBuilder();
15978 sb.append(" ").append(proc).append('/');
15979 UserHandle.formatUid(sb, uids.keyAt(j));
15980 Pair<Long, String> val = uids.valueAt(j);
15981 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15982 if (val.second != null) {
15983 sb.append(", report to ").append(val.second);
15985 pw.println(sb.toString());
15988 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15989 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15990 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15991 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15993 if (mTrackAllocationApp != null) {
15994 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15999 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
16002 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16003 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16004 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16009 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16010 if (mProfilerInfo != null) {
16011 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16012 mProfilerInfo.profileFd);
16013 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
16014 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16015 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16016 pw.println(" mProfileType=" + mProfileType);
16020 if (mNativeDebuggingApp != null) {
16021 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16026 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
16029 if (dumpPackage == null) {
16030 if (mAlwaysFinishActivities) {
16031 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16033 if (mController != null) {
16034 pw.println(" mController=" + mController
16035 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16038 pw.println(" Total persistent processes: " + numPers);
16039 pw.println(" mProcessesReady=" + mProcessesReady
16040 + " mSystemReady=" + mSystemReady
16041 + " mBooted=" + mBooted
16042 + " mFactoryTest=" + mFactoryTest);
16043 pw.println(" mBooting=" + mBooting
16044 + " mCallFinishBooting=" + mCallFinishBooting
16045 + " mBootAnimationComplete=" + mBootAnimationComplete);
16046 pw.print(" mLastPowerCheckUptime=");
16047 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16049 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16050 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16051 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16052 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
16053 + " (" + mLruProcesses.size() + " total)"
16054 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16055 + " mNumServiceProcs=" + mNumServiceProcs
16056 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16057 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
16058 + " mLastMemoryLevel=" + mLastMemoryLevel
16059 + " mLastNumProcesses=" + mLastNumProcesses);
16060 long now = SystemClock.uptimeMillis();
16061 pw.print(" mLastIdleTime=");
16062 TimeUtils.formatDuration(now, mLastIdleTime, pw);
16063 pw.print(" mLowRamSinceLastIdle=");
16064 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16069 if (!printedAnything) {
16070 pw.println(" (nothing)");
16074 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16075 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16076 if (mProcessesToGc.size() > 0) {
16077 boolean printed = false;
16078 long now = SystemClock.uptimeMillis();
16079 for (int i=0; i<mProcessesToGc.size(); i++) {
16080 ProcessRecord proc = mProcessesToGc.get(i);
16081 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16085 if (needSep) pw.println();
16087 pw.println(" Processes that are waiting to GC:");
16090 pw.print(" Process "); pw.println(proc);
16091 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16092 pw.print(", last gced=");
16093 pw.print(now-proc.lastRequestedGc);
16094 pw.print(" ms ago, last lowMem=");
16095 pw.print(now-proc.lastLowMemory);
16096 pw.println(" ms ago");
16103 void printOomLevel(PrintWriter pw, String name, int adj) {
16107 if (adj < 10) pw.print(' ');
16109 if (adj > -10) pw.print(' ');
16115 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16119 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16120 int opti, boolean dumpAll) {
16121 boolean needSep = false;
16123 if (mLruProcesses.size() > 0) {
16124 if (needSep) pw.println();
16126 pw.println(" OOM levels:");
16127 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16128 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16129 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16130 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16131 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16132 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16133 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16134 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16135 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16136 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16137 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16138 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16139 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16140 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16142 if (needSep) pw.println();
16143 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16144 pw.print(" total, non-act at ");
16145 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16146 pw.print(", non-svc at ");
16147 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16149 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16153 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16156 pw.println(" mHomeProcess: " + mHomeProcess);
16157 pw.println(" mPreviousProcess: " + mPreviousProcess);
16158 if (mHeavyWeightProcess != null) {
16159 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16166 * There are three ways to call this:
16167 * - no provider specified: dump all the providers
16168 * - a flattened component name that matched an existing provider was specified as the
16169 * first arg: dump that one provider
16170 * - the first arg isn't the flattened component name of an existing provider:
16171 * dump all providers whose component contains the first arg as a substring
16173 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16174 int opti, boolean dumpAll) {
16175 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16178 static class ItemMatcher {
16179 ArrayList<ComponentName> components;
16180 ArrayList<String> strings;
16181 ArrayList<Integer> objects;
16188 void build(String name) {
16189 ComponentName componentName = ComponentName.unflattenFromString(name);
16190 if (componentName != null) {
16191 if (components == null) {
16192 components = new ArrayList<ComponentName>();
16194 components.add(componentName);
16198 // Not a '/' separated full component name; maybe an object ID?
16200 objectId = Integer.parseInt(name, 16);
16201 if (objects == null) {
16202 objects = new ArrayList<Integer>();
16204 objects.add(objectId);
16206 } catch (RuntimeException e) {
16207 // Not an integer; just do string match.
16208 if (strings == null) {
16209 strings = new ArrayList<String>();
16217 int build(String[] args, int opti) {
16218 for (; opti<args.length; opti++) {
16219 String name = args[opti];
16220 if ("--".equals(name)) {
16228 boolean match(Object object, ComponentName comp) {
16232 if (components != null) {
16233 for (int i=0; i<components.size(); i++) {
16234 if (components.get(i).equals(comp)) {
16239 if (objects != null) {
16240 for (int i=0; i<objects.size(); i++) {
16241 if (System.identityHashCode(object) == objects.get(i)) {
16246 if (strings != null) {
16247 String flat = comp.flattenToString();
16248 for (int i=0; i<strings.size(); i++) {
16249 if (flat.contains(strings.get(i))) {
16259 * There are three things that cmd can be:
16260 * - a flattened component name that matches an existing activity
16261 * - the cmd arg isn't the flattened component name of an existing activity:
16262 * dump all activity whose component contains the cmd as a substring
16263 * - A hex number of the ActivityRecord object instance.
16265 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16266 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16268 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16269 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16270 ArrayList<ActivityRecord> activities;
16272 synchronized (this) {
16273 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16274 dumpFocusedStackOnly);
16277 if (activities.size() <= 0) {
16281 String[] newArgs = new String[args.length - opti];
16282 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16284 TaskRecord lastTask = null;
16285 boolean needSep = false;
16286 for (int i=activities.size()-1; i>=0; i--) {
16287 ActivityRecord r = activities.get(i);
16292 synchronized (this) {
16293 final TaskRecord task = r.getTask();
16294 if (lastTask != task) {
16296 pw.print("TASK "); pw.print(lastTask.affinity);
16297 pw.print(" id="); pw.print(lastTask.taskId);
16298 pw.print(" userId="); pw.println(lastTask.userId);
16300 lastTask.dump(pw, " ");
16304 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16310 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16311 * there is a thread associated with the activity.
16313 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16314 final ActivityRecord r, String[] args, boolean dumpAll) {
16315 String innerPrefix = prefix + " ";
16316 synchronized (this) {
16317 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16318 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16320 if (r.app != null) pw.println(r.app.pid);
16321 else pw.println("(not running)");
16323 r.dump(pw, innerPrefix);
16326 if (r.app != null && r.app.thread != null) {
16327 // flush anything that is already in the PrintWriter since the thread is going
16328 // to write to the file descriptor directly
16331 TransferPipe tp = new TransferPipe();
16333 r.app.thread.dumpActivity(tp.getWriteFd(),
16334 r.appToken, innerPrefix, args);
16339 } catch (IOException e) {
16340 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16341 } catch (RemoteException e) {
16342 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16347 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16348 int opti, boolean dumpAll, String dumpPackage) {
16349 boolean needSep = false;
16350 boolean onlyHistory = false;
16351 boolean printedAnything = false;
16353 if ("history".equals(dumpPackage)) {
16354 if (opti < args.length && "-s".equals(args[opti])) {
16357 onlyHistory = true;
16358 dumpPackage = null;
16361 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16362 if (!onlyHistory && dumpAll) {
16363 if (mRegisteredReceivers.size() > 0) {
16364 boolean printed = false;
16365 Iterator it = mRegisteredReceivers.values().iterator();
16366 while (it.hasNext()) {
16367 ReceiverList r = (ReceiverList)it.next();
16368 if (dumpPackage != null && (r.app == null ||
16369 !dumpPackage.equals(r.app.info.packageName))) {
16373 pw.println(" Registered Receivers:");
16376 printedAnything = true;
16378 pw.print(" * "); pw.println(r);
16383 if (mReceiverResolver.dump(pw, needSep ?
16384 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16385 " ", dumpPackage, false, false)) {
16387 printedAnything = true;
16391 for (BroadcastQueue q : mBroadcastQueues) {
16392 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16393 printedAnything |= needSep;
16398 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16399 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16404 printedAnything = true;
16405 pw.print(" Sticky broadcasts for user ");
16406 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16407 StringBuilder sb = new StringBuilder(128);
16408 for (Map.Entry<String, ArrayList<Intent>> ent
16409 : mStickyBroadcasts.valueAt(user).entrySet()) {
16410 pw.print(" * Sticky action "); pw.print(ent.getKey());
16413 ArrayList<Intent> intents = ent.getValue();
16414 final int N = intents.size();
16415 for (int i=0; i<N; i++) {
16417 sb.append(" Intent: ");
16418 intents.get(i).toShortString(sb, false, true, false, false);
16419 pw.println(sb.toString());
16420 Bundle bundle = intents.get(i).getExtras();
16421 if (bundle != null) {
16423 pw.println(bundle.toString());
16433 if (!onlyHistory && dumpAll) {
16435 for (BroadcastQueue queue : mBroadcastQueues) {
16436 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16437 + queue.mBroadcastsScheduled);
16439 pw.println(" mHandler:");
16440 mHandler.dump(new PrintWriterPrinter(pw), " ");
16442 printedAnything = true;
16445 if (!printedAnything) {
16446 pw.println(" (nothing)");
16450 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16451 int opti, boolean dumpAll, String dumpPackage) {
16452 if (mCurBroadcastStats == null) {
16456 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16457 final long now = SystemClock.elapsedRealtime();
16458 if (mLastBroadcastStats != null) {
16459 pw.print(" Last stats (from ");
16460 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16462 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16464 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16465 - mLastBroadcastStats.mStartUptime, pw);
16466 pw.println(" uptime):");
16467 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16468 pw.println(" (nothing)");
16472 pw.print(" Current stats (from ");
16473 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16474 pw.print(" to now, ");
16475 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16476 - mCurBroadcastStats.mStartUptime, pw);
16477 pw.println(" uptime):");
16478 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16479 pw.println(" (nothing)");
16483 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16484 int opti, boolean fullCheckin, String dumpPackage) {
16485 if (mCurBroadcastStats == null) {
16489 if (mLastBroadcastStats != null) {
16490 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16492 mLastBroadcastStats = null;
16496 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16498 mCurBroadcastStats = null;
16502 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16503 int opti, boolean dumpAll, String dumpPackage) {
16505 boolean printedAnything = false;
16507 ItemMatcher matcher = new ItemMatcher();
16508 matcher.build(args, opti);
16510 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16512 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16513 printedAnything |= needSep;
16515 if (mLaunchingProviders.size() > 0) {
16516 boolean printed = false;
16517 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16518 ContentProviderRecord r = mLaunchingProviders.get(i);
16519 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16523 if (needSep) pw.println();
16525 pw.println(" Launching content providers:");
16527 printedAnything = true;
16529 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16534 if (!printedAnything) {
16535 pw.println(" (nothing)");
16539 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16540 int opti, boolean dumpAll, String dumpPackage) {
16541 boolean needSep = false;
16542 boolean printedAnything = false;
16544 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16546 if (mGrantedUriPermissions.size() > 0) {
16547 boolean printed = false;
16549 if (dumpPackage != null) {
16551 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16552 MATCH_ANY_USER, 0);
16553 } catch (NameNotFoundException e) {
16557 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16558 int uid = mGrantedUriPermissions.keyAt(i);
16559 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16562 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16564 if (needSep) pw.println();
16566 pw.println(" Granted Uri Permissions:");
16568 printedAnything = true;
16570 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16571 for (UriPermission perm : perms.values()) {
16572 pw.print(" "); pw.println(perm);
16574 perm.dump(pw, " ");
16580 if (!printedAnything) {
16581 pw.println(" (nothing)");
16585 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16586 int opti, boolean dumpAll, String dumpPackage) {
16587 boolean printed = false;
16589 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16591 if (mIntentSenderRecords.size() > 0) {
16592 // Organize these by package name, so they are easier to read.
16593 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16594 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16595 final Iterator<WeakReference<PendingIntentRecord>> it
16596 = mIntentSenderRecords.values().iterator();
16597 while (it.hasNext()) {
16598 WeakReference<PendingIntentRecord> ref = it.next();
16599 PendingIntentRecord rec = ref != null ? ref.get() : null;
16604 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16607 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16608 if (list == null) {
16609 list = new ArrayList<>();
16610 byPackage.put(rec.key.packageName, list);
16614 for (int i = 0; i < byPackage.size(); i++) {
16615 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16617 pw.print(" * "); pw.print(byPackage.keyAt(i));
16618 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16619 for (int j = 0; j < intents.size(); j++) {
16620 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16622 intents.get(j).dump(pw, " ");
16626 if (weakRefs.size() > 0) {
16628 pw.println(" * WEAK REFS:");
16629 for (int i = 0; i < weakRefs.size(); i++) {
16630 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16636 pw.println(" (nothing)");
16640 private static final int dumpProcessList(PrintWriter pw,
16641 ActivityManagerService service, List list,
16642 String prefix, String normalLabel, String persistentLabel,
16643 String dumpPackage) {
16645 final int N = list.size()-1;
16646 for (int i=N; i>=0; i--) {
16647 ProcessRecord r = (ProcessRecord)list.get(i);
16648 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16651 pw.println(String.format("%s%s #%2d: %s",
16652 prefix, (r.persistent ? persistentLabel : normalLabel),
16654 if (r.persistent) {
16661 private static final boolean dumpProcessOomList(PrintWriter pw,
16662 ActivityManagerService service, List<ProcessRecord> origList,
16663 String prefix, String normalLabel, String persistentLabel,
16664 boolean inclDetails, String dumpPackage) {
16666 ArrayList<Pair<ProcessRecord, Integer>> list
16667 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16668 for (int i=0; i<origList.size(); i++) {
16669 ProcessRecord r = origList.get(i);
16670 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16673 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16676 if (list.size() <= 0) {
16680 Comparator<Pair<ProcessRecord, Integer>> comparator
16681 = new Comparator<Pair<ProcessRecord, Integer>>() {
16683 public int compare(Pair<ProcessRecord, Integer> object1,
16684 Pair<ProcessRecord, Integer> object2) {
16685 if (object1.first.setAdj != object2.first.setAdj) {
16686 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16688 if (object1.first.setProcState != object2.first.setProcState) {
16689 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16691 if (object1.second.intValue() != object2.second.intValue()) {
16692 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16698 Collections.sort(list, comparator);
16700 final long curUptime = SystemClock.uptimeMillis();
16701 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16703 for (int i=list.size()-1; i>=0; i--) {
16704 ProcessRecord r = list.get(i).first;
16705 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16707 switch (r.setSchedGroup) {
16708 case ProcessList.SCHED_GROUP_BACKGROUND:
16711 case ProcessList.SCHED_GROUP_DEFAULT:
16714 case ProcessList.SCHED_GROUP_TOP_APP:
16722 if (r.foregroundActivities) {
16724 } else if (r.foregroundServices) {
16729 String procState = ProcessList.makeProcStateString(r.curProcState);
16731 pw.print(r.persistent ? persistentLabel : normalLabel);
16733 int num = (origList.size()-1)-list.get(i).second;
16734 if (num < 10) pw.print(' ');
16739 pw.print(schedGroup);
16741 pw.print(foreground);
16743 pw.print(procState);
16745 if (r.trimMemoryLevel < 10) pw.print(' ');
16746 pw.print(r.trimMemoryLevel);
16748 pw.print(r.toShortString());
16750 pw.print(r.adjType);
16752 if (r.adjSource != null || r.adjTarget != null) {
16755 if (r.adjTarget instanceof ComponentName) {
16756 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16757 } else if (r.adjTarget != null) {
16758 pw.print(r.adjTarget.toString());
16760 pw.print("{null}");
16763 if (r.adjSource instanceof ProcessRecord) {
16765 pw.print(((ProcessRecord)r.adjSource).toShortString());
16767 } else if (r.adjSource != null) {
16768 pw.println(r.adjSource.toString());
16770 pw.println("{null}");
16776 pw.print("oom: max="); pw.print(r.maxAdj);
16777 pw.print(" curRaw="); pw.print(r.curRawAdj);
16778 pw.print(" setRaw="); pw.print(r.setRawAdj);
16779 pw.print(" cur="); pw.print(r.curAdj);
16780 pw.print(" set="); pw.println(r.setAdj);
16783 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16784 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16785 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16786 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16787 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16791 pw.print("cached="); pw.print(r.cached);
16792 pw.print(" empty="); pw.print(r.empty);
16793 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16795 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16796 if (r.lastCpuTime != 0) {
16797 long timeUsed = r.curCpuTime - r.lastCpuTime;
16800 pw.print("run cpu over ");
16801 TimeUtils.formatDuration(uptimeSince, pw);
16802 pw.print(" used ");
16803 TimeUtils.formatDuration(timeUsed, pw);
16805 pw.print((timeUsed*100)/uptimeSince);
16814 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16816 ArrayList<ProcessRecord> procs;
16817 synchronized (this) {
16818 if (args != null && args.length > start
16819 && args[start].charAt(0) != '-') {
16820 procs = new ArrayList<ProcessRecord>();
16823 pid = Integer.parseInt(args[start]);
16824 } catch (NumberFormatException e) {
16826 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16827 ProcessRecord proc = mLruProcesses.get(i);
16828 if (proc.pid == pid) {
16830 } else if (allPkgs && proc.pkgList != null
16831 && proc.pkgList.containsKey(args[start])) {
16833 } else if (proc.processName.equals(args[start])) {
16837 if (procs.size() <= 0) {
16841 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16847 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16848 PrintWriter pw, String[] args) {
16849 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16850 if (procs == null) {
16851 pw.println("No process found for: " + args[0]);
16855 long uptime = SystemClock.uptimeMillis();
16856 long realtime = SystemClock.elapsedRealtime();
16857 pw.println("Applications Graphics Acceleration Info:");
16858 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16860 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16861 ProcessRecord r = procs.get(i);
16862 if (r.thread != null) {
16863 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16866 TransferPipe tp = new TransferPipe();
16868 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16873 } catch (IOException e) {
16874 pw.println("Failure while dumping the app: " + r);
16876 } catch (RemoteException e) {
16877 pw.println("Got a RemoteException while dumping the app " + r);
16884 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16885 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16886 if (procs == null) {
16887 pw.println("No process found for: " + args[0]);
16891 pw.println("Applications Database Info:");
16893 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16894 ProcessRecord r = procs.get(i);
16895 if (r.thread != null) {
16896 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16899 TransferPipe tp = new TransferPipe();
16901 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16906 } catch (IOException e) {
16907 pw.println("Failure while dumping the app: " + r);
16909 } catch (RemoteException e) {
16910 pw.println("Got a RemoteException while dumping the app " + r);
16917 final static class MemItem {
16918 final boolean isProc;
16919 final String label;
16920 final String shortLabel;
16922 final long swapPss;
16924 final boolean hasActivities;
16925 ArrayList<MemItem> subitems;
16927 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16928 boolean _hasActivities) {
16931 shortLabel = _shortLabel;
16933 swapPss = _swapPss;
16935 hasActivities = _hasActivities;
16938 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16941 shortLabel = _shortLabel;
16943 swapPss = _swapPss;
16945 hasActivities = false;
16949 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16950 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16951 if (sort && !isCompact) {
16952 Collections.sort(items, new Comparator<MemItem>() {
16954 public int compare(MemItem lhs, MemItem rhs) {
16955 if (lhs.pss < rhs.pss) {
16957 } else if (lhs.pss > rhs.pss) {
16965 for (int i=0; i<items.size(); i++) {
16966 MemItem mi = items.get(i);
16969 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16970 mi.label, stringifyKBSize(mi.swapPss));
16972 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16974 } else if (mi.isProc) {
16975 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16976 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16977 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16978 pw.println(mi.hasActivities ? ",a" : ",e");
16980 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16981 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16983 if (mi.subitems != null) {
16984 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16985 true, isCompact, dumpSwapPss);
16990 // These are in KB.
16991 static final long[] DUMP_MEM_BUCKETS = new long[] {
16992 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16993 120*1024, 160*1024, 200*1024,
16994 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16995 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16998 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16999 boolean stackLike) {
17000 int start = label.lastIndexOf('.');
17001 if (start >= 0) start++;
17003 int end = label.length();
17004 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
17005 if (DUMP_MEM_BUCKETS[i] >= memKB) {
17006 long bucket = DUMP_MEM_BUCKETS[i]/1024;
17007 out.append(bucket);
17008 out.append(stackLike ? "MB." : "MB ");
17009 out.append(label, start, end);
17013 out.append(memKB/1024);
17014 out.append(stackLike ? "MB." : "MB ");
17015 out.append(label, start, end);
17018 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17019 ProcessList.NATIVE_ADJ,
17020 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17021 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17022 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17023 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17024 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17025 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17027 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17029 "System", "Persistent", "Persistent Service", "Foreground",
17030 "Visible", "Perceptible",
17031 "Heavy Weight", "Backup",
17032 "A Services", "Home",
17033 "Previous", "B Services", "Cached"
17035 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17037 "sys", "pers", "persvc", "fore",
17040 "servicea", "home",
17041 "prev", "serviceb", "cached"
17044 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17045 long realtime, boolean isCheckinRequest, boolean isCompact) {
17047 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17049 if (isCheckinRequest || isCompact) {
17050 // short checkin version
17051 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17053 pw.println("Applications Memory Usage (in Kilobytes):");
17054 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17058 private static final int KSM_SHARED = 0;
17059 private static final int KSM_SHARING = 1;
17060 private static final int KSM_UNSHARED = 2;
17061 private static final int KSM_VOLATILE = 3;
17063 private final long[] getKsmInfo() {
17064 long[] longOut = new long[4];
17065 final int[] SINGLE_LONG_FORMAT = new int[] {
17066 PROC_SPACE_TERM| PROC_OUT_LONG
17068 long[] longTmp = new long[1];
17069 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17070 SINGLE_LONG_FORMAT, null, longTmp, null);
17071 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17073 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17074 SINGLE_LONG_FORMAT, null, longTmp, null);
17075 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17077 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17078 SINGLE_LONG_FORMAT, null, longTmp, null);
17079 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17081 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17082 SINGLE_LONG_FORMAT, null, longTmp, null);
17083 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17087 private static String stringifySize(long size, int order) {
17088 Locale locale = Locale.US;
17091 return String.format(locale, "%,13d", size);
17093 return String.format(locale, "%,9dK", size / 1024);
17095 return String.format(locale, "%,5dM", size / 1024 / 1024);
17096 case 1024 * 1024 * 1024:
17097 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17099 throw new IllegalArgumentException("Invalid size order");
17103 private static String stringifyKBSize(long size) {
17104 return stringifySize(size * 1024, 1024);
17107 // Update this version number in case you change the 'compact' format
17108 private static final int MEMINFO_COMPACT_VERSION = 1;
17110 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17111 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17112 boolean dumpDetails = false;
17113 boolean dumpFullDetails = false;
17114 boolean dumpDalvik = false;
17115 boolean dumpSummaryOnly = false;
17116 boolean dumpUnreachable = false;
17117 boolean oomOnly = false;
17118 boolean isCompact = false;
17119 boolean localOnly = false;
17120 boolean packages = false;
17121 boolean isCheckinRequest = false;
17122 boolean dumpSwapPss = false;
17125 while (opti < args.length) {
17126 String opt = args[opti];
17127 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17131 if ("-a".equals(opt)) {
17132 dumpDetails = true;
17133 dumpFullDetails = true;
17135 dumpSwapPss = true;
17136 } else if ("-d".equals(opt)) {
17138 } else if ("-c".equals(opt)) {
17140 } else if ("-s".equals(opt)) {
17141 dumpDetails = true;
17142 dumpSummaryOnly = true;
17143 } else if ("-S".equals(opt)) {
17144 dumpSwapPss = true;
17145 } else if ("--unreachable".equals(opt)) {
17146 dumpUnreachable = true;
17147 } else if ("--oom".equals(opt)) {
17149 } else if ("--local".equals(opt)) {
17151 } else if ("--package".equals(opt)) {
17153 } else if ("--checkin".equals(opt)) {
17154 isCheckinRequest = true;
17156 } else if ("-h".equals(opt)) {
17157 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17158 pw.println(" -a: include all available information for each process.");
17159 pw.println(" -d: include dalvik details.");
17160 pw.println(" -c: dump in a compact machine-parseable representation.");
17161 pw.println(" -s: dump only summary of application memory usage.");
17162 pw.println(" -S: dump also SwapPss.");
17163 pw.println(" --oom: only show processes organized by oom adj.");
17164 pw.println(" --local: only collect details locally, don't call process.");
17165 pw.println(" --package: interpret process arg as package, dumping all");
17166 pw.println(" processes that have loaded that package.");
17167 pw.println(" --checkin: dump data for a checkin");
17168 pw.println("If [process] is specified it can be the name or ");
17169 pw.println("pid of a specific process to dump.");
17172 pw.println("Unknown argument: " + opt + "; use -h for help");
17176 long uptime = SystemClock.uptimeMillis();
17177 long realtime = SystemClock.elapsedRealtime();
17178 final long[] tmpLong = new long[1];
17180 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17181 if (procs == null) {
17182 // No Java processes. Maybe they want to print a native process.
17183 if (args != null && args.length > opti
17184 && args[opti].charAt(0) != '-') {
17185 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17186 = new ArrayList<ProcessCpuTracker.Stats>();
17187 updateCpuStatsNow();
17190 findPid = Integer.parseInt(args[opti]);
17191 } catch (NumberFormatException e) {
17193 synchronized (mProcessCpuTracker) {
17194 final int N = mProcessCpuTracker.countStats();
17195 for (int i=0; i<N; i++) {
17196 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17197 if (st.pid == findPid || (st.baseName != null
17198 && st.baseName.equals(args[opti]))) {
17199 nativeProcs.add(st);
17203 if (nativeProcs.size() > 0) {
17204 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17206 Debug.MemoryInfo mi = null;
17207 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17208 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17209 final int pid = r.pid;
17210 if (!isCheckinRequest && dumpDetails) {
17211 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17214 mi = new Debug.MemoryInfo();
17216 if (dumpDetails || (!brief && !oomOnly)) {
17217 Debug.getMemoryInfo(pid, mi);
17219 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17220 mi.dalvikPrivateDirty = (int)tmpLong[0];
17222 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17223 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17224 if (isCheckinRequest) {
17231 pw.println("No process found for: " + args[opti]);
17235 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17236 dumpDetails = true;
17239 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17241 String[] innerArgs = new String[args.length-opti];
17242 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17244 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17245 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17246 long nativePss = 0;
17247 long nativeSwapPss = 0;
17248 long dalvikPss = 0;
17249 long dalvikSwapPss = 0;
17250 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17252 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17255 long otherSwapPss = 0;
17256 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17257 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17259 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17260 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17261 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17262 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17265 long totalSwapPss = 0;
17266 long cachedPss = 0;
17267 long cachedSwapPss = 0;
17268 boolean hasSwapPss = false;
17270 Debug.MemoryInfo mi = null;
17271 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17272 final ProcessRecord r = procs.get(i);
17273 final IApplicationThread thread;
17276 final boolean hasActivities;
17277 synchronized (this) {
17280 oomAdj = r.getSetAdjWithServices();
17281 hasActivities = r.activities.size() > 0;
17283 if (thread != null) {
17284 if (!isCheckinRequest && dumpDetails) {
17285 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17288 mi = new Debug.MemoryInfo();
17290 if (dumpDetails || (!brief && !oomOnly)) {
17291 Debug.getMemoryInfo(pid, mi);
17292 hasSwapPss = mi.hasSwappedOutPss;
17294 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17295 mi.dalvikPrivateDirty = (int)tmpLong[0];
17299 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17300 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17301 if (isCheckinRequest) {
17307 TransferPipe tp = new TransferPipe();
17309 thread.dumpMemInfo(tp.getWriteFd(),
17310 mi, isCheckinRequest, dumpFullDetails,
17311 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17316 } catch (IOException e) {
17317 if (!isCheckinRequest) {
17318 pw.println("Got IoException! " + e);
17321 } catch (RemoteException e) {
17322 if (!isCheckinRequest) {
17323 pw.println("Got RemoteException! " + e);
17330 final long myTotalPss = mi.getTotalPss();
17331 final long myTotalUss = mi.getTotalUss();
17332 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17334 synchronized (this) {
17335 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17336 // Record this for posterity if the process has been stable.
17337 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17341 if (!isCheckinRequest && mi != null) {
17342 totalPss += myTotalPss;
17343 totalSwapPss += myTotalSwapPss;
17344 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17345 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17346 myTotalSwapPss, pid, hasActivities);
17347 procMems.add(pssItem);
17348 procMemsMap.put(pid, pssItem);
17350 nativePss += mi.nativePss;
17351 nativeSwapPss += mi.nativeSwappedOutPss;
17352 dalvikPss += mi.dalvikPss;
17353 dalvikSwapPss += mi.dalvikSwappedOutPss;
17354 for (int j=0; j<dalvikSubitemPss.length; j++) {
17355 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17356 dalvikSubitemSwapPss[j] +=
17357 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17359 otherPss += mi.otherPss;
17360 otherSwapPss += mi.otherSwappedOutPss;
17361 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17362 long mem = mi.getOtherPss(j);
17365 mem = mi.getOtherSwappedOutPss(j);
17366 miscSwapPss[j] += mem;
17367 otherSwapPss -= mem;
17370 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17371 cachedPss += myTotalPss;
17372 cachedSwapPss += myTotalSwapPss;
17375 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17376 if (oomIndex == (oomPss.length - 1)
17377 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17378 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17379 oomPss[oomIndex] += myTotalPss;
17380 oomSwapPss[oomIndex] += myTotalSwapPss;
17381 if (oomProcs[oomIndex] == null) {
17382 oomProcs[oomIndex] = new ArrayList<MemItem>();
17384 oomProcs[oomIndex].add(pssItem);
17392 long nativeProcTotalPss = 0;
17394 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17395 // If we are showing aggregations, also look for native processes to
17396 // include so that our aggregations are more accurate.
17397 updateCpuStatsNow();
17399 synchronized (mProcessCpuTracker) {
17400 final int N = mProcessCpuTracker.countStats();
17401 for (int i=0; i<N; i++) {
17402 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17403 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17405 mi = new Debug.MemoryInfo();
17407 if (!brief && !oomOnly) {
17408 Debug.getMemoryInfo(st.pid, mi);
17410 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17411 mi.nativePrivateDirty = (int)tmpLong[0];
17414 final long myTotalPss = mi.getTotalPss();
17415 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17416 totalPss += myTotalPss;
17417 nativeProcTotalPss += myTotalPss;
17419 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17420 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17421 procMems.add(pssItem);
17423 nativePss += mi.nativePss;
17424 nativeSwapPss += mi.nativeSwappedOutPss;
17425 dalvikPss += mi.dalvikPss;
17426 dalvikSwapPss += mi.dalvikSwappedOutPss;
17427 for (int j=0; j<dalvikSubitemPss.length; j++) {
17428 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17429 dalvikSubitemSwapPss[j] +=
17430 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17432 otherPss += mi.otherPss;
17433 otherSwapPss += mi.otherSwappedOutPss;
17434 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17435 long mem = mi.getOtherPss(j);
17438 mem = mi.getOtherSwappedOutPss(j);
17439 miscSwapPss[j] += mem;
17440 otherSwapPss -= mem;
17442 oomPss[0] += myTotalPss;
17443 oomSwapPss[0] += myTotalSwapPss;
17444 if (oomProcs[0] == null) {
17445 oomProcs[0] = new ArrayList<MemItem>();
17447 oomProcs[0].add(pssItem);
17452 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17454 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17455 final int dalvikId = -2;
17456 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17457 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17458 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17459 String label = Debug.MemoryInfo.getOtherLabel(j);
17460 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17462 if (dalvikSubitemPss.length > 0) {
17463 // Add dalvik subitems.
17464 for (MemItem memItem : catMems) {
17465 int memItemStart = 0, memItemEnd = 0;
17466 if (memItem.id == dalvikId) {
17467 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17468 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17469 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17470 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17471 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17472 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17473 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17474 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17475 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17476 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17477 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17479 continue; // No subitems, continue.
17481 memItem.subitems = new ArrayList<MemItem>();
17482 for (int j=memItemStart; j<=memItemEnd; j++) {
17483 final String name = Debug.MemoryInfo.getOtherLabel(
17484 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17485 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17486 dalvikSubitemSwapPss[j], j));
17491 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17492 for (int j=0; j<oomPss.length; j++) {
17493 if (oomPss[j] != 0) {
17494 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17495 : DUMP_MEM_OOM_LABEL[j];
17496 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17497 DUMP_MEM_OOM_ADJ[j]);
17498 item.subitems = oomProcs[j];
17503 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17504 if (!brief && !oomOnly && !isCompact) {
17506 pw.println("Total PSS by process:");
17507 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17511 pw.println("Total PSS by OOM adjustment:");
17513 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17514 if (!brief && !oomOnly) {
17515 PrintWriter out = categoryPw != null ? categoryPw : pw;
17518 out.println("Total PSS by category:");
17520 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17525 MemInfoReader memInfo = new MemInfoReader();
17526 memInfo.readMemInfo();
17527 if (nativeProcTotalPss > 0) {
17528 synchronized (this) {
17529 final long cachedKb = memInfo.getCachedSizeKb();
17530 final long freeKb = memInfo.getFreeSizeKb();
17531 final long zramKb = memInfo.getZramTotalSizeKb();
17532 final long kernelKb = memInfo.getKernelUsedSizeKb();
17533 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17534 kernelKb*1024, nativeProcTotalPss*1024);
17535 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17536 nativeProcTotalPss);
17541 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17542 pw.print(" (status ");
17543 switch (mLastMemoryLevel) {
17544 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17545 pw.println("normal)");
17547 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17548 pw.println("moderate)");
17550 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17551 pw.println("low)");
17553 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17554 pw.println("critical)");
17557 pw.print(mLastMemoryLevel);
17561 pw.print(" Free RAM: ");
17562 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17563 + memInfo.getFreeSizeKb()));
17565 pw.print(stringifyKBSize(cachedPss));
17566 pw.print(" cached pss + ");
17567 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17568 pw.print(" cached kernel + ");
17569 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17570 pw.println(" free)");
17572 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17573 pw.print(cachedPss + memInfo.getCachedSizeKb()
17574 + memInfo.getFreeSizeKb()); pw.print(",");
17575 pw.println(totalPss - cachedPss);
17578 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17579 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17580 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17582 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17583 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17584 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17585 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17586 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17588 pw.print("lostram,"); pw.println(lostRAM);
17591 if (memInfo.getZramTotalSizeKb() != 0) {
17593 pw.print(" ZRAM: ");
17594 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17595 pw.print(" physical used for ");
17596 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17597 - memInfo.getSwapFreeSizeKb()));
17598 pw.print(" in swap (");
17599 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17600 pw.println(" total swap)");
17602 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17603 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17604 pw.println(memInfo.getSwapFreeSizeKb());
17607 final long[] ksm = getKsmInfo();
17609 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17610 || ksm[KSM_VOLATILE] != 0) {
17611 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17612 pw.print(" saved from shared ");
17613 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17614 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17615 pw.print(" unshared; ");
17616 pw.print(stringifyKBSize(
17617 ksm[KSM_VOLATILE])); pw.println(" volatile");
17619 pw.print(" Tuning: ");
17620 pw.print(ActivityManager.staticGetMemoryClass());
17621 pw.print(" (large ");
17622 pw.print(ActivityManager.staticGetLargeMemoryClass());
17623 pw.print("), oom ");
17624 pw.print(stringifySize(
17625 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17626 pw.print(", restore limit ");
17627 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17628 if (ActivityManager.isLowRamDeviceStatic()) {
17629 pw.print(" (low-ram)");
17631 if (ActivityManager.isHighEndGfx()) {
17632 pw.print(" (high-end-gfx)");
17636 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17637 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17638 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17639 pw.print("tuning,");
17640 pw.print(ActivityManager.staticGetMemoryClass());
17642 pw.print(ActivityManager.staticGetLargeMemoryClass());
17644 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17645 if (ActivityManager.isLowRamDeviceStatic()) {
17646 pw.print(",low-ram");
17648 if (ActivityManager.isHighEndGfx()) {
17649 pw.print(",high-end-gfx");
17657 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17658 long memtrack, String name) {
17660 sb.append(ProcessList.makeOomAdjString(oomAdj));
17662 sb.append(ProcessList.makeProcStateString(procState));
17664 ProcessList.appendRamKb(sb, pss);
17667 if (memtrack > 0) {
17669 sb.append(stringifyKBSize(memtrack));
17670 sb.append(" memtrack)");
17674 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17675 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17676 sb.append(" (pid ");
17679 sb.append(mi.adjType);
17681 if (mi.adjReason != null) {
17683 sb.append(mi.adjReason);
17688 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17689 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17690 for (int i=0, N=memInfos.size(); i<N; i++) {
17691 ProcessMemInfo mi = memInfos.get(i);
17692 infoMap.put(mi.pid, mi);
17694 updateCpuStatsNow();
17695 long[] memtrackTmp = new long[1];
17696 final List<ProcessCpuTracker.Stats> stats;
17697 // Get a list of Stats that have vsize > 0
17698 synchronized (mProcessCpuTracker) {
17699 stats = mProcessCpuTracker.getStats((st) -> {
17700 return st.vsize > 0;
17703 final int statsCount = stats.size();
17704 for (int i = 0; i < statsCount; i++) {
17705 ProcessCpuTracker.Stats st = stats.get(i);
17706 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17708 if (infoMap.indexOfKey(st.pid) < 0) {
17709 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17710 ProcessList.NATIVE_ADJ, -1, "native", null);
17712 mi.memtrack = memtrackTmp[0];
17719 long totalMemtrack = 0;
17720 for (int i=0, N=memInfos.size(); i<N; i++) {
17721 ProcessMemInfo mi = memInfos.get(i);
17723 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17724 mi.memtrack = memtrackTmp[0];
17726 totalPss += mi.pss;
17727 totalMemtrack += mi.memtrack;
17729 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17730 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17731 if (lhs.oomAdj != rhs.oomAdj) {
17732 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17734 if (lhs.pss != rhs.pss) {
17735 return lhs.pss < rhs.pss ? 1 : -1;
17741 StringBuilder tag = new StringBuilder(128);
17742 StringBuilder stack = new StringBuilder(128);
17743 tag.append("Low on memory -- ");
17744 appendMemBucket(tag, totalPss, "total", false);
17745 appendMemBucket(stack, totalPss, "total", true);
17747 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17748 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17749 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17751 boolean firstLine = true;
17752 int lastOomAdj = Integer.MIN_VALUE;
17753 long extraNativeRam = 0;
17754 long extraNativeMemtrack = 0;
17755 long cachedPss = 0;
17756 for (int i=0, N=memInfos.size(); i<N; i++) {
17757 ProcessMemInfo mi = memInfos.get(i);
17759 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17760 cachedPss += mi.pss;
17763 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17764 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17765 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17766 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17767 if (lastOomAdj != mi.oomAdj) {
17768 lastOomAdj = mi.oomAdj;
17769 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17772 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17777 stack.append("\n\t at ");
17785 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17786 appendMemBucket(tag, mi.pss, mi.name, false);
17788 appendMemBucket(stack, mi.pss, mi.name, true);
17789 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17790 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17792 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17793 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17794 stack.append(DUMP_MEM_OOM_LABEL[k]);
17796 stack.append(DUMP_MEM_OOM_ADJ[k]);
17803 appendMemInfo(fullNativeBuilder, mi);
17804 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17805 // The short form only has native processes that are >= 512K.
17806 if (mi.pss >= 512) {
17807 appendMemInfo(shortNativeBuilder, mi);
17809 extraNativeRam += mi.pss;
17810 extraNativeMemtrack += mi.memtrack;
17813 // Short form has all other details, but if we have collected RAM
17814 // from smaller native processes let's dump a summary of that.
17815 if (extraNativeRam > 0) {
17816 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17817 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17818 shortNativeBuilder.append('\n');
17819 extraNativeRam = 0;
17821 appendMemInfo(fullJavaBuilder, mi);
17825 fullJavaBuilder.append(" ");
17826 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17827 fullJavaBuilder.append(": TOTAL");
17828 if (totalMemtrack > 0) {
17829 fullJavaBuilder.append(" (");
17830 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17831 fullJavaBuilder.append(" memtrack)");
17834 fullJavaBuilder.append("\n");
17836 MemInfoReader memInfo = new MemInfoReader();
17837 memInfo.readMemInfo();
17838 final long[] infos = memInfo.getRawInfo();
17840 StringBuilder memInfoBuilder = new StringBuilder(1024);
17841 Debug.getMemInfo(infos);
17842 memInfoBuilder.append(" MemInfo: ");
17843 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17844 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17845 memInfoBuilder.append(stringifyKBSize(
17846 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17847 memInfoBuilder.append(stringifyKBSize(
17848 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17849 memInfoBuilder.append(stringifyKBSize(
17850 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17851 memInfoBuilder.append(" ");
17852 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17853 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17854 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17855 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17856 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17857 memInfoBuilder.append(" ZRAM: ");
17858 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17859 memInfoBuilder.append(" RAM, ");
17860 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17861 memInfoBuilder.append(" swap total, ");
17862 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17863 memInfoBuilder.append(" swap free\n");
17865 final long[] ksm = getKsmInfo();
17866 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17867 || ksm[KSM_VOLATILE] != 0) {
17868 memInfoBuilder.append(" KSM: ");
17869 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17870 memInfoBuilder.append(" saved from shared ");
17871 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17872 memInfoBuilder.append("\n ");
17873 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17874 memInfoBuilder.append(" unshared; ");
17875 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17876 memInfoBuilder.append(" volatile\n");
17878 memInfoBuilder.append(" Free RAM: ");
17879 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17880 + memInfo.getFreeSizeKb()));
17881 memInfoBuilder.append("\n");
17882 memInfoBuilder.append(" Used RAM: ");
17883 memInfoBuilder.append(stringifyKBSize(
17884 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17885 memInfoBuilder.append("\n");
17886 memInfoBuilder.append(" Lost RAM: ");
17887 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17888 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17889 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17890 memInfoBuilder.append("\n");
17891 Slog.i(TAG, "Low on memory:");
17892 Slog.i(TAG, shortNativeBuilder.toString());
17893 Slog.i(TAG, fullJavaBuilder.toString());
17894 Slog.i(TAG, memInfoBuilder.toString());
17896 StringBuilder dropBuilder = new StringBuilder(1024);
17898 StringWriter oomSw = new StringWriter();
17899 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17900 StringWriter catSw = new StringWriter();
17901 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17902 String[] emptyArgs = new String[] { };
17903 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17905 String oomString = oomSw.toString();
17907 dropBuilder.append("Low on memory:");
17908 dropBuilder.append(stack);
17909 dropBuilder.append('\n');
17910 dropBuilder.append(fullNativeBuilder);
17911 dropBuilder.append(fullJavaBuilder);
17912 dropBuilder.append('\n');
17913 dropBuilder.append(memInfoBuilder);
17914 dropBuilder.append('\n');
17916 dropBuilder.append(oomString);
17917 dropBuilder.append('\n');
17919 StringWriter catSw = new StringWriter();
17920 synchronized (ActivityManagerService.this) {
17921 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17922 String[] emptyArgs = new String[] { };
17924 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17926 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17927 false, null).dumpLocked();
17929 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17932 dropBuilder.append(catSw.toString());
17933 addErrorToDropBox("lowmem", null, "system_server", null,
17934 null, tag.toString(), dropBuilder.toString(), null, null);
17935 //Slog.i(TAG, "Sent to dropbox:");
17936 //Slog.i(TAG, dropBuilder.toString());
17937 synchronized (ActivityManagerService.this) {
17938 long now = SystemClock.uptimeMillis();
17939 if (mLastMemUsageReportTime < now) {
17940 mLastMemUsageReportTime = now;
17946 * Searches array of arguments for the specified string
17947 * @param args array of argument strings
17948 * @param value value to search for
17949 * @return true if the value is contained in the array
17951 private static boolean scanArgs(String[] args, String value) {
17952 if (args != null) {
17953 for (String arg : args) {
17954 if (value.equals(arg)) {
17962 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17963 ContentProviderRecord cpr, boolean always) {
17964 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17966 if (!inLaunching || always) {
17967 synchronized (cpr) {
17968 cpr.launchingApp = null;
17971 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17972 String names[] = cpr.info.authority.split(";");
17973 for (int j = 0; j < names.length; j++) {
17974 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17978 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17979 ContentProviderConnection conn = cpr.connections.get(i);
17980 if (conn.waiting) {
17981 // If this connection is waiting for the provider, then we don't
17982 // need to mess with its process unless we are always removing
17983 // or for some reason the provider is not currently launching.
17984 if (inLaunching && !always) {
17988 ProcessRecord capp = conn.client;
17990 if (conn.stableCount > 0) {
17991 if (!capp.persistent && capp.thread != null
17993 && capp.pid != MY_PID) {
17994 capp.kill("depends on provider "
17995 + cpr.name.flattenToShortString()
17996 + " in dying proc " + (proc != null ? proc.processName : "??")
17997 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17999 } else if (capp.thread != null && conn.provider.provider != null) {
18001 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
18002 } catch (RemoteException e) {
18004 // In the protocol here, we don't expect the client to correctly
18005 // clean up this connection, we'll just remove it.
18006 cpr.connections.remove(i);
18007 if (conn.client.conProviders.remove(conn)) {
18008 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18013 if (inLaunching && always) {
18014 mLaunchingProviders.remove(cpr);
18016 return inLaunching;
18020 * Main code for cleaning up a process when it has gone away. This is
18021 * called both as a result of the process dying, or directly when stopping
18022 * a process when running in single process mode.
18024 * @return Returns true if the given process has been restarted, so the
18025 * app that was passed in must remain on the process lists.
18027 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18028 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18030 removeLruProcessLocked(app);
18031 ProcessList.remove(app.pid);
18034 mProcessesToGc.remove(app);
18035 mPendingPssProcesses.remove(app);
18037 // Dismiss any open dialogs.
18038 if (app.crashDialog != null && !app.forceCrashReport) {
18039 app.crashDialog.dismiss();
18040 app.crashDialog = null;
18042 if (app.anrDialog != null) {
18043 app.anrDialog.dismiss();
18044 app.anrDialog = null;
18046 if (app.waitDialog != null) {
18047 app.waitDialog.dismiss();
18048 app.waitDialog = null;
18051 app.crashing = false;
18052 app.notResponding = false;
18054 app.resetPackageList(mProcessStats);
18055 app.unlinkDeathRecipient();
18056 app.makeInactive(mProcessStats);
18057 app.waitingToKill = null;
18058 app.forcingToImportant = null;
18059 updateProcessForegroundLocked(app, false, false);
18060 app.foregroundActivities = false;
18061 app.hasShownUi = false;
18062 app.treatLikeActivity = false;
18063 app.hasAboveClient = false;
18064 app.hasClientActivities = false;
18066 mServices.killServicesLocked(app, allowRestart);
18068 boolean restart = false;
18070 // Remove published content providers.
18071 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18072 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18073 final boolean always = app.bad || !allowRestart;
18074 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18075 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18076 // We left the provider in the launching list, need to
18081 cpr.provider = null;
18084 app.pubProviders.clear();
18086 // Take care of any launching providers waiting for this process.
18087 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18091 // Unregister from connected content providers.
18092 if (!app.conProviders.isEmpty()) {
18093 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18094 ContentProviderConnection conn = app.conProviders.get(i);
18095 conn.provider.connections.remove(conn);
18096 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18097 conn.provider.name);
18099 app.conProviders.clear();
18102 // At this point there may be remaining entries in mLaunchingProviders
18103 // where we were the only one waiting, so they are no longer of use.
18104 // Look for these and clean up if found.
18105 // XXX Commented out for now. Trying to figure out a way to reproduce
18106 // the actual situation to identify what is actually going on.
18108 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18109 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18110 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18111 synchronized (cpr) {
18112 cpr.launchingApp = null;
18119 skipCurrentReceiverLocked(app);
18121 // Unregister any receivers.
18122 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18123 removeReceiverLocked(app.receivers.valueAt(i));
18125 app.receivers.clear();
18127 // If the app is undergoing backup, tell the backup manager about it
18128 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18129 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18130 + mBackupTarget.appInfo + " died during backup");
18131 mHandler.post(new Runnable() {
18135 IBackupManager bm = IBackupManager.Stub.asInterface(
18136 ServiceManager.getService(Context.BACKUP_SERVICE));
18137 bm.agentDisconnected(app.info.packageName);
18138 } catch (RemoteException e) {
18139 // can't happen; backup manager is local
18145 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18146 ProcessChangeItem item = mPendingProcessChanges.get(i);
18147 if (item.pid == app.pid) {
18148 mPendingProcessChanges.remove(i);
18149 mAvailProcessChanges.add(item);
18152 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18153 null).sendToTarget();
18155 // If the caller is restarting this app, then leave it in its
18156 // current lists and let the caller take care of it.
18161 if (!app.persistent || app.isolated) {
18162 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18163 "Removing non-persistent process during cleanup: " + app);
18164 if (!replacingPid) {
18165 removeProcessNameLocked(app.processName, app.uid, app);
18167 if (mHeavyWeightProcess == app) {
18168 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18169 mHeavyWeightProcess.userId, 0));
18170 mHeavyWeightProcess = null;
18172 } else if (!app.removed) {
18173 // This app is persistent, so we need to keep its record around.
18174 // If it is not already on the pending app list, add it there
18175 // and start a new process for it.
18176 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18177 mPersistentStartingProcesses.add(app);
18181 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18182 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18183 mProcessesOnHold.remove(app);
18185 if (app == mHomeProcess) {
18186 mHomeProcess = null;
18188 if (app == mPreviousProcess) {
18189 mPreviousProcess = null;
18192 if (restart && !app.isolated) {
18193 // We have components that still need to be running in the
18194 // process, so re-launch it.
18196 ProcessList.remove(app.pid);
18198 addProcessNameLocked(app);
18199 startProcessLocked(app, "restart", app.processName);
18201 } else if (app.pid > 0 && app.pid != MY_PID) {
18204 synchronized (mPidsSelfLocked) {
18205 mPidsSelfLocked.remove(app.pid);
18206 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18208 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18209 if (app.isolated) {
18210 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18217 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18218 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18219 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18220 if (cpr.launchingApp == app) {
18227 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18228 // Look through the content providers we are waiting to have launched,
18229 // and if any run in this process then either schedule a restart of
18230 // the process or kill the client waiting for it if this process has
18232 boolean restart = false;
18233 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18234 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18235 if (cpr.launchingApp == app) {
18236 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18239 removeDyingProviderLocked(app, cpr, true);
18246 // =========================================================
18248 // =========================================================
18251 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18253 enforceNotIsolatedCaller("getServices");
18255 final int callingUid = Binder.getCallingUid();
18256 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18257 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18258 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18260 synchronized (this) {
18261 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18262 allowed, canInteractAcrossUsers);
18267 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18268 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18269 synchronized (this) {
18270 return mServices.getRunningServiceControlPanelLocked(name);
18275 public ComponentName startService(IApplicationThread caller, Intent service,
18276 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18277 throws TransactionTooLargeException {
18278 enforceNotIsolatedCaller("startService");
18279 // Refuse possible leaked file descriptors
18280 if (service != null && service.hasFileDescriptors() == true) {
18281 throw new IllegalArgumentException("File descriptors passed in Intent");
18284 if (callingPackage == null) {
18285 throw new IllegalArgumentException("callingPackage cannot be null");
18288 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18289 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18290 synchronized(this) {
18291 final int callingPid = Binder.getCallingPid();
18292 final int callingUid = Binder.getCallingUid();
18293 final long origId = Binder.clearCallingIdentity();
18296 res = mServices.startServiceLocked(caller, service,
18297 resolvedType, callingPid, callingUid,
18298 requireForeground, callingPackage, userId);
18300 Binder.restoreCallingIdentity(origId);
18306 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18307 boolean fgRequired, String callingPackage, int userId)
18308 throws TransactionTooLargeException {
18309 synchronized(this) {
18310 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18311 "startServiceInPackage: " + service + " type=" + resolvedType);
18312 final long origId = Binder.clearCallingIdentity();
18315 res = mServices.startServiceLocked(null, service,
18316 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18318 Binder.restoreCallingIdentity(origId);
18325 public int stopService(IApplicationThread caller, Intent service,
18326 String resolvedType, int userId) {
18327 enforceNotIsolatedCaller("stopService");
18328 // Refuse possible leaked file descriptors
18329 if (service != null && service.hasFileDescriptors() == true) {
18330 throw new IllegalArgumentException("File descriptors passed in Intent");
18333 synchronized(this) {
18334 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18339 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18340 enforceNotIsolatedCaller("peekService");
18341 // Refuse possible leaked file descriptors
18342 if (service != null && service.hasFileDescriptors() == true) {
18343 throw new IllegalArgumentException("File descriptors passed in Intent");
18346 if (callingPackage == null) {
18347 throw new IllegalArgumentException("callingPackage cannot be null");
18350 synchronized(this) {
18351 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18356 public boolean stopServiceToken(ComponentName className, IBinder token,
18358 synchronized(this) {
18359 return mServices.stopServiceTokenLocked(className, token, startId);
18364 public void setServiceForeground(ComponentName className, IBinder token,
18365 int id, Notification notification, int flags) {
18366 synchronized(this) {
18367 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18372 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18373 boolean requireFull, String name, String callerPackage) {
18374 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18375 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18378 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18379 String className, int flags) {
18380 boolean result = false;
18381 // For apps that don't have pre-defined UIDs, check for permission
18382 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18383 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18384 if (ActivityManager.checkUidPermission(
18385 INTERACT_ACROSS_USERS,
18386 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18387 ComponentName comp = new ComponentName(aInfo.packageName, className);
18388 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18389 + " requests FLAG_SINGLE_USER, but app does not hold "
18390 + INTERACT_ACROSS_USERS;
18392 throw new SecurityException(msg);
18394 // Permission passed
18397 } else if ("system".equals(componentProcessName)) {
18399 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18400 // Phone app and persistent apps are allowed to export singleuser providers.
18401 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18402 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18404 if (DEBUG_MU) Slog.v(TAG_MU,
18405 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18406 + Integer.toHexString(flags) + ") = " + result);
18411 * Checks to see if the caller is in the same app as the singleton
18412 * component, or the component is in a special app. It allows special apps
18413 * to export singleton components but prevents exporting singleton
18414 * components for regular apps.
18416 boolean isValidSingletonCall(int callingUid, int componentUid) {
18417 int componentAppId = UserHandle.getAppId(componentUid);
18418 return UserHandle.isSameApp(callingUid, componentUid)
18419 || componentAppId == SYSTEM_UID
18420 || componentAppId == PHONE_UID
18421 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18422 == PackageManager.PERMISSION_GRANTED;
18425 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18426 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18427 int userId) throws TransactionTooLargeException {
18428 enforceNotIsolatedCaller("bindService");
18430 // Refuse possible leaked file descriptors
18431 if (service != null && service.hasFileDescriptors() == true) {
18432 throw new IllegalArgumentException("File descriptors passed in Intent");
18435 if (callingPackage == null) {
18436 throw new IllegalArgumentException("callingPackage cannot be null");
18439 synchronized(this) {
18440 return mServices.bindServiceLocked(caller, token, service,
18441 resolvedType, connection, flags, callingPackage, userId);
18445 public boolean unbindService(IServiceConnection connection) {
18446 synchronized (this) {
18447 return mServices.unbindServiceLocked(connection);
18451 public void publishService(IBinder token, Intent intent, IBinder service) {
18452 // Refuse possible leaked file descriptors
18453 if (intent != null && intent.hasFileDescriptors() == true) {
18454 throw new IllegalArgumentException("File descriptors passed in Intent");
18457 synchronized(this) {
18458 if (!(token instanceof ServiceRecord)) {
18459 throw new IllegalArgumentException("Invalid service token");
18461 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18465 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18466 // Refuse possible leaked file descriptors
18467 if (intent != null && intent.hasFileDescriptors() == true) {
18468 throw new IllegalArgumentException("File descriptors passed in Intent");
18471 synchronized(this) {
18472 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18476 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18477 synchronized(this) {
18478 if (!(token instanceof ServiceRecord)) {
18479 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18480 throw new IllegalArgumentException("Invalid service token");
18482 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18486 // =========================================================
18487 // BACKUP AND RESTORE
18488 // =========================================================
18490 // Cause the target app to be launched if necessary and its backup agent
18491 // instantiated. The backup agent will invoke backupAgentCreated() on the
18492 // activity manager to announce its creation.
18493 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18494 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18495 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18497 IPackageManager pm = AppGlobals.getPackageManager();
18498 ApplicationInfo app = null;
18500 app = pm.getApplicationInfo(packageName, 0, userId);
18501 } catch (RemoteException e) {
18502 // can't happen; package manager is process-local
18505 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18512 synchronized(this) {
18513 // !!! TODO: currently no check here that we're already bound
18514 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18515 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18516 synchronized (stats) {
18517 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18520 // Backup agent is now in use, its package can't be stopped.
18522 AppGlobals.getPackageManager().setPackageStoppedState(
18523 app.packageName, false, UserHandle.getUserId(app.uid));
18524 } catch (RemoteException e) {
18525 } catch (IllegalArgumentException e) {
18526 Slog.w(TAG, "Failed trying to unstop package "
18527 + app.packageName + ": " + e);
18530 BackupRecord r = new BackupRecord(ss, app, backupMode);
18531 ComponentName hostingName =
18532 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18533 ? new ComponentName(app.packageName, app.backupAgentName)
18534 : new ComponentName("android", "FullBackupAgent");
18535 // startProcessLocked() returns existing proc's record if it's already running
18536 ProcessRecord proc = startProcessLocked(app.processName, app,
18537 false, 0, "backup", hostingName, false, false, false);
18538 if (proc == null) {
18539 Slog.e(TAG, "Unable to start backup agent process " + r);
18543 // If the app is a regular app (uid >= 10000) and not the system server or phone
18544 // process, etc, then mark it as being in full backup so that certain calls to the
18545 // process can be blocked. This is not reset to false anywhere because we kill the
18546 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18547 if (UserHandle.isApp(app.uid) &&
18548 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18549 proc.inFullBackup = true;
18552 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18553 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18555 mBackupAppName = app.packageName;
18557 // Try not to kill the process during backup
18558 updateOomAdjLocked(proc, true);
18560 // If the process is already attached, schedule the creation of the backup agent now.
18561 // If it is not yet live, this will be done when it attaches to the framework.
18562 if (proc.thread != null) {
18563 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18565 proc.thread.scheduleCreateBackupAgent(app,
18566 compatibilityInfoForPackageLocked(app), backupMode);
18567 } catch (RemoteException e) {
18568 // Will time out on the backup manager side
18571 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18573 // Invariants: at this point, the target app process exists and the application
18574 // is either already running or in the process of coming up. mBackupTarget and
18575 // mBackupAppName describe the app, so that when it binds back to the AM we
18576 // know that it's scheduled for a backup-agent operation.
18579 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18580 if (oldBackupUid != -1) {
18581 js.removeBackingUpUid(oldBackupUid);
18583 if (newBackupUid != -1) {
18584 js.addBackingUpUid(newBackupUid);
18591 public void clearPendingBackup() {
18592 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18593 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18595 synchronized (this) {
18596 mBackupTarget = null;
18597 mBackupAppName = null;
18600 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18601 js.clearAllBackingUpUids();
18604 // A backup agent has just come up
18605 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18606 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18609 synchronized(this) {
18610 if (!agentPackageName.equals(mBackupAppName)) {
18611 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18616 long oldIdent = Binder.clearCallingIdentity();
18618 IBackupManager bm = IBackupManager.Stub.asInterface(
18619 ServiceManager.getService(Context.BACKUP_SERVICE));
18620 bm.agentConnected(agentPackageName, agent);
18621 } catch (RemoteException e) {
18622 // can't happen; the backup manager service is local
18623 } catch (Exception e) {
18624 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18625 e.printStackTrace();
18627 Binder.restoreCallingIdentity(oldIdent);
18631 // done with this agent
18632 public void unbindBackupAgent(ApplicationInfo appInfo) {
18633 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18634 if (appInfo == null) {
18635 Slog.w(TAG, "unbind backup agent for null app");
18641 synchronized(this) {
18643 if (mBackupAppName == null) {
18644 Slog.w(TAG, "Unbinding backup agent with no active backup");
18648 if (!mBackupAppName.equals(appInfo.packageName)) {
18649 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18653 // Not backing this app up any more; reset its OOM adjustment
18654 final ProcessRecord proc = mBackupTarget.app;
18655 updateOomAdjLocked(proc, true);
18656 proc.inFullBackup = false;
18658 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18660 // If the app crashed during backup, 'thread' will be null here
18661 if (proc.thread != null) {
18663 proc.thread.scheduleDestroyBackupAgent(appInfo,
18664 compatibilityInfoForPackageLocked(appInfo));
18665 } catch (Exception e) {
18666 Slog.e(TAG, "Exception when unbinding backup agent:");
18667 e.printStackTrace();
18671 mBackupTarget = null;
18672 mBackupAppName = null;
18676 if (oldBackupUid != -1) {
18677 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18678 js.removeBackingUpUid(oldBackupUid);
18682 // =========================================================
18684 // =========================================================
18686 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18687 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18690 // Easy case -- we have the app's ProcessRecord.
18691 if (record != null) {
18692 return record.info.isInstantApp();
18694 // Otherwise check with PackageManager.
18695 if (callerPackage == null) {
18696 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18697 throw new IllegalArgumentException("Calling application did not provide package name");
18699 mAppOpsService.checkPackage(uid, callerPackage);
18701 IPackageManager pm = AppGlobals.getPackageManager();
18702 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18703 } catch (RemoteException e) {
18704 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18709 boolean isPendingBroadcastProcessLocked(int pid) {
18710 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18711 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18714 void skipPendingBroadcastLocked(int pid) {
18715 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18716 for (BroadcastQueue queue : mBroadcastQueues) {
18717 queue.skipPendingBroadcastLocked(pid);
18721 // The app just attached; send any pending broadcasts that it should receive
18722 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18723 boolean didSomething = false;
18724 for (BroadcastQueue queue : mBroadcastQueues) {
18725 didSomething |= queue.sendPendingBroadcastsLocked(app);
18727 return didSomething;
18730 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18731 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18733 enforceNotIsolatedCaller("registerReceiver");
18734 ArrayList<Intent> stickyIntents = null;
18735 ProcessRecord callerApp = null;
18736 final boolean visibleToInstantApps
18737 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18740 boolean instantApp;
18741 synchronized(this) {
18742 if (caller != null) {
18743 callerApp = getRecordForAppLocked(caller);
18744 if (callerApp == null) {
18745 throw new SecurityException(
18746 "Unable to find app for caller " + caller
18747 + " (pid=" + Binder.getCallingPid()
18748 + ") when registering receiver " + receiver);
18750 if (callerApp.info.uid != SYSTEM_UID &&
18751 !callerApp.pkgList.containsKey(callerPackage) &&
18752 !"android".equals(callerPackage)) {
18753 throw new SecurityException("Given caller package " + callerPackage
18754 + " is not running in process " + callerApp);
18756 callingUid = callerApp.info.uid;
18757 callingPid = callerApp.pid;
18759 callerPackage = null;
18760 callingUid = Binder.getCallingUid();
18761 callingPid = Binder.getCallingPid();
18764 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18765 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18766 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18768 Iterator<String> actions = filter.actionsIterator();
18769 if (actions == null) {
18770 ArrayList<String> noAction = new ArrayList<String>(1);
18771 noAction.add(null);
18772 actions = noAction.iterator();
18775 // Collect stickies of users
18776 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18777 while (actions.hasNext()) {
18778 String action = actions.next();
18779 for (int id : userIds) {
18780 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18781 if (stickies != null) {
18782 ArrayList<Intent> intents = stickies.get(action);
18783 if (intents != null) {
18784 if (stickyIntents == null) {
18785 stickyIntents = new ArrayList<Intent>();
18787 stickyIntents.addAll(intents);
18794 ArrayList<Intent> allSticky = null;
18795 if (stickyIntents != null) {
18796 final ContentResolver resolver = mContext.getContentResolver();
18797 // Look for any matching sticky broadcasts...
18798 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18799 Intent intent = stickyIntents.get(i);
18800 // Don't provided intents that aren't available to instant apps.
18802 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18805 // If intent has scheme "content", it will need to acccess
18806 // provider that needs to lock mProviderMap in ActivityThread
18807 // and also it may need to wait application response, so we
18808 // cannot lock ActivityManagerService here.
18809 if (filter.match(resolver, intent, true, TAG) >= 0) {
18810 if (allSticky == null) {
18811 allSticky = new ArrayList<Intent>();
18813 allSticky.add(intent);
18818 // The first sticky in the list is returned directly back to the client.
18819 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18820 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18821 if (receiver == null) {
18825 synchronized (this) {
18826 if (callerApp != null && (callerApp.thread == null
18827 || callerApp.thread.asBinder() != caller.asBinder())) {
18828 // Original caller already died
18831 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18833 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18835 if (rl.app != null) {
18836 rl.app.receivers.add(rl);
18839 receiver.asBinder().linkToDeath(rl, 0);
18840 } catch (RemoteException e) {
18843 rl.linkedToDeath = true;
18845 mRegisteredReceivers.put(receiver.asBinder(), rl);
18846 } else if (rl.uid != callingUid) {
18847 throw new IllegalArgumentException(
18848 "Receiver requested to register for uid " + callingUid
18849 + " was previously registered for uid " + rl.uid
18850 + " callerPackage is " + callerPackage);
18851 } else if (rl.pid != callingPid) {
18852 throw new IllegalArgumentException(
18853 "Receiver requested to register for pid " + callingPid
18854 + " was previously registered for pid " + rl.pid
18855 + " callerPackage is " + callerPackage);
18856 } else if (rl.userId != userId) {
18857 throw new IllegalArgumentException(
18858 "Receiver requested to register for user " + userId
18859 + " was previously registered for user " + rl.userId
18860 + " callerPackage is " + callerPackage);
18862 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18863 permission, callingUid, userId, instantApp, visibleToInstantApps);
18865 if (!bf.debugCheck()) {
18866 Slog.w(TAG, "==> For Dynamic broadcast");
18868 mReceiverResolver.addFilter(bf);
18870 // Enqueue broadcasts for all existing stickies that match
18872 if (allSticky != null) {
18873 ArrayList receivers = new ArrayList();
18876 final int stickyCount = allSticky.size();
18877 for (int i = 0; i < stickyCount; i++) {
18878 Intent intent = allSticky.get(i);
18879 BroadcastQueue queue = broadcastQueueForIntent(intent);
18880 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18881 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18882 null, 0, null, null, false, true, true, -1);
18883 queue.enqueueParallelBroadcastLocked(r);
18884 queue.scheduleBroadcastsLocked();
18892 public void unregisterReceiver(IIntentReceiver receiver) {
18893 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18895 final long origId = Binder.clearCallingIdentity();
18897 boolean doTrim = false;
18899 synchronized(this) {
18900 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18902 final BroadcastRecord r = rl.curBroadcast;
18903 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18904 final boolean doNext = r.queue.finishReceiverLocked(
18905 r, r.resultCode, r.resultData, r.resultExtras,
18906 r.resultAbort, false);
18909 r.queue.processNextBroadcast(false);
18913 if (rl.app != null) {
18914 rl.app.receivers.remove(rl);
18916 removeReceiverLocked(rl);
18917 if (rl.linkedToDeath) {
18918 rl.linkedToDeath = false;
18919 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18924 // If we actually concluded any broadcasts, we might now be able
18925 // to trim the recipients' apps from our working set
18927 trimApplications();
18932 Binder.restoreCallingIdentity(origId);
18936 void removeReceiverLocked(ReceiverList rl) {
18937 mRegisteredReceivers.remove(rl.receiver.asBinder());
18938 for (int i = rl.size() - 1; i >= 0; i--) {
18939 mReceiverResolver.removeFilter(rl.get(i));
18943 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18944 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18945 ProcessRecord r = mLruProcesses.get(i);
18946 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18948 r.thread.dispatchPackageBroadcast(cmd, packages);
18949 } catch (RemoteException ex) {
18955 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18956 int callingUid, int[] users) {
18957 // TODO: come back and remove this assumption to triage all broadcasts
18958 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18960 List<ResolveInfo> receivers = null;
18962 HashSet<ComponentName> singleUserReceivers = null;
18963 boolean scannedFirstReceivers = false;
18964 for (int user : users) {
18965 // Skip users that have Shell restrictions, with exception of always permitted
18966 // Shell broadcasts
18967 if (callingUid == SHELL_UID
18968 && mUserController.hasUserRestriction(
18969 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18970 && !isPermittedShellBroadcast(intent)) {
18973 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18974 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18975 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18976 // If this is not the system user, we need to check for
18977 // any receivers that should be filtered out.
18978 for (int i=0; i<newReceivers.size(); i++) {
18979 ResolveInfo ri = newReceivers.get(i);
18980 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18981 newReceivers.remove(i);
18986 if (newReceivers != null && newReceivers.size() == 0) {
18987 newReceivers = null;
18989 if (receivers == null) {
18990 receivers = newReceivers;
18991 } else if (newReceivers != null) {
18992 // We need to concatenate the additional receivers
18993 // found with what we have do far. This would be easy,
18994 // but we also need to de-dup any receivers that are
18996 if (!scannedFirstReceivers) {
18997 // Collect any single user receivers we had already retrieved.
18998 scannedFirstReceivers = true;
18999 for (int i=0; i<receivers.size(); i++) {
19000 ResolveInfo ri = receivers.get(i);
19001 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19002 ComponentName cn = new ComponentName(
19003 ri.activityInfo.packageName, ri.activityInfo.name);
19004 if (singleUserReceivers == null) {
19005 singleUserReceivers = new HashSet<ComponentName>();
19007 singleUserReceivers.add(cn);
19011 // Add the new results to the existing results, tracking
19012 // and de-dupping single user receivers.
19013 for (int i=0; i<newReceivers.size(); i++) {
19014 ResolveInfo ri = newReceivers.get(i);
19015 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19016 ComponentName cn = new ComponentName(
19017 ri.activityInfo.packageName, ri.activityInfo.name);
19018 if (singleUserReceivers == null) {
19019 singleUserReceivers = new HashSet<ComponentName>();
19021 if (!singleUserReceivers.contains(cn)) {
19022 singleUserReceivers.add(cn);
19031 } catch (RemoteException ex) {
19032 // pm is in same process, this will never happen.
19037 private boolean isPermittedShellBroadcast(Intent intent) {
19038 // remote bugreport should always be allowed to be taken
19039 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19042 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19043 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19044 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19045 // Don't yell about broadcasts sent via shell
19049 final String action = intent.getAction();
19050 if (isProtectedBroadcast
19051 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19052 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19053 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19054 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19055 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19056 || Intent.ACTION_MASTER_CLEAR.equals(action)
19057 || Intent.ACTION_FACTORY_RESET.equals(action)
19058 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19059 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19060 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19061 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19062 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19063 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19064 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19065 // Broadcast is either protected, or it's a public action that
19066 // we've relaxed, so it's fine for system internals to send.
19070 // This broadcast may be a problem... but there are often system components that
19071 // want to send an internal broadcast to themselves, which is annoying to have to
19072 // explicitly list each action as a protected broadcast, so we will check for that
19073 // one safe case and allow it: an explicit broadcast, only being received by something
19074 // that has protected itself.
19075 if (receivers != null && receivers.size() > 0
19076 && (intent.getPackage() != null || intent.getComponent() != null)) {
19077 boolean allProtected = true;
19078 for (int i = receivers.size()-1; i >= 0; i--) {
19079 Object target = receivers.get(i);
19080 if (target instanceof ResolveInfo) {
19081 ResolveInfo ri = (ResolveInfo)target;
19082 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19083 allProtected = false;
19087 BroadcastFilter bf = (BroadcastFilter)target;
19088 if (bf.requiredPermission == null) {
19089 allProtected = false;
19094 if (allProtected) {
19100 // The vast majority of broadcasts sent from system internals
19101 // should be protected to avoid security holes, so yell loudly
19102 // to ensure we examine these cases.
19103 if (callerApp != null) {
19104 Log.wtf(TAG, "Sending non-protected broadcast " + action
19105 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19108 Log.wtf(TAG, "Sending non-protected broadcast " + action
19109 + " from system uid " + UserHandle.formatUid(callingUid)
19110 + " pkg " + callerPackage,
19115 final int broadcastIntentLocked(ProcessRecord callerApp,
19116 String callerPackage, Intent intent, String resolvedType,
19117 IIntentReceiver resultTo, int resultCode, String resultData,
19118 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19119 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19120 intent = new Intent(intent);
19122 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19123 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19124 if (callerInstantApp) {
19125 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19128 // By default broadcasts do not go to stopped apps.
19129 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19131 // If we have not finished booting, don't allow this to launch new processes.
19132 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19133 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19136 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19137 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19138 + " ordered=" + ordered + " userid=" + userId);
19139 if ((resultTo != null) && !ordered) {
19140 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19143 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19144 ALLOW_NON_FULL, "broadcast", callerPackage);
19146 // Make sure that the user who is receiving this broadcast is running.
19147 // If not, we will just skip it. Make an exception for shutdown broadcasts
19148 // and upgrade steps.
19150 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19151 if ((callingUid != SYSTEM_UID
19152 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19153 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19154 Slog.w(TAG, "Skipping broadcast of " + intent
19155 + ": user " + userId + " is stopped");
19156 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19160 BroadcastOptions brOptions = null;
19161 if (bOptions != null) {
19162 brOptions = new BroadcastOptions(bOptions);
19163 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19164 // See if the caller is allowed to do this. Note we are checking against
19165 // the actual real caller (not whoever provided the operation as say a
19166 // PendingIntent), because that who is actually supplied the arguments.
19167 if (checkComponentPermission(
19168 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19169 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19170 != PackageManager.PERMISSION_GRANTED) {
19171 String msg = "Permission Denial: " + intent.getAction()
19172 + " broadcast from " + callerPackage + " (pid=" + callingPid
19173 + ", uid=" + callingUid + ")"
19175 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19177 throw new SecurityException(msg);
19182 // Verify that protected broadcasts are only being sent by system code,
19183 // and that system code is only sending protected broadcasts.
19184 final String action = intent.getAction();
19185 final boolean isProtectedBroadcast;
19187 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19188 } catch (RemoteException e) {
19189 Slog.w(TAG, "Remote exception", e);
19190 return ActivityManager.BROADCAST_SUCCESS;
19193 final boolean isCallerSystem;
19194 switch (UserHandle.getAppId(callingUid)) {
19198 case BLUETOOTH_UID:
19200 isCallerSystem = true;
19203 isCallerSystem = (callerApp != null) && callerApp.persistent;
19207 // First line security check before anything else: stop non-system apps from
19208 // sending protected broadcasts.
19209 if (!isCallerSystem) {
19210 if (isProtectedBroadcast) {
19211 String msg = "Permission Denial: not allowed to send broadcast "
19212 + action + " from pid="
19213 + callingPid + ", uid=" + callingUid;
19215 throw new SecurityException(msg);
19217 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19218 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19219 // Special case for compatibility: we don't want apps to send this,
19220 // but historically it has not been protected and apps may be using it
19221 // to poke their own app widget. So, instead of making it protected,
19222 // just limit it to the caller.
19223 if (callerPackage == null) {
19224 String msg = "Permission Denial: not allowed to send broadcast "
19225 + action + " from unknown caller.";
19227 throw new SecurityException(msg);
19228 } else if (intent.getComponent() != null) {
19229 // They are good enough to send to an explicit component... verify
19230 // it is being sent to the calling app.
19231 if (!intent.getComponent().getPackageName().equals(
19233 String msg = "Permission Denial: not allowed to send broadcast "
19235 + intent.getComponent().getPackageName() + " from "
19238 throw new SecurityException(msg);
19241 // Limit broadcast to their own package.
19242 intent.setPackage(callerPackage);
19247 if (action != null) {
19248 if (getBackgroundLaunchBroadcasts().contains(action)) {
19249 if (DEBUG_BACKGROUND_CHECK) {
19250 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19252 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19256 case Intent.ACTION_UID_REMOVED:
19257 case Intent.ACTION_PACKAGE_REMOVED:
19258 case Intent.ACTION_PACKAGE_CHANGED:
19259 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19260 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19261 case Intent.ACTION_PACKAGES_SUSPENDED:
19262 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19263 // Handle special intents: if this broadcast is from the package
19264 // manager about a package being removed, we need to remove all of
19265 // its activities from the history stack.
19266 if (checkComponentPermission(
19267 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19268 callingPid, callingUid, -1, true)
19269 != PackageManager.PERMISSION_GRANTED) {
19270 String msg = "Permission Denial: " + intent.getAction()
19271 + " broadcast from " + callerPackage + " (pid=" + callingPid
19272 + ", uid=" + callingUid + ")"
19274 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19276 throw new SecurityException(msg);
19279 case Intent.ACTION_UID_REMOVED:
19280 final int uid = getUidFromIntent(intent);
19282 mBatteryStatsService.removeUid(uid);
19283 mAppOpsService.uidRemoved(uid);
19286 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19287 // If resources are unavailable just force stop all those packages
19288 // and flush the attribute cache as well.
19290 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19291 if (list != null && list.length > 0) {
19292 for (int i = 0; i < list.length; i++) {
19293 forceStopPackageLocked(list[i], -1, false, true, true,
19294 false, false, userId, "storage unmount");
19296 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19297 sendPackageBroadcastLocked(
19298 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19302 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19303 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19305 case Intent.ACTION_PACKAGE_REMOVED:
19306 case Intent.ACTION_PACKAGE_CHANGED:
19307 Uri data = intent.getData();
19309 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19310 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19311 final boolean replacing =
19312 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19313 final boolean killProcess =
19314 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19315 final boolean fullUninstall = removed && !replacing;
19318 forceStopPackageLocked(ssp, UserHandle.getAppId(
19319 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19320 false, true, true, false, fullUninstall, userId,
19321 removed ? "pkg removed" : "pkg changed");
19323 final int cmd = killProcess
19324 ? ApplicationThreadConstants.PACKAGE_REMOVED
19325 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19326 sendPackageBroadcastLocked(cmd,
19327 new String[] {ssp}, userId);
19328 if (fullUninstall) {
19329 mAppOpsService.packageRemoved(
19330 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19332 // Remove all permissions granted from/to this package
19333 removeUriPermissionsForPackageLocked(ssp, userId, true);
19335 removeTasksByPackageNameLocked(ssp, userId);
19337 mServices.forceStopPackageLocked(ssp, userId);
19339 // Hide the "unsupported display" dialog if necessary.
19340 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19341 mUnsupportedDisplaySizeDialog.getPackageName())) {
19342 mUnsupportedDisplaySizeDialog.dismiss();
19343 mUnsupportedDisplaySizeDialog = null;
19345 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19346 mBatteryStatsService.notePackageUninstalled(ssp);
19350 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19351 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19352 userId, ProcessList.INVALID_ADJ,
19353 false, true, true, false, "change " + ssp);
19355 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19356 intent.getStringArrayExtra(
19357 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19361 case Intent.ACTION_PACKAGES_SUSPENDED:
19362 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19363 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19364 intent.getAction());
19365 final String[] packageNames = intent.getStringArrayExtra(
19366 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19367 final int userHandle = intent.getIntExtra(
19368 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19370 synchronized(ActivityManagerService.this) {
19371 mRecentTasks.onPackagesSuspendedChanged(
19372 packageNames, suspended, userHandle);
19377 case Intent.ACTION_PACKAGE_REPLACED:
19379 final Uri data = intent.getData();
19381 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19382 ApplicationInfo aInfo = null;
19384 aInfo = AppGlobals.getPackageManager()
19385 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19386 } catch (RemoteException ignore) {}
19387 if (aInfo == null) {
19388 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19389 + " ssp=" + ssp + " data=" + data);
19390 return ActivityManager.BROADCAST_SUCCESS;
19392 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19393 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19394 new String[] {ssp}, userId);
19398 case Intent.ACTION_PACKAGE_ADDED:
19400 // Special case for adding a package: by default turn on compatibility mode.
19401 Uri data = intent.getData();
19403 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19404 final boolean replacing =
19405 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19406 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19409 ApplicationInfo ai = AppGlobals.getPackageManager().
19410 getApplicationInfo(ssp, 0, 0);
19411 mBatteryStatsService.notePackageInstalled(ssp,
19412 ai != null ? ai.versionCode : 0);
19413 } catch (RemoteException e) {
19418 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19420 Uri data = intent.getData();
19422 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19423 // Hide the "unsupported display" dialog if necessary.
19424 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19425 mUnsupportedDisplaySizeDialog.getPackageName())) {
19426 mUnsupportedDisplaySizeDialog.dismiss();
19427 mUnsupportedDisplaySizeDialog = null;
19429 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19433 case Intent.ACTION_TIMEZONE_CHANGED:
19434 // If this is the time zone changed action, queue up a message that will reset
19435 // the timezone of all currently running processes. This message will get
19436 // queued up before the broadcast happens.
19437 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19439 case Intent.ACTION_TIME_CHANGED:
19440 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19441 // the tri-state value it may contain and "unknown".
19442 // For convenience we re-use the Intent extra values.
19443 final int NO_EXTRA_VALUE_FOUND = -1;
19444 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19445 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19446 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19447 // Only send a message if the time preference is available.
19448 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19449 Message updateTimePreferenceMsg =
19450 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19451 timeFormatPreferenceMsgValue, 0);
19452 mHandler.sendMessage(updateTimePreferenceMsg);
19454 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19455 synchronized (stats) {
19456 stats.noteCurrentTimeChangedLocked();
19459 case Intent.ACTION_CLEAR_DNS_CACHE:
19460 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19462 case Proxy.PROXY_CHANGE_ACTION:
19463 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19464 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19466 case android.hardware.Camera.ACTION_NEW_PICTURE:
19467 case android.hardware.Camera.ACTION_NEW_VIDEO:
19468 // In N we just turned these off; in O we are turing them back on partly,
19469 // only for registered receivers. This will still address the main problem
19470 // (a spam of apps waking up when a picture is taken putting significant
19471 // memory pressure on the system at a bad point), while still allowing apps
19472 // that are already actively running to know about this happening.
19473 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19475 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19476 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19478 case "com.android.launcher.action.INSTALL_SHORTCUT":
19479 // As of O, we no longer support this broadcasts, even for pre-O apps.
19480 // Apps should now be using ShortcutManager.pinRequestShortcut().
19481 Log.w(TAG, "Broadcast " + action
19482 + " no longer supported. It will not be delivered.");
19483 return ActivityManager.BROADCAST_SUCCESS;
19486 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19487 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19488 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19489 final int uid = getUidFromIntent(intent);
19491 final UidRecord uidRec = mActiveUids.get(uid);
19492 if (uidRec != null) {
19493 uidRec.updateHasInternetPermission();
19499 // Add to the sticky list if requested.
19501 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19502 callingPid, callingUid)
19503 != PackageManager.PERMISSION_GRANTED) {
19504 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19505 + callingPid + ", uid=" + callingUid
19506 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19508 throw new SecurityException(msg);
19510 if (requiredPermissions != null && requiredPermissions.length > 0) {
19511 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19512 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19513 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19515 if (intent.getComponent() != null) {
19516 throw new SecurityException(
19517 "Sticky broadcasts can't target a specific component");
19519 // We use userId directly here, since the "all" target is maintained
19520 // as a separate set of sticky broadcasts.
19521 if (userId != UserHandle.USER_ALL) {
19522 // But first, if this is not a broadcast to all users, then
19523 // make sure it doesn't conflict with an existing broadcast to
19525 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19526 UserHandle.USER_ALL);
19527 if (stickies != null) {
19528 ArrayList<Intent> list = stickies.get(intent.getAction());
19529 if (list != null) {
19530 int N = list.size();
19532 for (i=0; i<N; i++) {
19533 if (intent.filterEquals(list.get(i))) {
19534 throw new IllegalArgumentException(
19535 "Sticky broadcast " + intent + " for user "
19536 + userId + " conflicts with existing global broadcast");
19542 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19543 if (stickies == null) {
19544 stickies = new ArrayMap<>();
19545 mStickyBroadcasts.put(userId, stickies);
19547 ArrayList<Intent> list = stickies.get(intent.getAction());
19548 if (list == null) {
19549 list = new ArrayList<>();
19550 stickies.put(intent.getAction(), list);
19552 final int stickiesCount = list.size();
19554 for (i = 0; i < stickiesCount; i++) {
19555 if (intent.filterEquals(list.get(i))) {
19556 // This sticky already exists, replace it.
19557 list.set(i, new Intent(intent));
19561 if (i >= stickiesCount) {
19562 list.add(new Intent(intent));
19567 if (userId == UserHandle.USER_ALL) {
19568 // Caller wants broadcast to go to all started users.
19569 users = mUserController.getStartedUserArrayLocked();
19571 // Caller wants broadcast to go to one specific user.
19572 users = new int[] {userId};
19575 // Figure out who all will receive this broadcast.
19576 List receivers = null;
19577 List<BroadcastFilter> registeredReceivers = null;
19578 // Need to resolve the intent to interested receivers...
19579 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19581 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19583 if (intent.getComponent() == null) {
19584 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19585 // Query one target user at a time, excluding shell-restricted users
19586 for (int i = 0; i < users.length; i++) {
19587 if (mUserController.hasUserRestriction(
19588 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19591 List<BroadcastFilter> registeredReceiversForUser =
19592 mReceiverResolver.queryIntent(intent,
19593 resolvedType, false /*defaultOnly*/, users[i]);
19594 if (registeredReceivers == null) {
19595 registeredReceivers = registeredReceiversForUser;
19596 } else if (registeredReceiversForUser != null) {
19597 registeredReceivers.addAll(registeredReceiversForUser);
19601 registeredReceivers = mReceiverResolver.queryIntent(intent,
19602 resolvedType, false /*defaultOnly*/, userId);
19606 final boolean replacePending =
19607 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19609 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19610 + " replacePending=" + replacePending);
19612 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19613 if (!ordered && NR > 0) {
19614 // If we are not serializing this broadcast, then send the
19615 // registered receivers separately so they don't wait for the
19616 // components to be launched.
19617 if (isCallerSystem) {
19618 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19619 isProtectedBroadcast, registeredReceivers);
19621 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19622 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19623 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19624 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19625 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19626 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19627 final boolean replaced = replacePending
19628 && (queue.replaceParallelBroadcastLocked(r) != null);
19629 // Note: We assume resultTo is null for non-ordered broadcasts.
19631 queue.enqueueParallelBroadcastLocked(r);
19632 queue.scheduleBroadcastsLocked();
19634 registeredReceivers = null;
19638 // Merge into one list.
19640 if (receivers != null) {
19641 // A special case for PACKAGE_ADDED: do not allow the package
19642 // being added to see this broadcast. This prevents them from
19643 // using this as a back door to get run as soon as they are
19644 // installed. Maybe in the future we want to have a special install
19645 // broadcast or such for apps, but we'd like to deliberately make
19647 String skipPackages[] = null;
19648 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19649 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19650 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19651 Uri data = intent.getData();
19652 if (data != null) {
19653 String pkgName = data.getSchemeSpecificPart();
19654 if (pkgName != null) {
19655 skipPackages = new String[] { pkgName };
19658 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19659 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19661 if (skipPackages != null && (skipPackages.length > 0)) {
19662 for (String skipPackage : skipPackages) {
19663 if (skipPackage != null) {
19664 int NT = receivers.size();
19665 for (int it=0; it<NT; it++) {
19666 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19667 if (curt.activityInfo.packageName.equals(skipPackage)) {
19668 receivers.remove(it);
19677 int NT = receivers != null ? receivers.size() : 0;
19679 ResolveInfo curt = null;
19680 BroadcastFilter curr = null;
19681 while (it < NT && ir < NR) {
19682 if (curt == null) {
19683 curt = (ResolveInfo)receivers.get(it);
19685 if (curr == null) {
19686 curr = registeredReceivers.get(ir);
19688 if (curr.getPriority() >= curt.priority) {
19689 // Insert this broadcast record into the final list.
19690 receivers.add(it, curr);
19696 // Skip to the next ResolveInfo in the final list.
19703 if (receivers == null) {
19704 receivers = new ArrayList();
19706 receivers.add(registeredReceivers.get(ir));
19710 if (isCallerSystem) {
19711 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19712 isProtectedBroadcast, receivers);
19715 if ((receivers != null && receivers.size() > 0)
19716 || resultTo != null) {
19717 BroadcastQueue queue = broadcastQueueForIntent(intent);
19718 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19719 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19720 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19721 resultData, resultExtras, ordered, sticky, false, userId);
19723 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19724 + ": prev had " + queue.mOrderedBroadcasts.size());
19725 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19726 "Enqueueing broadcast " + r.intent.getAction());
19728 final BroadcastRecord oldRecord =
19729 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19730 if (oldRecord != null) {
19731 // Replaced, fire the result-to receiver.
19732 if (oldRecord.resultTo != null) {
19733 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19735 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19737 Activity.RESULT_CANCELED, null, null,
19738 false, false, oldRecord.userId);
19739 } catch (RemoteException e) {
19740 Slog.w(TAG, "Failure ["
19741 + queue.mQueueName + "] sending broadcast result of "
19747 queue.enqueueOrderedBroadcastLocked(r);
19748 queue.scheduleBroadcastsLocked();
19751 // There was nobody interested in the broadcast, but we still want to record
19752 // that it happened.
19753 if (intent.getComponent() == null && intent.getPackage() == null
19754 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19755 // This was an implicit broadcast... let's record it for posterity.
19756 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19760 return ActivityManager.BROADCAST_SUCCESS;
19764 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19766 private int getUidFromIntent(Intent intent) {
19767 if (intent == null) {
19770 final Bundle intentExtras = intent.getExtras();
19771 return intent.hasExtra(Intent.EXTRA_UID)
19772 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19775 final void rotateBroadcastStatsIfNeededLocked() {
19776 final long now = SystemClock.elapsedRealtime();
19777 if (mCurBroadcastStats == null ||
19778 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19779 mLastBroadcastStats = mCurBroadcastStats;
19780 if (mLastBroadcastStats != null) {
19781 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19782 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19784 mCurBroadcastStats = new BroadcastStats();
19788 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19789 int skipCount, long dispatchTime) {
19790 rotateBroadcastStatsIfNeededLocked();
19791 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19794 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19795 rotateBroadcastStatsIfNeededLocked();
19796 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19799 final Intent verifyBroadcastLocked(Intent intent) {
19800 // Refuse possible leaked file descriptors
19801 if (intent != null && intent.hasFileDescriptors() == true) {
19802 throw new IllegalArgumentException("File descriptors passed in Intent");
19805 int flags = intent.getFlags();
19807 if (!mProcessesReady) {
19808 // if the caller really truly claims to know what they're doing, go
19809 // ahead and allow the broadcast without launching any receivers
19810 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19811 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19812 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19813 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19814 + " before boot completion");
19815 throw new IllegalStateException("Cannot broadcast before boot completed");
19819 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19820 throw new IllegalArgumentException(
19821 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19824 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19825 switch (Binder.getCallingUid()) {
19830 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19831 + Binder.getCallingUid());
19832 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19840 public final int broadcastIntent(IApplicationThread caller,
19841 Intent intent, String resolvedType, IIntentReceiver resultTo,
19842 int resultCode, String resultData, Bundle resultExtras,
19843 String[] requiredPermissions, int appOp, Bundle bOptions,
19844 boolean serialized, boolean sticky, int userId) {
19845 enforceNotIsolatedCaller("broadcastIntent");
19846 synchronized(this) {
19847 intent = verifyBroadcastLocked(intent);
19849 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19850 final int callingPid = Binder.getCallingPid();
19851 final int callingUid = Binder.getCallingUid();
19852 final long origId = Binder.clearCallingIdentity();
19853 int res = broadcastIntentLocked(callerApp,
19854 callerApp != null ? callerApp.info.packageName : null,
19855 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19856 requiredPermissions, appOp, bOptions, serialized, sticky,
19857 callingPid, callingUid, userId);
19858 Binder.restoreCallingIdentity(origId);
19864 int broadcastIntentInPackage(String packageName, int uid,
19865 Intent intent, String resolvedType, IIntentReceiver resultTo,
19866 int resultCode, String resultData, Bundle resultExtras,
19867 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19869 synchronized(this) {
19870 intent = verifyBroadcastLocked(intent);
19872 final long origId = Binder.clearCallingIdentity();
19873 String[] requiredPermissions = requiredPermission == null ? null
19874 : new String[] {requiredPermission};
19875 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19876 resultTo, resultCode, resultData, resultExtras,
19877 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19878 sticky, -1, uid, userId);
19879 Binder.restoreCallingIdentity(origId);
19884 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19885 // Refuse possible leaked file descriptors
19886 if (intent != null && intent.hasFileDescriptors() == true) {
19887 throw new IllegalArgumentException("File descriptors passed in Intent");
19890 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19891 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19893 synchronized(this) {
19894 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19895 != PackageManager.PERMISSION_GRANTED) {
19896 String msg = "Permission Denial: unbroadcastIntent() from pid="
19897 + Binder.getCallingPid()
19898 + ", uid=" + Binder.getCallingUid()
19899 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19901 throw new SecurityException(msg);
19903 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19904 if (stickies != null) {
19905 ArrayList<Intent> list = stickies.get(intent.getAction());
19906 if (list != null) {
19907 int N = list.size();
19909 for (i=0; i<N; i++) {
19910 if (intent.filterEquals(list.get(i))) {
19915 if (list.size() <= 0) {
19916 stickies.remove(intent.getAction());
19919 if (stickies.size() <= 0) {
19920 mStickyBroadcasts.remove(userId);
19926 void backgroundServicesFinishedLocked(int userId) {
19927 for (BroadcastQueue queue : mBroadcastQueues) {
19928 queue.backgroundServicesFinishedLocked(userId);
19932 public void finishReceiver(IBinder who, int resultCode, String resultData,
19933 Bundle resultExtras, boolean resultAbort, int flags) {
19934 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19936 // Refuse possible leaked file descriptors
19937 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19938 throw new IllegalArgumentException("File descriptors passed in Bundle");
19941 final long origId = Binder.clearCallingIdentity();
19943 boolean doNext = false;
19946 synchronized(this) {
19947 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19948 ? mFgBroadcastQueue : mBgBroadcastQueue;
19949 r = queue.getMatchingOrderedReceiver(who);
19951 doNext = r.queue.finishReceiverLocked(r, resultCode,
19952 resultData, resultExtras, resultAbort, true);
19957 r.queue.processNextBroadcast(false);
19959 trimApplications();
19961 Binder.restoreCallingIdentity(origId);
19965 // =========================================================
19967 // =========================================================
19969 public boolean startInstrumentation(ComponentName className,
19970 String profileFile, int flags, Bundle arguments,
19971 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19972 int userId, String abiOverride) {
19973 enforceNotIsolatedCaller("startInstrumentation");
19974 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19975 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19976 // Refuse possible leaked file descriptors
19977 if (arguments != null && arguments.hasFileDescriptors()) {
19978 throw new IllegalArgumentException("File descriptors passed in Bundle");
19981 synchronized(this) {
19982 InstrumentationInfo ii = null;
19983 ApplicationInfo ai = null;
19985 ii = mContext.getPackageManager().getInstrumentationInfo(
19986 className, STOCK_PM_FLAGS);
19987 ai = AppGlobals.getPackageManager().getApplicationInfo(
19988 ii.targetPackage, STOCK_PM_FLAGS, userId);
19989 } catch (PackageManager.NameNotFoundException e) {
19990 } catch (RemoteException e) {
19993 reportStartInstrumentationFailureLocked(watcher, className,
19994 "Unable to find instrumentation info for: " + className);
19998 reportStartInstrumentationFailureLocked(watcher, className,
19999 "Unable to find instrumentation target package: " + ii.targetPackage);
20002 if (!ai.hasCode()) {
20003 reportStartInstrumentationFailureLocked(watcher, className,
20004 "Instrumentation target has no code: " + ii.targetPackage);
20008 int match = mContext.getPackageManager().checkSignatures(
20009 ii.targetPackage, ii.packageName);
20010 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20011 String msg = "Permission Denial: starting instrumentation "
20012 + className + " from pid="
20013 + Binder.getCallingPid()
20014 + ", uid=" + Binder.getCallingPid()
20015 + " not allowed because package " + ii.packageName
20016 + " does not have a signature matching the target "
20017 + ii.targetPackage;
20018 reportStartInstrumentationFailureLocked(watcher, className, msg);
20019 throw new SecurityException(msg);
20022 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20023 activeInstr.mClass = className;
20024 String defProcess = ai.processName;;
20025 if (ii.targetProcesses == null) {
20026 activeInstr.mTargetProcesses = new String[]{ai.processName};
20027 } else if (ii.targetProcesses.equals("*")) {
20028 activeInstr.mTargetProcesses = new String[0];
20030 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20031 defProcess = activeInstr.mTargetProcesses[0];
20033 activeInstr.mTargetInfo = ai;
20034 activeInstr.mProfileFile = profileFile;
20035 activeInstr.mArguments = arguments;
20036 activeInstr.mWatcher = watcher;
20037 activeInstr.mUiAutomationConnection = uiAutomationConnection;
20038 activeInstr.mResultClass = className;
20040 final long origId = Binder.clearCallingIdentity();
20041 // Instrumentation can kill and relaunch even persistent processes
20042 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20044 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20045 app.instr = activeInstr;
20046 activeInstr.mFinished = false;
20047 activeInstr.mRunningProcesses.add(app);
20048 if (!mActiveInstrumentation.contains(activeInstr)) {
20049 mActiveInstrumentation.add(activeInstr);
20051 Binder.restoreCallingIdentity(origId);
20058 * Report errors that occur while attempting to start Instrumentation. Always writes the
20059 * error to the logs, but if somebody is watching, send the report there too. This enables
20060 * the "am" command to report errors with more information.
20062 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
20063 * @param cn The component name of the instrumentation.
20064 * @param report The error report.
20066 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20067 ComponentName cn, String report) {
20068 Slog.w(TAG, report);
20069 if (watcher != null) {
20070 Bundle results = new Bundle();
20071 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20072 results.putString("Error", report);
20073 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20077 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20078 if (app.instr == null) {
20079 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20083 if (!app.instr.mFinished && results != null) {
20084 if (app.instr.mCurResults == null) {
20085 app.instr.mCurResults = new Bundle(results);
20087 app.instr.mCurResults.putAll(results);
20092 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20093 int userId = UserHandle.getCallingUserId();
20094 // Refuse possible leaked file descriptors
20095 if (results != null && results.hasFileDescriptors()) {
20096 throw new IllegalArgumentException("File descriptors passed in Intent");
20099 synchronized(this) {
20100 ProcessRecord app = getRecordForAppLocked(target);
20102 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20105 final long origId = Binder.clearCallingIdentity();
20106 addInstrumentationResultsLocked(app, results);
20107 Binder.restoreCallingIdentity(origId);
20111 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20112 if (app.instr == null) {
20113 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20117 if (!app.instr.mFinished) {
20118 if (app.instr.mWatcher != null) {
20119 Bundle finalResults = app.instr.mCurResults;
20120 if (finalResults != null) {
20121 if (app.instr.mCurResults != null && results != null) {
20122 finalResults.putAll(results);
20125 finalResults = results;
20127 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20128 app.instr.mClass, resultCode, finalResults);
20131 // Can't call out of the system process with a lock held, so post a message.
20132 if (app.instr.mUiAutomationConnection != null) {
20133 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20134 app.instr.mUiAutomationConnection).sendToTarget();
20136 app.instr.mFinished = true;
20139 app.instr.removeProcess(app);
20142 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20146 public void finishInstrumentation(IApplicationThread target,
20147 int resultCode, Bundle results) {
20148 int userId = UserHandle.getCallingUserId();
20149 // Refuse possible leaked file descriptors
20150 if (results != null && results.hasFileDescriptors()) {
20151 throw new IllegalArgumentException("File descriptors passed in Intent");
20154 synchronized(this) {
20155 ProcessRecord app = getRecordForAppLocked(target);
20157 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20160 final long origId = Binder.clearCallingIdentity();
20161 finishInstrumentationLocked(app, resultCode, results);
20162 Binder.restoreCallingIdentity(origId);
20166 // =========================================================
20168 // =========================================================
20170 public ConfigurationInfo getDeviceConfigurationInfo() {
20171 ConfigurationInfo config = new ConfigurationInfo();
20172 synchronized (this) {
20173 final Configuration globalConfig = getGlobalConfiguration();
20174 config.reqTouchScreen = globalConfig.touchscreen;
20175 config.reqKeyboardType = globalConfig.keyboard;
20176 config.reqNavigation = globalConfig.navigation;
20177 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20178 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20179 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20181 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20182 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20183 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20185 config.reqGlEsVersion = GL_ES_VERSION;
20190 ActivityStack getFocusedStack() {
20191 return mStackSupervisor.getFocusedStack();
20195 public int getFocusedStackId() throws RemoteException {
20196 ActivityStack focusedStack = getFocusedStack();
20197 if (focusedStack != null) {
20198 return focusedStack.getStackId();
20203 public Configuration getConfiguration() {
20205 synchronized(this) {
20206 ci = new Configuration(getGlobalConfiguration());
20207 ci.userSetLocale = false;
20213 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20214 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20215 synchronized (this) {
20216 mSuppressResizeConfigChanges = suppress;
20221 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20222 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20223 * activity and clearing the task at the same time.
20226 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20227 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20228 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20229 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20231 synchronized (this) {
20232 final long origId = Binder.clearCallingIdentity();
20234 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20236 Binder.restoreCallingIdentity(origId);
20242 public void updatePersistentConfiguration(Configuration values) {
20243 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20244 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20245 if (values == null) {
20246 throw new NullPointerException("Configuration must not be null");
20249 int userId = UserHandle.getCallingUserId();
20251 synchronized(this) {
20252 updatePersistentConfigurationLocked(values, userId);
20256 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20257 final long origId = Binder.clearCallingIdentity();
20259 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20261 Binder.restoreCallingIdentity(origId);
20265 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20266 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20267 FONT_SCALE, 1.0f, userId);
20269 synchronized (this) {
20270 if (getGlobalConfiguration().fontScale == scaleFactor) {
20274 final Configuration configuration
20275 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20276 configuration.fontScale = scaleFactor;
20277 updatePersistentConfigurationLocked(configuration, userId);
20281 private void enforceWriteSettingsPermission(String func) {
20282 int uid = Binder.getCallingUid();
20283 if (uid == ROOT_UID) {
20287 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20288 Settings.getPackageNameForUid(mContext, uid), false)) {
20292 String msg = "Permission Denial: " + func + " from pid="
20293 + Binder.getCallingPid()
20295 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20297 throw new SecurityException(msg);
20301 public boolean updateConfiguration(Configuration values) {
20302 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20304 synchronized(this) {
20305 if (values == null && mWindowManager != null) {
20306 // sentinel: fetch the current configuration from the window manager
20307 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20310 if (mWindowManager != null) {
20311 // Update OOM levels based on display size.
20312 mProcessList.applyDisplaySize(mWindowManager);
20315 final long origId = Binder.clearCallingIdentity();
20317 if (values != null) {
20318 Settings.System.clearConfiguration(values);
20320 updateConfigurationLocked(values, null, false, false /* persistent */,
20321 UserHandle.USER_NULL, false /* deferResume */,
20322 mTmpUpdateConfigurationResult);
20323 return mTmpUpdateConfigurationResult.changes != 0;
20325 Binder.restoreCallingIdentity(origId);
20330 void updateUserConfigurationLocked() {
20331 final Configuration configuration = new Configuration(getGlobalConfiguration());
20332 final int currentUserId = mUserController.getCurrentUserIdLocked();
20333 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20334 currentUserId, Settings.System.canWrite(mContext));
20335 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20336 false /* persistent */, currentUserId, false /* deferResume */);
20339 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20340 boolean initLocale) {
20341 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20344 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20345 boolean initLocale, boolean deferResume) {
20346 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20347 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20348 UserHandle.USER_NULL, deferResume);
20351 // To cache the list of supported system locales
20352 private String[] mSupportedSystemLocales = null;
20354 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20355 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20356 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20357 deferResume, null /* result */);
20361 * Do either or both things: (1) change the current configuration, and (2)
20362 * make sure the given activity is running with the (now) current
20363 * configuration. Returns true if the activity has been left running, or
20364 * false if <var>starting</var> is being destroyed to match the new
20367 * @param userId is only used when persistent parameter is set to true to persist configuration
20368 * for that particular user
20370 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20371 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20372 UpdateConfigurationResult result) {
20374 boolean kept = true;
20376 if (mWindowManager != null) {
20377 mWindowManager.deferSurfaceLayout();
20380 if (values != null) {
20381 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20385 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20387 if (mWindowManager != null) {
20388 mWindowManager.continueSurfaceLayout();
20392 if (result != null) {
20393 result.changes = changes;
20394 result.activityRelaunched = !kept;
20399 /** Update default (global) configuration and notify listeners about changes. */
20400 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20401 boolean persistent, int userId, boolean deferResume) {
20402 mTempConfig.setTo(getGlobalConfiguration());
20403 final int changes = mTempConfig.updateFrom(values);
20404 if (changes == 0) {
20405 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20406 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20407 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20408 // (even if there are no actual changes) to unfreeze the window.
20409 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20413 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20414 "Updating global configuration to: " + values);
20416 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20418 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20419 final LocaleList locales = values.getLocales();
20420 int bestLocaleIndex = 0;
20421 if (locales.size() > 1) {
20422 if (mSupportedSystemLocales == null) {
20423 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20425 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20427 SystemProperties.set("persist.sys.locale",
20428 locales.get(bestLocaleIndex).toLanguageTag());
20429 LocaleList.setDefault(locales, bestLocaleIndex);
20430 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20431 locales.get(bestLocaleIndex)));
20434 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20435 mTempConfig.seq = mConfigurationSeq;
20437 // Update stored global config and notify everyone about the change.
20438 mStackSupervisor.onConfigurationChanged(mTempConfig);
20440 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20441 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20442 mUsageStatsService.reportConfigurationChange(mTempConfig,
20443 mUserController.getCurrentUserIdLocked());
20445 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20446 mShowDialogs = shouldShowDialogs(mTempConfig);
20448 AttributeCache ac = AttributeCache.instance();
20450 ac.updateConfiguration(mTempConfig);
20453 // Make sure all resources in our process are updated right now, so that anyone who is going
20454 // to retrieve resource values after we return will be sure to get the new ones. This is
20455 // especially important during boot, where the first config change needs to guarantee all
20456 // resources have that config before following boot code is executed.
20457 mSystemThread.applyConfigurationToResources(mTempConfig);
20459 // We need another copy of global config because we're scheduling some calls instead of
20460 // running them in place. We need to be sure that object we send will be handled unchanged.
20461 final Configuration configCopy = new Configuration(mTempConfig);
20462 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20463 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20464 msg.obj = configCopy;
20466 mHandler.sendMessage(msg);
20469 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20470 ProcessRecord app = mLruProcesses.get(i);
20472 if (app.thread != null) {
20473 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20474 + app.processName + " new config " + configCopy);
20475 app.thread.scheduleConfigurationChanged(configCopy);
20477 } catch (Exception e) {
20481 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20482 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20483 | Intent.FLAG_RECEIVER_FOREGROUND
20484 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20485 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20486 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20487 UserHandle.USER_ALL);
20488 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20489 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20490 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20491 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20492 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20493 if (initLocale || !mProcessesReady) {
20494 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20496 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20497 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20498 UserHandle.USER_ALL);
20501 // Override configuration of the default display duplicates global config, so we need to
20502 // update it also. This will also notify WindowManager about changes.
20503 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20510 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20511 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20513 synchronized (this) {
20514 // Check if display is initialized in AM.
20515 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20516 // Call might come when display is not yet added or has already been removed.
20517 if (DEBUG_CONFIGURATION) {
20518 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20524 if (values == null && mWindowManager != null) {
20525 // sentinel: fetch the current configuration from the window manager
20526 values = mWindowManager.computeNewConfiguration(displayId);
20529 if (mWindowManager != null) {
20530 // Update OOM levels based on display size.
20531 mProcessList.applyDisplaySize(mWindowManager);
20534 final long origId = Binder.clearCallingIdentity();
20536 if (values != null) {
20537 Settings.System.clearConfiguration(values);
20539 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20540 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20541 return mTmpUpdateConfigurationResult.changes != 0;
20543 Binder.restoreCallingIdentity(origId);
20548 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20549 boolean deferResume, int displayId) {
20550 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20551 displayId, null /* result */);
20555 * Updates override configuration specific for the selected display. If no config is provided,
20556 * new one will be computed in WM based on current display info.
20558 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20559 ActivityRecord starting, boolean deferResume, int displayId,
20560 UpdateConfigurationResult result) {
20562 boolean kept = true;
20564 if (mWindowManager != null) {
20565 mWindowManager.deferSurfaceLayout();
20568 if (values != null) {
20569 if (displayId == DEFAULT_DISPLAY) {
20570 // Override configuration of the default display duplicates global config, so
20571 // we're calling global config update instead for default display. It will also
20572 // apply the correct override config.
20573 changes = updateGlobalConfiguration(values, false /* initLocale */,
20574 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20576 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20580 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20582 if (mWindowManager != null) {
20583 mWindowManager.continueSurfaceLayout();
20587 if (result != null) {
20588 result.changes = changes;
20589 result.activityRelaunched = !kept;
20594 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20596 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20597 final int changes = mTempConfig.updateFrom(values);
20598 if (changes != 0) {
20599 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20600 + mTempConfig + " for displayId=" + displayId);
20601 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20603 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20604 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20605 // Reset the unsupported display size dialog.
20606 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20608 killAllBackgroundProcessesExcept(N,
20609 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20613 // Update the configuration with WM first and check if any of the stacks need to be resized
20614 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20615 // necessary. This way we don't need to relaunch again afterwards in
20616 // ensureActivityConfigurationLocked().
20617 if (mWindowManager != null) {
20618 final int[] resizedStacks =
20619 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20620 if (resizedStacks != null) {
20621 for (int stackId : resizedStacks) {
20622 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20630 /** Applies latest configuration and/or visibility updates if needed. */
20631 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20632 boolean kept = true;
20633 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20634 // mainStack is null during startup.
20635 if (mainStack != null) {
20636 if (changes != 0 && starting == null) {
20637 // If the configuration changed, and the caller is not already
20638 // in the process of starting an activity, then find the top
20639 // activity to check if its configuration needs to change.
20640 starting = mainStack.topRunningActivityLocked();
20643 if (starting != null) {
20644 kept = starting.ensureActivityConfigurationLocked(changes,
20645 false /* preserveWindow */);
20646 // And we need to make sure at this point that all other activities
20647 // are made visible with the correct configuration.
20648 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20649 !PRESERVE_WINDOWS);
20656 /** Helper method that requests bounds from WM and applies them to stack. */
20657 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20658 final Rect newStackBounds = new Rect();
20659 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20660 mStackSupervisor.resizeStackLocked(
20661 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20662 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20663 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20667 * Decide based on the configuration whether we should show the ANR,
20668 * crash, etc dialogs. The idea is that if there is no affordance to
20669 * press the on-screen buttons, or the user experience would be more
20670 * greatly impacted than the crash itself, we shouldn't show the dialog.
20672 * A thought: SystemUI might also want to get told about this, the Power
20673 * dialog / global actions also might want different behaviors.
20675 private static boolean shouldShowDialogs(Configuration config) {
20676 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20677 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20678 && config.navigation == Configuration.NAVIGATION_NONAV);
20679 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20680 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20681 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20682 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20683 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20684 return inputMethodExists && uiModeSupportsDialogs;
20688 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20689 synchronized (this) {
20690 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20691 if (srec != null) {
20692 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20698 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20699 Intent resultData) {
20701 synchronized (this) {
20702 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20704 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20710 public int getLaunchedFromUid(IBinder activityToken) {
20711 ActivityRecord srec;
20712 synchronized (this) {
20713 srec = ActivityRecord.forTokenLocked(activityToken);
20715 if (srec == null) {
20718 return srec.launchedFromUid;
20721 public String getLaunchedFromPackage(IBinder activityToken) {
20722 ActivityRecord srec;
20723 synchronized (this) {
20724 srec = ActivityRecord.forTokenLocked(activityToken);
20726 if (srec == null) {
20729 return srec.launchedFromPackage;
20732 // =========================================================
20733 // LIFETIME MANAGEMENT
20734 // =========================================================
20736 // Returns whether the app is receiving broadcast.
20737 // If receiving, fetch all broadcast queues which the app is
20738 // the current [or imminent] receiver on.
20739 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20740 ArraySet<BroadcastQueue> receivingQueues) {
20741 if (!app.curReceivers.isEmpty()) {
20742 for (BroadcastRecord r : app.curReceivers) {
20743 receivingQueues.add(r.queue);
20748 // It's not the current receiver, but it might be starting up to become one
20749 for (BroadcastQueue queue : mBroadcastQueues) {
20750 final BroadcastRecord r = queue.mPendingBroadcast;
20751 if (r != null && r.curApp == app) {
20752 // found it; report which queue it's in
20753 receivingQueues.add(queue);
20757 return !receivingQueues.isEmpty();
20760 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20761 int targetUid, ComponentName targetComponent, String targetProcess) {
20762 if (!mTrackingAssociations) {
20765 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20766 = mAssociations.get(targetUid);
20767 if (components == null) {
20768 components = new ArrayMap<>();
20769 mAssociations.put(targetUid, components);
20771 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20772 if (sourceUids == null) {
20773 sourceUids = new SparseArray<>();
20774 components.put(targetComponent, sourceUids);
20776 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20777 if (sourceProcesses == null) {
20778 sourceProcesses = new ArrayMap<>();
20779 sourceUids.put(sourceUid, sourceProcesses);
20781 Association ass = sourceProcesses.get(sourceProcess);
20783 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20785 sourceProcesses.put(sourceProcess, ass);
20789 if (ass.mNesting == 1) {
20790 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20791 ass.mLastState = sourceState;
20796 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20797 ComponentName targetComponent) {
20798 if (!mTrackingAssociations) {
20801 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20802 = mAssociations.get(targetUid);
20803 if (components == null) {
20806 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20807 if (sourceUids == null) {
20810 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20811 if (sourceProcesses == null) {
20814 Association ass = sourceProcesses.get(sourceProcess);
20815 if (ass == null || ass.mNesting <= 0) {
20819 if (ass.mNesting == 0) {
20820 long uptime = SystemClock.uptimeMillis();
20821 ass.mTime += uptime - ass.mStartTime;
20822 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20823 += uptime - ass.mLastStateUptime;
20824 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20828 private void noteUidProcessState(final int uid, final int state) {
20829 mBatteryStatsService.noteUidProcessState(uid, state);
20830 if (mTrackingAssociations) {
20831 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20832 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20833 = mAssociations.valueAt(i1);
20834 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20835 SparseArray<ArrayMap<String, Association>> sourceUids
20836 = targetComponents.valueAt(i2);
20837 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20838 if (sourceProcesses != null) {
20839 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20840 Association ass = sourceProcesses.valueAt(i4);
20841 if (ass.mNesting >= 1) {
20842 // currently associated
20843 long uptime = SystemClock.uptimeMillis();
20844 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20845 += uptime - ass.mLastStateUptime;
20846 ass.mLastState = state;
20847 ass.mLastStateUptime = uptime;
20856 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20857 boolean doingAll, long now) {
20858 if (mAdjSeq == app.adjSeq) {
20859 // This adjustment has already been computed.
20860 return app.curRawAdj;
20863 if (app.thread == null) {
20864 app.adjSeq = mAdjSeq;
20865 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20866 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20867 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20870 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20871 app.adjSource = null;
20872 app.adjTarget = null;
20874 app.cached = false;
20876 final int activitiesSize = app.activities.size();
20878 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20879 // The max adjustment doesn't allow this app to be anything
20880 // below foreground, so it is not worth doing work for it.
20881 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20882 app.adjType = "fixed";
20883 app.adjSeq = mAdjSeq;
20884 app.curRawAdj = app.maxAdj;
20885 app.foregroundActivities = false;
20886 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20887 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20888 // System processes can do UI, and when they do we want to have
20889 // them trim their memory after the user leaves the UI. To
20890 // facilitate this, here we need to determine whether or not it
20891 // is currently showing UI.
20892 app.systemNoUi = true;
20893 if (app == TOP_APP) {
20894 app.systemNoUi = false;
20895 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20896 app.adjType = "pers-top-activity";
20897 } else if (app.hasTopUi) {
20898 app.systemNoUi = false;
20899 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20900 app.adjType = "pers-top-ui";
20901 } else if (activitiesSize > 0) {
20902 for (int j = 0; j < activitiesSize; j++) {
20903 final ActivityRecord r = app.activities.get(j);
20905 app.systemNoUi = false;
20909 if (!app.systemNoUi) {
20910 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20912 return (app.curAdj=app.maxAdj);
20915 app.systemNoUi = false;
20917 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20919 // Determine the importance of the process, starting with most
20920 // important to least, and assign an appropriate OOM adjustment.
20924 boolean foregroundActivities = false;
20925 mTmpBroadcastQueue.clear();
20926 if (app == TOP_APP) {
20927 // The last app on the list is the foreground app.
20928 adj = ProcessList.FOREGROUND_APP_ADJ;
20929 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20930 app.adjType = "top-activity";
20931 foregroundActivities = true;
20932 procState = PROCESS_STATE_CUR_TOP;
20933 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20934 } else if (app.instr != null) {
20935 // Don't want to kill running instrumentation.
20936 adj = ProcessList.FOREGROUND_APP_ADJ;
20937 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20938 app.adjType = "instrumentation";
20939 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20940 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20941 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20942 // An app that is currently receiving a broadcast also
20943 // counts as being in the foreground for OOM killer purposes.
20944 // It's placed in a sched group based on the nature of the
20945 // broadcast as reflected by which queue it's active in.
20946 adj = ProcessList.FOREGROUND_APP_ADJ;
20947 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20948 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20949 app.adjType = "broadcast";
20950 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20951 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20952 } else if (app.executingServices.size() > 0) {
20953 // An app that is currently executing a service callback also
20954 // counts as being in the foreground.
20955 adj = ProcessList.FOREGROUND_APP_ADJ;
20956 schedGroup = app.execServicesFg ?
20957 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20958 app.adjType = "exec-service";
20959 procState = ActivityManager.PROCESS_STATE_SERVICE;
20960 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20961 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20963 // As far as we know the process is empty. We may change our mind later.
20964 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20965 // At this point we don't actually know the adjustment. Use the cached adj
20966 // value that the caller wants us to.
20968 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20971 app.adjType = "cch-empty";
20972 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20975 // Examine all activities if not already foreground.
20976 if (!foregroundActivities && activitiesSize > 0) {
20977 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20978 for (int j = 0; j < activitiesSize; j++) {
20979 final ActivityRecord r = app.activities.get(j);
20980 if (r.app != app) {
20981 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20982 + " instead of expected " + app);
20983 if (r.app == null || (r.app.uid == app.uid)) {
20984 // Only fix things up when they look sane
20991 // App has a visible activity; only upgrade adjustment.
20992 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20993 adj = ProcessList.VISIBLE_APP_ADJ;
20994 app.adjType = "vis-activity";
20995 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20997 if (procState > PROCESS_STATE_CUR_TOP) {
20998 procState = PROCESS_STATE_CUR_TOP;
20999 app.adjType = "vis-activity";
21000 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
21002 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21003 app.cached = false;
21005 foregroundActivities = true;
21006 final TaskRecord task = r.getTask();
21007 if (task != null && minLayer > 0) {
21008 final int layer = task.mLayerRank;
21009 if (layer >= 0 && minLayer > layer) {
21014 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21015 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21016 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21017 app.adjType = "pause-activity";
21018 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21020 if (procState > PROCESS_STATE_CUR_TOP) {
21021 procState = PROCESS_STATE_CUR_TOP;
21022 app.adjType = "pause-activity";
21023 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21025 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21026 app.cached = false;
21028 foregroundActivities = true;
21029 } else if (r.state == ActivityState.STOPPING) {
21030 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21031 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21032 app.adjType = "stop-activity";
21033 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21035 // For the process state, we will at this point consider the
21036 // process to be cached. It will be cached either as an activity
21037 // or empty depending on whether the activity is finishing. We do
21038 // this so that we can treat the process as cached for purposes of
21039 // memory trimming (determing current memory level, trim command to
21040 // send to process) since there can be an arbitrary number of stopping
21041 // processes and they should soon all go into the cached state.
21042 if (!r.finishing) {
21043 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21044 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21045 app.adjType = "stop-activity";
21046 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21049 app.cached = false;
21051 foregroundActivities = true;
21053 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21054 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21055 app.adjType = "cch-act";
21056 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21060 if (adj == ProcessList.VISIBLE_APP_ADJ) {
21065 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21066 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21067 if (app.foregroundServices) {
21068 // The user is aware of this app, so make it visible.
21069 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21070 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21071 app.cached = false;
21072 app.adjType = "fg-service";
21073 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21074 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21075 } else if (app.hasOverlayUi) {
21076 // The process is display an overlay UI.
21077 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21078 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21079 app.cached = false;
21080 app.adjType = "has-overlay-ui";
21081 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21082 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21086 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21087 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21088 if (app.forcingToImportant != null) {
21089 // This is currently used for toasts... they are not interactive, and
21090 // we don't want them to cause the app to become fully foreground (and
21091 // thus out of background check), so we yes the best background level we can.
21092 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21093 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21094 app.cached = false;
21095 app.adjType = "force-imp";
21096 app.adjSource = app.forcingToImportant;
21097 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21098 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21102 if (app == mHeavyWeightProcess) {
21103 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21104 // We don't want to kill the current heavy-weight process.
21105 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21106 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21107 app.cached = false;
21108 app.adjType = "heavy";
21109 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21111 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21112 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21113 app.adjType = "heavy";
21114 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21118 if (app == mHomeProcess) {
21119 if (adj > ProcessList.HOME_APP_ADJ) {
21120 // This process is hosting what we currently consider to be the
21121 // home app, so we don't want to let it go into the background.
21122 adj = ProcessList.HOME_APP_ADJ;
21123 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21124 app.cached = false;
21125 app.adjType = "home";
21126 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21128 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21129 procState = ActivityManager.PROCESS_STATE_HOME;
21130 app.adjType = "home";
21131 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21135 if (app == mPreviousProcess && app.activities.size() > 0) {
21136 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21137 // This was the previous process that showed UI to the user.
21138 // We want to try to keep it around more aggressively, to give
21139 // a good experience around switching between two apps.
21140 adj = ProcessList.PREVIOUS_APP_ADJ;
21141 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21142 app.cached = false;
21143 app.adjType = "previous";
21144 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21146 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21147 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21148 app.adjType = "previous";
21149 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21153 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21154 + " reason=" + app.adjType);
21156 // By default, we use the computed adjustment. It may be changed if
21157 // there are applications dependent on our services or providers, but
21158 // this gives us a baseline and makes sure we don't get into an
21159 // infinite recursion.
21160 app.adjSeq = mAdjSeq;
21161 app.curRawAdj = adj;
21162 app.hasStartedServices = false;
21164 if (mBackupTarget != null && app == mBackupTarget.app) {
21165 // If possible we want to avoid killing apps while they're being backed up
21166 if (adj > ProcessList.BACKUP_APP_ADJ) {
21167 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21168 adj = ProcessList.BACKUP_APP_ADJ;
21169 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21170 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21172 app.adjType = "backup";
21173 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21174 app.cached = false;
21176 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21177 procState = ActivityManager.PROCESS_STATE_BACKUP;
21178 app.adjType = "backup";
21179 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21183 boolean mayBeTop = false;
21184 String mayBeTopType = null;
21185 Object mayBeTopSource = null;
21186 Object mayBeTopTarget = null;
21188 for (int is = app.services.size()-1;
21189 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21190 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21191 || procState > ActivityManager.PROCESS_STATE_TOP);
21193 ServiceRecord s = app.services.valueAt(is);
21194 if (s.startRequested) {
21195 app.hasStartedServices = true;
21196 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21197 procState = ActivityManager.PROCESS_STATE_SERVICE;
21198 app.adjType = "started-services";
21199 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21201 if (app.hasShownUi && app != mHomeProcess) {
21202 // If this process has shown some UI, let it immediately
21203 // go to the LRU list because it may be pretty heavy with
21204 // UI stuff. We'll tag it with a label just to help
21205 // debug and understand what is going on.
21206 if (adj > ProcessList.SERVICE_ADJ) {
21207 app.adjType = "cch-started-ui-services";
21210 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21211 // This service has seen some activity within
21212 // recent memory, so we will keep its process ahead
21213 // of the background processes.
21214 if (adj > ProcessList.SERVICE_ADJ) {
21215 adj = ProcessList.SERVICE_ADJ;
21216 app.adjType = "started-services";
21217 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21218 app.cached = false;
21221 // If we have let the service slide into the background
21222 // state, still have some text describing what it is doing
21223 // even though the service no longer has an impact.
21224 if (adj > ProcessList.SERVICE_ADJ) {
21225 app.adjType = "cch-started-services";
21230 for (int conni = s.connections.size()-1;
21231 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21232 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21233 || procState > ActivityManager.PROCESS_STATE_TOP);
21235 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21237 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21238 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21239 || procState > ActivityManager.PROCESS_STATE_TOP);
21241 // XXX should compute this based on the max of
21242 // all connected clients.
21243 ConnectionRecord cr = clist.get(i);
21244 if (cr.binding.client == app) {
21245 // Binding to ourself is not interesting.
21249 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21250 ProcessRecord client = cr.binding.client;
21251 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21252 TOP_APP, doingAll, now);
21253 int clientProcState = client.curProcState;
21254 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21255 // If the other app is cached for any reason, for purposes here
21256 // we are going to consider it empty. The specific cached state
21257 // doesn't propagate except under certain conditions.
21258 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21260 String adjType = null;
21261 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21262 // Not doing bind OOM management, so treat
21263 // this guy more like a started service.
21264 if (app.hasShownUi && app != mHomeProcess) {
21265 // If this process has shown some UI, let it immediately
21266 // go to the LRU list because it may be pretty heavy with
21267 // UI stuff. We'll tag it with a label just to help
21268 // debug and understand what is going on.
21269 if (adj > clientAdj) {
21270 adjType = "cch-bound-ui-services";
21272 app.cached = false;
21274 clientProcState = procState;
21276 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21277 // This service has not seen activity within
21278 // recent memory, so allow it to drop to the
21279 // LRU list if there is no other reason to keep
21280 // it around. We'll also tag it with a label just
21281 // to help debug and undertand what is going on.
21282 if (adj > clientAdj) {
21283 adjType = "cch-bound-services";
21289 if (adj > clientAdj) {
21290 // If this process has recently shown UI, and
21291 // the process that is binding to it is less
21292 // important than being visible, then we don't
21293 // care about the binding as much as we care
21294 // about letting this process get into the LRU
21295 // list to be killed and restarted if needed for
21297 if (app.hasShownUi && app != mHomeProcess
21298 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21299 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21300 adjType = "cch-bound-ui-services";
21304 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21305 |Context.BIND_IMPORTANT)) != 0) {
21306 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21307 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21308 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21309 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21310 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21311 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21312 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21313 newAdj = clientAdj;
21315 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21316 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21321 if (!client.cached) {
21322 app.cached = false;
21324 if (adj > newAdj) {
21326 adjType = "service";
21330 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21331 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21332 // This will treat important bound services identically to
21333 // the top app, which may behave differently than generic
21334 // foreground work.
21335 if (client.curSchedGroup > schedGroup) {
21336 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21337 schedGroup = client.curSchedGroup;
21339 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21342 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21343 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21344 // Special handling of clients who are in the top state.
21345 // We *may* want to consider this process to be in the
21346 // top state as well, but only if there is not another
21347 // reason for it to be running. Being on the top is a
21348 // special state, meaning you are specifically running
21349 // for the current top app. If the process is already
21350 // running in the background for some other reason, it
21351 // is more important to continue considering it to be
21352 // in the background state.
21354 mayBeTopType = "service";
21355 mayBeTopSource = cr.binding.client;
21356 mayBeTopTarget = s.name;
21357 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21359 // Special handling for above-top states (persistent
21360 // processes). These should not bring the current process
21361 // into the top state, since they are not on top. Instead
21362 // give them the best state after that.
21363 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21365 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21366 } else if (mWakefulness
21367 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21368 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21371 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21374 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21378 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21379 if (clientProcState <
21380 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21382 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21385 if (clientProcState <
21386 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21388 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21391 if (procState > clientProcState) {
21392 procState = clientProcState;
21393 if (adjType == null) {
21394 adjType = "service";
21397 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21398 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21399 app.pendingUiClean = true;
21401 if (adjType != null) {
21402 app.adjType = adjType;
21403 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21404 .REASON_SERVICE_IN_USE;
21405 app.adjSource = cr.binding.client;
21406 app.adjSourceProcState = clientProcState;
21407 app.adjTarget = s.name;
21408 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21409 + ": " + app + ", due to " + cr.binding.client
21410 + " adj=" + adj + " procState=" + procState);
21413 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21414 app.treatLikeActivity = true;
21416 final ActivityRecord a = cr.activity;
21417 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21418 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21419 (a.visible || a.state == ActivityState.RESUMED ||
21420 a.state == ActivityState.PAUSING)) {
21421 adj = ProcessList.FOREGROUND_APP_ADJ;
21422 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21423 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21424 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21426 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21429 app.cached = false;
21430 app.adjType = "service";
21431 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21432 .REASON_SERVICE_IN_USE;
21434 app.adjSourceProcState = procState;
21435 app.adjTarget = s.name;
21436 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21444 for (int provi = app.pubProviders.size()-1;
21445 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21446 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21447 || procState > ActivityManager.PROCESS_STATE_TOP);
21449 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21450 for (int i = cpr.connections.size()-1;
21451 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21452 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21453 || procState > ActivityManager.PROCESS_STATE_TOP);
21455 ContentProviderConnection conn = cpr.connections.get(i);
21456 ProcessRecord client = conn.client;
21457 if (client == app) {
21458 // Being our own client is not interesting.
21461 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21462 int clientProcState = client.curProcState;
21463 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21464 // If the other app is cached for any reason, for purposes here
21465 // we are going to consider it empty.
21466 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21468 String adjType = null;
21469 if (adj > clientAdj) {
21470 if (app.hasShownUi && app != mHomeProcess
21471 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21472 adjType = "cch-ui-provider";
21474 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21475 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21476 adjType = "provider";
21478 app.cached &= client.cached;
21480 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21481 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21482 // Special handling of clients who are in the top state.
21483 // We *may* want to consider this process to be in the
21484 // top state as well, but only if there is not another
21485 // reason for it to be running. Being on the top is a
21486 // special state, meaning you are specifically running
21487 // for the current top app. If the process is already
21488 // running in the background for some other reason, it
21489 // is more important to continue considering it to be
21490 // in the background state.
21492 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21493 mayBeTopType = adjType = "provider-top";
21494 mayBeTopSource = client;
21495 mayBeTopTarget = cpr.name;
21497 // Special handling for above-top states (persistent
21498 // processes). These should not bring the current process
21499 // into the top state, since they are not on top. Instead
21500 // give them the best state after that.
21502 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21503 if (adjType == null) {
21504 adjType = "provider";
21508 if (procState > clientProcState) {
21509 procState = clientProcState;
21511 if (client.curSchedGroup > schedGroup) {
21512 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21514 if (adjType != null) {
21515 app.adjType = adjType;
21516 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21517 .REASON_PROVIDER_IN_USE;
21518 app.adjSource = client;
21519 app.adjSourceProcState = clientProcState;
21520 app.adjTarget = cpr.name;
21521 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21522 + ": " + app + ", due to " + client
21523 + " adj=" + adj + " procState=" + procState);
21526 // If the provider has external (non-framework) process
21527 // dependencies, ensure that its adjustment is at least
21528 // FOREGROUND_APP_ADJ.
21529 if (cpr.hasExternalProcessHandles()) {
21530 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21531 adj = ProcessList.FOREGROUND_APP_ADJ;
21532 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21533 app.cached = false;
21534 app.adjType = "ext-provider";
21535 app.adjTarget = cpr.name;
21536 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21538 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21539 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21544 if (app.lastProviderTime > 0 &&
21545 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21546 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21547 adj = ProcessList.PREVIOUS_APP_ADJ;
21548 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21549 app.cached = false;
21550 app.adjType = "recent-provider";
21551 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21553 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21554 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21555 app.adjType = "recent-provider";
21556 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21560 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21561 // A client of one of our services or providers is in the top state. We
21562 // *may* want to be in the top state, but not if we are already running in
21563 // the background for some other reason. For the decision here, we are going
21564 // to pick out a few specific states that we want to remain in when a client
21565 // is top (states that tend to be longer-term) and otherwise allow it to go
21566 // to the top state.
21567 switch (procState) {
21568 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21569 // Something else is keeping it at this level, just leave it.
21571 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21572 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21573 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21574 case ActivityManager.PROCESS_STATE_SERVICE:
21575 // These all are longer-term states, so pull them up to the top
21576 // of the background states, but not all the way to the top state.
21577 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21578 app.adjType = mayBeTopType;
21579 app.adjSource = mayBeTopSource;
21580 app.adjTarget = mayBeTopTarget;
21581 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21582 + ": " + app + ", due to " + mayBeTopSource
21583 + " adj=" + adj + " procState=" + procState);
21586 // Otherwise, top is a better choice, so take it.
21587 procState = ActivityManager.PROCESS_STATE_TOP;
21588 app.adjType = mayBeTopType;
21589 app.adjSource = mayBeTopSource;
21590 app.adjTarget = mayBeTopTarget;
21591 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21592 + ": " + app + ", due to " + mayBeTopSource
21593 + " adj=" + adj + " procState=" + procState);
21598 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21599 if (app.hasClientActivities) {
21600 // This is a cached process, but with client activities. Mark it so.
21601 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21602 app.adjType = "cch-client-act";
21603 } else if (app.treatLikeActivity) {
21604 // This is a cached process, but somebody wants us to treat it like it has
21605 // an activity, okay!
21606 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21607 app.adjType = "cch-as-act";
21611 if (adj == ProcessList.SERVICE_ADJ) {
21613 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21614 mNewNumServiceProcs++;
21615 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21616 if (!app.serviceb) {
21617 // This service isn't far enough down on the LRU list to
21618 // normally be a B service, but if we are low on RAM and it
21619 // is large we want to force it down since we would prefer to
21620 // keep launcher over it.
21621 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21622 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21623 app.serviceHighRam = true;
21624 app.serviceb = true;
21625 //Slog.i(TAG, "ADJ " + app + " high ram!");
21627 mNewNumAServiceProcs++;
21628 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21631 app.serviceHighRam = false;
21634 if (app.serviceb) {
21635 adj = ProcessList.SERVICE_B_ADJ;
21639 app.curRawAdj = adj;
21641 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21642 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21643 if (adj > app.maxAdj) {
21645 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21646 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21650 // Do final modification to adj. Everything we do between here and applying
21651 // the final setAdj must be done in this function, because we will also use
21652 // it when computing the final cached adj later. Note that we don't need to
21653 // worry about this for max adj above, since max adj will always be used to
21654 // keep it out of the cached vaues.
21655 app.curAdj = app.modifyRawOomAdj(adj);
21656 app.curSchedGroup = schedGroup;
21657 app.curProcState = procState;
21658 app.foregroundActivities = foregroundActivities;
21660 return app.curRawAdj;
21664 * Record new PSS sample for a process.
21666 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21668 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21670 proc.lastPssTime = now;
21671 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21672 if (DEBUG_PSS) Slog.d(TAG_PSS,
21673 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21674 + " state=" + ProcessList.makeProcStateString(procState));
21675 if (proc.initialIdlePss == 0) {
21676 proc.initialIdlePss = pss;
21678 proc.lastPss = pss;
21679 proc.lastSwapPss = swapPss;
21680 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21681 proc.lastCachedPss = pss;
21682 proc.lastCachedSwapPss = swapPss;
21685 final SparseArray<Pair<Long, String>> watchUids
21686 = mMemWatchProcesses.getMap().get(proc.processName);
21688 if (watchUids != null) {
21689 Pair<Long, String> val = watchUids.get(proc.uid);
21691 val = watchUids.get(0);
21697 if (check != null) {
21698 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21699 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21700 if (!isDebuggable) {
21701 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21702 isDebuggable = true;
21705 if (isDebuggable) {
21706 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21707 final ProcessRecord myProc = proc;
21708 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21709 mMemWatchDumpProcName = proc.processName;
21710 mMemWatchDumpFile = heapdumpFile.toString();
21711 mMemWatchDumpPid = proc.pid;
21712 mMemWatchDumpUid = proc.uid;
21713 BackgroundThread.getHandler().post(new Runnable() {
21715 public void run() {
21716 revokeUriPermission(ActivityThread.currentActivityThread()
21717 .getApplicationThread(),
21718 null, DumpHeapActivity.JAVA_URI,
21719 Intent.FLAG_GRANT_READ_URI_PERMISSION
21720 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21721 UserHandle.myUserId());
21722 ParcelFileDescriptor fd = null;
21724 heapdumpFile.delete();
21725 fd = ParcelFileDescriptor.open(heapdumpFile,
21726 ParcelFileDescriptor.MODE_CREATE |
21727 ParcelFileDescriptor.MODE_TRUNCATE |
21728 ParcelFileDescriptor.MODE_WRITE_ONLY |
21729 ParcelFileDescriptor.MODE_APPEND);
21730 IApplicationThread thread = myProc.thread;
21731 if (thread != null) {
21733 if (DEBUG_PSS) Slog.d(TAG_PSS,
21734 "Requesting dump heap from "
21735 + myProc + " to " + heapdumpFile);
21736 thread.dumpHeap(/* managed= */ true,
21737 /* mallocInfo= */ false, /* runGc= */ false,
21738 heapdumpFile.toString(), fd);
21739 } catch (RemoteException e) {
21742 } catch (FileNotFoundException e) {
21743 e.printStackTrace();
21748 } catch (IOException e) {
21755 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21756 + ", but debugging not enabled");
21763 * Schedule PSS collection of a process.
21765 void requestPssLocked(ProcessRecord proc, int procState) {
21766 if (mPendingPssProcesses.contains(proc)) {
21769 if (mPendingPssProcesses.size() == 0) {
21770 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21772 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21773 proc.pssProcState = procState;
21774 mPendingPssProcesses.add(proc);
21778 * Schedule PSS collection of all processes.
21780 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21782 if (now < (mLastFullPssTime +
21783 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21784 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21788 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21789 mLastFullPssTime = now;
21790 mFullPssPending = true;
21791 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21792 mPendingPssProcesses.clear();
21793 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21794 ProcessRecord app = mLruProcesses.get(i);
21795 if (app.thread == null
21796 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21799 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21800 app.pssProcState = app.setProcState;
21801 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21802 mTestPssMode, isSleepingLocked(), now);
21803 mPendingPssProcesses.add(app);
21806 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21809 public void setTestPssMode(boolean enabled) {
21810 synchronized (this) {
21811 mTestPssMode = enabled;
21813 // Whenever we enable the mode, we want to take a snapshot all of current
21814 // process mem use.
21815 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21821 * Ask a given process to GC right now.
21823 final void performAppGcLocked(ProcessRecord app) {
21825 app.lastRequestedGc = SystemClock.uptimeMillis();
21826 if (app.thread != null) {
21827 if (app.reportLowMemory) {
21828 app.reportLowMemory = false;
21829 app.thread.scheduleLowMemory();
21831 app.thread.processInBackground();
21834 } catch (Exception e) {
21840 * Returns true if things are idle enough to perform GCs.
21842 private final boolean canGcNowLocked() {
21843 boolean processingBroadcasts = false;
21844 for (BroadcastQueue q : mBroadcastQueues) {
21845 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21846 processingBroadcasts = true;
21849 return !processingBroadcasts
21850 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21854 * Perform GCs on all processes that are waiting for it, but only
21855 * if things are idle.
21857 final void performAppGcsLocked() {
21858 final int N = mProcessesToGc.size();
21862 if (canGcNowLocked()) {
21863 while (mProcessesToGc.size() > 0) {
21864 ProcessRecord proc = mProcessesToGc.remove(0);
21865 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21866 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21867 <= SystemClock.uptimeMillis()) {
21868 // To avoid spamming the system, we will GC processes one
21869 // at a time, waiting a few seconds between each.
21870 performAppGcLocked(proc);
21871 scheduleAppGcsLocked();
21874 // It hasn't been long enough since we last GCed this
21875 // process... put it in the list to wait for its time.
21876 addProcessToGcListLocked(proc);
21882 scheduleAppGcsLocked();
21887 * If all looks good, perform GCs on all processes waiting for them.
21889 final void performAppGcsIfAppropriateLocked() {
21890 if (canGcNowLocked()) {
21891 performAppGcsLocked();
21894 // Still not idle, wait some more.
21895 scheduleAppGcsLocked();
21899 * Schedule the execution of all pending app GCs.
21901 final void scheduleAppGcsLocked() {
21902 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21904 if (mProcessesToGc.size() > 0) {
21905 // Schedule a GC for the time to the next process.
21906 ProcessRecord proc = mProcessesToGc.get(0);
21907 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21909 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21910 long now = SystemClock.uptimeMillis();
21911 if (when < (now+mConstants.GC_TIMEOUT)) {
21912 when = now + mConstants.GC_TIMEOUT;
21914 mHandler.sendMessageAtTime(msg, when);
21919 * Add a process to the array of processes waiting to be GCed. Keeps the
21920 * list in sorted order by the last GC time. The process can't already be
21923 final void addProcessToGcListLocked(ProcessRecord proc) {
21924 boolean added = false;
21925 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21926 if (mProcessesToGc.get(i).lastRequestedGc <
21927 proc.lastRequestedGc) {
21929 mProcessesToGc.add(i+1, proc);
21934 mProcessesToGc.add(0, proc);
21939 * Set up to ask a process to GC itself. This will either do it
21940 * immediately, or put it on the list of processes to gc the next
21941 * time things are idle.
21943 final void scheduleAppGcLocked(ProcessRecord app) {
21944 long now = SystemClock.uptimeMillis();
21945 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21948 if (!mProcessesToGc.contains(app)) {
21949 addProcessToGcListLocked(app);
21950 scheduleAppGcsLocked();
21954 final void checkExcessivePowerUsageLocked() {
21955 updateCpuStatsNow();
21957 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21958 boolean doCpuKills = true;
21959 if (mLastPowerCheckUptime == 0) {
21960 doCpuKills = false;
21962 final long curUptime = SystemClock.uptimeMillis();
21963 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21964 mLastPowerCheckUptime = curUptime;
21965 int i = mLruProcesses.size();
21968 ProcessRecord app = mLruProcesses.get(i);
21969 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21970 if (app.lastCpuTime <= 0) {
21973 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21975 StringBuilder sb = new StringBuilder(128);
21976 sb.append("CPU for ");
21977 app.toShortString(sb);
21978 sb.append(": over ");
21979 TimeUtils.formatDuration(uptimeSince, sb);
21980 sb.append(" used ");
21981 TimeUtils.formatDuration(cputimeUsed, sb);
21983 sb.append((cputimeUsed*100)/uptimeSince);
21985 Slog.i(TAG_POWER, sb.toString());
21987 // If the process has used too much CPU over the last duration, the
21988 // user probably doesn't want this, so kill!
21989 if (doCpuKills && uptimeSince > 0) {
21990 // What is the limit for this process?
21992 long checkDur = curUptime - app.whenUnimportant;
21993 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21994 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21995 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21996 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21997 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21998 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21999 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
22001 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
22003 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
22004 synchronized (stats) {
22005 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
22006 uptimeSince, cputimeUsed);
22008 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
22009 + " dur=" + checkDur + " limit=" + cpuLimit, true);
22010 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22013 app.lastCpuTime = app.curCpuTime;
22018 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22020 boolean success = true;
22022 if (app.curRawAdj != app.setRawAdj) {
22023 app.setRawAdj = app.curRawAdj;
22028 if (app.curAdj != app.setAdj) {
22029 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22030 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22031 String msg = "Set " + app.pid + " " + app.processName + " adj "
22032 + app.curAdj + ": " + app.adjType;
22033 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22035 app.setAdj = app.curAdj;
22036 app.verifiedAdj = ProcessList.INVALID_ADJ;
22039 if (app.setSchedGroup != app.curSchedGroup) {
22040 int oldSchedGroup = app.setSchedGroup;
22041 app.setSchedGroup = app.curSchedGroup;
22042 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22043 String msg = "Setting sched group of " + app.processName
22044 + " to " + app.curSchedGroup;
22045 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22047 if (app.waitingToKill != null && app.curReceivers.isEmpty()
22048 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22049 app.kill(app.waitingToKill, true);
22053 switch (app.curSchedGroup) {
22054 case ProcessList.SCHED_GROUP_BACKGROUND:
22055 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22057 case ProcessList.SCHED_GROUP_TOP_APP:
22058 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22059 processGroup = THREAD_GROUP_TOP_APP;
22062 processGroup = THREAD_GROUP_DEFAULT;
22065 long oldId = Binder.clearCallingIdentity();
22067 setProcessGroup(app.pid, processGroup);
22068 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22069 // do nothing if we already switched to RT
22070 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22071 mVrController.onTopProcChangedLocked(app);
22072 if (mUseFifoUiScheduling) {
22073 // Switch UI pipeline for app to SCHED_FIFO
22074 app.savedPriority = Process.getThreadPriority(app.pid);
22075 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22076 if (app.renderThreadTid != 0) {
22077 scheduleAsFifoPriority(app.renderThreadTid,
22078 /* suppressLogs */true);
22079 if (DEBUG_OOM_ADJ) {
22080 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22081 app.renderThreadTid + ") to FIFO");
22084 if (DEBUG_OOM_ADJ) {
22085 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22089 // Boost priority for top app UI and render threads
22090 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22091 if (app.renderThreadTid != 0) {
22093 setThreadPriority(app.renderThreadTid,
22094 TOP_APP_PRIORITY_BOOST);
22095 } catch (IllegalArgumentException e) {
22096 // thread died, ignore
22101 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22102 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22103 mVrController.onTopProcChangedLocked(app);
22104 if (mUseFifoUiScheduling) {
22106 // Reset UI pipeline to SCHED_OTHER
22107 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22108 setThreadPriority(app.pid, app.savedPriority);
22109 if (app.renderThreadTid != 0) {
22110 setThreadScheduler(app.renderThreadTid,
22112 setThreadPriority(app.renderThreadTid, -4);
22114 } catch (IllegalArgumentException e) {
22116 "Failed to set scheduling policy, thread does not exist:\n"
22118 } catch (SecurityException e) {
22119 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22122 // Reset priority for top app UI and render threads
22123 setThreadPriority(app.pid, 0);
22124 if (app.renderThreadTid != 0) {
22125 setThreadPriority(app.renderThreadTid, 0);
22129 } catch (Exception e) {
22131 Slog.w(TAG, "Failed setting process group of " + app.pid
22132 + " to " + app.curSchedGroup);
22133 Slog.w(TAG, "at location", e);
22136 Binder.restoreCallingIdentity(oldId);
22140 if (app.repForegroundActivities != app.foregroundActivities) {
22141 app.repForegroundActivities = app.foregroundActivities;
22142 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22144 if (app.repProcState != app.curProcState) {
22145 app.repProcState = app.curProcState;
22146 if (app.thread != null) {
22149 //RuntimeException h = new RuntimeException("here");
22150 Slog.i(TAG, "Sending new process state " + app.repProcState
22151 + " to " + app /*, h*/);
22153 app.thread.setProcessState(app.repProcState);
22154 } catch (RemoteException e) {
22158 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22159 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22160 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22161 // Experimental code to more aggressively collect pss while
22162 // running test... the problem is that this tends to collect
22163 // the data right when a process is transitioning between process
22164 // states, which well tend to give noisy data.
22165 long start = SystemClock.uptimeMillis();
22166 long pss = Debug.getPss(app.pid, mTmpLong, null);
22167 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22168 mPendingPssProcesses.remove(app);
22169 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22170 + " to " + app.curProcState + ": "
22171 + (SystemClock.uptimeMillis()-start) + "ms");
22173 app.lastStateTime = now;
22174 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22175 mTestPssMode, isSleepingLocked(), now);
22176 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22177 + ProcessList.makeProcStateString(app.setProcState) + " to "
22178 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22179 + (app.nextPssTime-now) + ": " + app);
22181 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22182 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22184 requestPssLocked(app, app.setProcState);
22185 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22186 mTestPssMode, isSleepingLocked(), now);
22187 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22188 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22190 if (app.setProcState != app.curProcState) {
22191 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22192 String msg = "Proc state change of " + app.processName
22193 + " to " + app.curProcState;
22194 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22196 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22197 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22198 if (setImportant && !curImportant) {
22199 // This app is no longer something we consider important enough to allow to
22200 // use arbitrary amounts of battery power. Note
22201 // its current CPU time to later know to kill it if
22202 // it is not behaving well.
22203 app.whenUnimportant = now;
22204 app.lastCpuTime = 0;
22206 // Inform UsageStats of important process state change
22207 // Must be called before updating setProcState
22208 maybeUpdateUsageStatsLocked(app, nowElapsed);
22210 app.setProcState = app.curProcState;
22211 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22212 app.notCachedSinceIdle = false;
22215 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22217 app.procStateChanged = true;
22219 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22220 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22221 // For apps that sit around for a long time in the interactive state, we need
22222 // to report this at least once a day so they don't go idle.
22223 maybeUpdateUsageStatsLocked(app, nowElapsed);
22226 if (changes != 0) {
22227 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22228 "Changes in " + app + ": " + changes);
22229 int i = mPendingProcessChanges.size()-1;
22230 ProcessChangeItem item = null;
22232 item = mPendingProcessChanges.get(i);
22233 if (item.pid == app.pid) {
22234 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22235 "Re-using existing item: " + item);
22241 // No existing item in pending changes; need a new one.
22242 final int NA = mAvailProcessChanges.size();
22244 item = mAvailProcessChanges.remove(NA-1);
22245 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22246 "Retrieving available item: " + item);
22248 item = new ProcessChangeItem();
22249 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22250 "Allocating new item: " + item);
22253 item.pid = app.pid;
22254 item.uid = app.info.uid;
22255 if (mPendingProcessChanges.size() == 0) {
22256 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22257 "*** Enqueueing dispatch processes changed!");
22258 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22260 mPendingProcessChanges.add(item);
22262 item.changes |= changes;
22263 item.foregroundActivities = app.repForegroundActivities;
22264 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22265 "Item " + Integer.toHexString(System.identityHashCode(item))
22266 + " " + app.toShortString() + ": changes=" + item.changes
22267 + " foreground=" + item.foregroundActivities
22268 + " type=" + app.adjType + " source=" + app.adjSource
22269 + " target=" + app.adjTarget);
22275 private boolean isEphemeralLocked(int uid) {
22276 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22277 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22280 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22285 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22286 final UidRecord.ChangeItem pendingChange;
22287 if (uidRec == null || uidRec.pendingChange == null) {
22288 if (mPendingUidChanges.size() == 0) {
22289 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22290 "*** Enqueueing dispatch uid changed!");
22291 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22293 final int NA = mAvailUidChanges.size();
22295 pendingChange = mAvailUidChanges.remove(NA-1);
22296 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22297 "Retrieving available item: " + pendingChange);
22299 pendingChange = new UidRecord.ChangeItem();
22300 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22301 "Allocating new item: " + pendingChange);
22303 if (uidRec != null) {
22304 uidRec.pendingChange = pendingChange;
22305 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22306 // If this uid is going away, and we haven't yet reported it is gone,
22308 change |= UidRecord.CHANGE_IDLE;
22310 } else if (uid < 0) {
22311 throw new IllegalArgumentException("No UidRecord or uid");
22313 pendingChange.uidRecord = uidRec;
22314 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22315 mPendingUidChanges.add(pendingChange);
22317 pendingChange = uidRec.pendingChange;
22318 // If there is no change in idle or active state, then keep whatever was pending.
22319 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22320 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22321 | UidRecord.CHANGE_ACTIVE));
22323 // If there is no change in cached or uncached state, then keep whatever was pending.
22324 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22325 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22326 | UidRecord.CHANGE_UNCACHED));
22328 // If this is a report of the UID being gone, then we shouldn't keep any previous
22329 // report of it being active or cached. (That is, a gone uid is never active,
22330 // and never cached.)
22331 if ((change & UidRecord.CHANGE_GONE) != 0) {
22332 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22333 if (!uidRec.idle) {
22334 // If this uid is going away, and we haven't yet reported it is gone,
22336 change |= UidRecord.CHANGE_IDLE;
22340 pendingChange.change = change;
22341 pendingChange.processState = uidRec != null
22342 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22343 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22344 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22345 if (uidRec != null) {
22346 uidRec.lastReportedChange = change;
22347 uidRec.updateLastDispatchedProcStateSeq(change);
22350 // Directly update the power manager, since we sit on top of it and it is critical
22351 // it be kept in sync (so wake locks will be held as soon as appropriate).
22352 if (mLocalPowerManager != null) {
22353 // TO DO: dispatch cached/uncached changes here, so we don't need to report
22354 // all proc state changes.
22355 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22356 mLocalPowerManager.uidActive(pendingChange.uid);
22358 if ((change & UidRecord.CHANGE_IDLE) != 0) {
22359 mLocalPowerManager.uidIdle(pendingChange.uid);
22361 if ((change & UidRecord.CHANGE_GONE) != 0) {
22362 mLocalPowerManager.uidGone(pendingChange.uid);
22364 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22365 pendingChange.processState);
22370 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22371 String authority) {
22372 if (app == null) return;
22373 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22374 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22375 if (userState == null) return;
22376 final long now = SystemClock.elapsedRealtime();
22377 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22378 if (lastReported == null || lastReported < now - 60 * 1000L) {
22379 if (mSystemReady) {
22380 // Cannot touch the user stats if not system ready
22381 mUsageStatsService.reportContentProviderUsage(
22382 authority, providerPkgName, app.userId);
22384 userState.mProviderLastReportedFg.put(authority, now);
22389 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22390 if (DEBUG_USAGE_STATS) {
22391 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22392 + "] state changes: old = " + app.setProcState + ", new = "
22393 + app.curProcState);
22395 if (mUsageStatsService == null) {
22398 boolean isInteraction;
22399 // To avoid some abuse patterns, we are going to be careful about what we consider
22400 // to be an app interaction. Being the top activity doesn't count while the display
22401 // is sleeping, nor do short foreground services.
22402 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22403 isInteraction = true;
22404 app.fgInteractionTime = 0;
22405 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22406 if (app.fgInteractionTime == 0) {
22407 app.fgInteractionTime = nowElapsed;
22408 isInteraction = false;
22410 isInteraction = nowElapsed > app.fgInteractionTime
22411 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22414 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22415 app.fgInteractionTime = 0;
22417 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22418 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22419 app.interactionEventTime = nowElapsed;
22420 String[] packages = app.getPackageList();
22421 if (packages != null) {
22422 for (int i = 0; i < packages.length; i++) {
22423 mUsageStatsService.reportEvent(packages[i], app.userId,
22424 UsageEvents.Event.SYSTEM_INTERACTION);
22428 app.reportedInteraction = isInteraction;
22429 if (!isInteraction) {
22430 app.interactionEventTime = 0;
22434 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22435 if (proc.thread != null) {
22436 if (proc.baseProcessTracker != null) {
22437 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22442 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22443 ProcessRecord TOP_APP, boolean doingAll, long now) {
22444 if (app.thread == null) {
22448 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22450 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22453 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22455 if (isForeground != proc.foregroundServices) {
22456 proc.foregroundServices = isForeground;
22457 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22459 if (isForeground) {
22460 if (curProcs == null) {
22461 curProcs = new ArrayList<ProcessRecord>();
22462 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22464 if (!curProcs.contains(proc)) {
22465 curProcs.add(proc);
22466 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22467 proc.info.packageName, proc.info.uid);
22470 if (curProcs != null) {
22471 if (curProcs.remove(proc)) {
22472 mBatteryStatsService.noteEvent(
22473 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22474 proc.info.packageName, proc.info.uid);
22475 if (curProcs.size() <= 0) {
22476 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22482 updateOomAdjLocked();
22487 private final ActivityRecord resumedAppLocked() {
22488 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22492 pkg = act.packageName;
22493 uid = act.info.applicationInfo.uid;
22498 // Has the UID or resumed package name changed?
22499 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22500 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22501 if (mCurResumedPackage != null) {
22502 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22503 mCurResumedPackage, mCurResumedUid);
22505 mCurResumedPackage = pkg;
22506 mCurResumedUid = uid;
22507 if (mCurResumedPackage != null) {
22508 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22509 mCurResumedPackage, mCurResumedUid);
22516 * Update OomAdj for a specific process.
22517 * @param app The process to update
22518 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22519 * if necessary, or skip.
22520 * @return whether updateOomAdjLocked(app) was successful.
22522 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22523 final ActivityRecord TOP_ACT = resumedAppLocked();
22524 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22525 final boolean wasCached = app.cached;
22529 // This is the desired cached adjusment we want to tell it to use.
22530 // If our app is currently cached, we know it, and that is it. Otherwise,
22531 // we don't know it yet, and it needs to now be cached we will then
22532 // need to do a complete oom adj.
22533 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22534 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22535 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22536 SystemClock.uptimeMillis());
22538 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22539 // Changed to/from cached state, so apps after it in the LRU
22540 // list may also be changed.
22541 updateOomAdjLocked();
22546 final void updateOomAdjLocked() {
22547 final ActivityRecord TOP_ACT = resumedAppLocked();
22548 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22549 final long now = SystemClock.uptimeMillis();
22550 final long nowElapsed = SystemClock.elapsedRealtime();
22551 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22552 final int N = mLruProcesses.size();
22555 RuntimeException e = new RuntimeException();
22556 e.fillInStackTrace();
22557 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22560 // Reset state in all uid records.
22561 for (int i=mActiveUids.size()-1; i>=0; i--) {
22562 final UidRecord uidRec = mActiveUids.valueAt(i);
22563 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22564 "Starting update of " + uidRec);
22568 mStackSupervisor.rankTaskLayersIfNeeded();
22571 mNewNumServiceProcs = 0;
22572 mNewNumAServiceProcs = 0;
22574 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22575 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22577 // Let's determine how many processes we have running vs.
22578 // how many slots we have for background processes; we may want
22579 // to put multiple processes in a slot of there are enough of
22581 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22582 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22583 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22584 if (numEmptyProcs > cachedProcessLimit) {
22585 // If there are more empty processes than our limit on cached
22586 // processes, then use the cached process limit for the factor.
22587 // This ensures that the really old empty processes get pushed
22588 // down to the bottom, so if we are running low on memory we will
22589 // have a better chance at keeping around more cached processes
22590 // instead of a gazillion empty processes.
22591 numEmptyProcs = cachedProcessLimit;
22593 int emptyFactor = numEmptyProcs/numSlots;
22594 if (emptyFactor < 1) emptyFactor = 1;
22595 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22596 if (cachedFactor < 1) cachedFactor = 1;
22597 int stepCached = 0;
22601 int numTrimming = 0;
22603 mNumNonCachedProcs = 0;
22604 mNumCachedHiddenProcs = 0;
22606 // First update the OOM adjustment for each of the
22607 // application processes based on their current state.
22608 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22609 int nextCachedAdj = curCachedAdj+1;
22610 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22611 int nextEmptyAdj = curEmptyAdj+2;
22612 for (int i=N-1; i>=0; i--) {
22613 ProcessRecord app = mLruProcesses.get(i);
22614 if (!app.killedByAm && app.thread != null) {
22615 app.procStateChanged = false;
22616 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22618 // If we haven't yet assigned the final cached adj
22619 // to the process, do that now.
22620 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22621 switch (app.curProcState) {
22622 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22623 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22624 // This process is a cached process holding activities...
22625 // assign it the next cached value for that type, and then
22626 // step that cached level.
22627 app.curRawAdj = curCachedAdj;
22628 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22629 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22630 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22632 if (curCachedAdj != nextCachedAdj) {
22634 if (stepCached >= cachedFactor) {
22636 curCachedAdj = nextCachedAdj;
22637 nextCachedAdj += 2;
22638 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22639 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22645 // For everything else, assign next empty cached process
22646 // level and bump that up. Note that this means that
22647 // long-running services that have dropped down to the
22648 // cached level will be treated as empty (since their process
22649 // state is still as a service), which is what we want.
22650 app.curRawAdj = curEmptyAdj;
22651 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22652 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22653 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22655 if (curEmptyAdj != nextEmptyAdj) {
22657 if (stepEmpty >= emptyFactor) {
22659 curEmptyAdj = nextEmptyAdj;
22661 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22662 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22670 applyOomAdjLocked(app, true, now, nowElapsed);
22672 // Count the number of process types.
22673 switch (app.curProcState) {
22674 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22675 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22676 mNumCachedHiddenProcs++;
22678 if (numCached > cachedProcessLimit) {
22679 app.kill("cached #" + numCached, true);
22682 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22683 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22684 && app.lastActivityTime < oldTime) {
22685 app.kill("empty for "
22686 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22687 / 1000) + "s", true);
22690 if (numEmpty > emptyProcessLimit) {
22691 app.kill("empty #" + numEmpty, true);
22696 mNumNonCachedProcs++;
22700 if (app.isolated && app.services.size() <= 0) {
22701 // If this is an isolated process, and there are no
22702 // services running in it, then the process is no longer
22703 // needed. We agressively kill these because we can by
22704 // definition not re-use the same process again, and it is
22705 // good to avoid having whatever code was running in them
22706 // left sitting around after no longer needed.
22707 app.kill("isolated not needed", true);
22709 // Keeping this process, update its uid.
22710 final UidRecord uidRec = app.uidRecord;
22711 if (uidRec != null) {
22712 uidRec.ephemeral = app.info.isInstantApp();
22713 if (uidRec.curProcState > app.curProcState) {
22714 uidRec.curProcState = app.curProcState;
22716 if (app.foregroundServices) {
22717 uidRec.foregroundServices = true;
22722 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22723 && !app.killedByAm) {
22729 incrementProcStateSeqAndNotifyAppsLocked();
22731 mNumServiceProcs = mNewNumServiceProcs;
22733 // Now determine the memory trimming level of background processes.
22734 // Unfortunately we need to start at the back of the list to do this
22735 // properly. We only do this if the number of background apps we
22736 // are managing to keep around is less than half the maximum we desire;
22737 // if we are keeping a good number around, we'll let them use whatever
22738 // memory they want.
22739 final int numCachedAndEmpty = numCached + numEmpty;
22741 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22742 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22743 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22744 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22745 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22746 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22748 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22751 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22753 // We always allow the memory level to go up (better). We only allow it to go
22754 // down if we are in a state where that is allowed, *and* the total number of processes
22755 // has gone down since last time.
22756 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22757 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22758 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22759 if (memFactor > mLastMemoryLevel) {
22760 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22761 memFactor = mLastMemoryLevel;
22762 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22765 if (memFactor != mLastMemoryLevel) {
22766 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22768 mLastMemoryLevel = memFactor;
22769 mLastNumProcesses = mLruProcesses.size();
22770 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22771 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22772 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22773 if (mLowRamStartTime == 0) {
22774 mLowRamStartTime = now;
22778 switch (memFactor) {
22779 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22780 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22782 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22783 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22786 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22789 int factor = numTrimming/3;
22791 if (mHomeProcess != null) minFactor++;
22792 if (mPreviousProcess != null) minFactor++;
22793 if (factor < minFactor) factor = minFactor;
22794 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22795 for (int i=N-1; i>=0; i--) {
22796 ProcessRecord app = mLruProcesses.get(i);
22797 if (allChanged || app.procStateChanged) {
22798 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22799 app.procStateChanged = false;
22801 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22802 && !app.killedByAm) {
22803 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22805 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22806 "Trimming memory of " + app.processName + " to " + curLevel);
22807 app.thread.scheduleTrimMemory(curLevel);
22808 } catch (RemoteException e) {
22811 // For now we won't do this; our memory trimming seems
22812 // to be good enough at this point that destroying
22813 // activities causes more harm than good.
22814 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22815 && app != mHomeProcess && app != mPreviousProcess) {
22816 // Need to do this on its own message because the stack may not
22817 // be in a consistent state at this point.
22818 // For these apps we will also finish their activities
22819 // to help them free memory.
22820 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22824 app.trimMemoryLevel = curLevel;
22826 if (step >= factor) {
22828 switch (curLevel) {
22829 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22830 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22832 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22833 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22837 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22838 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22839 && app.thread != null) {
22841 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22842 "Trimming memory of heavy-weight " + app.processName
22843 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22844 app.thread.scheduleTrimMemory(
22845 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22846 } catch (RemoteException e) {
22849 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22851 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22852 || app.systemNoUi) && app.pendingUiClean) {
22853 // If this application is now in the background and it
22854 // had done UI, then give it the special trim level to
22855 // have it free UI resources.
22856 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22857 if (app.trimMemoryLevel < level && app.thread != null) {
22859 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22860 "Trimming memory of bg-ui " + app.processName
22862 app.thread.scheduleTrimMemory(level);
22863 } catch (RemoteException e) {
22866 app.pendingUiClean = false;
22868 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22870 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22871 "Trimming memory of fg " + app.processName
22872 + " to " + fgTrimLevel);
22873 app.thread.scheduleTrimMemory(fgTrimLevel);
22874 } catch (RemoteException e) {
22877 app.trimMemoryLevel = fgTrimLevel;
22881 if (mLowRamStartTime != 0) {
22882 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22883 mLowRamStartTime = 0;
22885 for (int i=N-1; i>=0; i--) {
22886 ProcessRecord app = mLruProcesses.get(i);
22887 if (allChanged || app.procStateChanged) {
22888 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22889 app.procStateChanged = false;
22891 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22892 || app.systemNoUi) && app.pendingUiClean) {
22893 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22894 && app.thread != null) {
22896 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22897 "Trimming memory of ui hidden " + app.processName
22898 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22899 app.thread.scheduleTrimMemory(
22900 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22901 } catch (RemoteException e) {
22904 app.pendingUiClean = false;
22906 app.trimMemoryLevel = 0;
22910 if (mAlwaysFinishActivities) {
22911 // Need to do this on its own message because the stack may not
22912 // be in a consistent state at this point.
22913 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22917 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22920 ArrayList<UidRecord> becameIdle = null;
22922 // Update from any uid changes.
22923 if (mLocalPowerManager != null) {
22924 mLocalPowerManager.startUidChanges();
22926 for (int i=mActiveUids.size()-1; i>=0; i--) {
22927 final UidRecord uidRec = mActiveUids.valueAt(i);
22928 int uidChange = UidRecord.CHANGE_PROCSTATE;
22929 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22930 && (uidRec.setProcState != uidRec.curProcState
22931 || uidRec.setWhitelist != uidRec.curWhitelist)) {
22932 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22933 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22934 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22935 + " to " + uidRec.curWhitelist);
22936 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22937 && !uidRec.curWhitelist) {
22938 // UID is now in the background (and not on the temp whitelist). Was it
22939 // previously in the foreground (or on the temp whitelist)?
22940 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22941 || uidRec.setWhitelist) {
22942 uidRec.lastBackgroundTime = nowElapsed;
22943 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22944 // Note: the background settle time is in elapsed realtime, while
22945 // the handler time base is uptime. All this means is that we may
22946 // stop background uids later than we had intended, but that only
22947 // happens because the device was sleeping so we are okay anyway.
22948 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22949 mConstants.BACKGROUND_SETTLE_TIME);
22952 if (uidRec.idle && !uidRec.setIdle) {
22953 uidChange = UidRecord.CHANGE_IDLE;
22954 if (becameIdle == null) {
22955 becameIdle = new ArrayList<>();
22957 becameIdle.add(uidRec);
22961 uidChange = UidRecord.CHANGE_ACTIVE;
22962 EventLogTags.writeAmUidActive(uidRec.uid);
22963 uidRec.idle = false;
22965 uidRec.lastBackgroundTime = 0;
22967 final boolean wasCached = uidRec.setProcState
22968 > ActivityManager.PROCESS_STATE_RECEIVER;
22969 final boolean isCached = uidRec.curProcState
22970 > ActivityManager.PROCESS_STATE_RECEIVER;
22971 if (wasCached != isCached ||
22972 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22973 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22975 uidRec.setProcState = uidRec.curProcState;
22976 uidRec.setWhitelist = uidRec.curWhitelist;
22977 uidRec.setIdle = uidRec.idle;
22978 enqueueUidChangeLocked(uidRec, -1, uidChange);
22979 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22980 if (uidRec.foregroundServices) {
22981 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22985 if (mLocalPowerManager != null) {
22986 mLocalPowerManager.finishUidChanges();
22989 if (becameIdle != null) {
22990 // If we have any new uids that became idle this time, we need to make sure
22991 // they aren't left with running services.
22992 for (int i = becameIdle.size() - 1; i >= 0; i--) {
22993 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22997 if (mProcessStats.shouldWriteNowLocked(now)) {
22998 mHandler.post(new Runnable() {
22999 @Override public void run() {
23000 synchronized (ActivityManagerService.this) {
23001 mProcessStats.writeStateAsyncLocked();
23007 if (DEBUG_OOM_ADJ) {
23008 final long duration = SystemClock.uptimeMillis() - now;
23010 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23011 new RuntimeException("here").fillInStackTrace());
23013 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23019 public void makePackageIdle(String packageName, int userId) {
23020 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23021 != PackageManager.PERMISSION_GRANTED) {
23022 String msg = "Permission Denial: makePackageIdle() from pid="
23023 + Binder.getCallingPid()
23024 + ", uid=" + Binder.getCallingUid()
23025 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23027 throw new SecurityException(msg);
23029 final int callingPid = Binder.getCallingPid();
23030 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23031 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23032 long callingId = Binder.clearCallingIdentity();
23033 synchronized(this) {
23035 IPackageManager pm = AppGlobals.getPackageManager();
23038 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23039 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23040 } catch (RemoteException e) {
23042 if (pkgUid == -1) {
23043 throw new IllegalArgumentException("Unknown package name " + packageName);
23046 if (mLocalPowerManager != null) {
23047 mLocalPowerManager.startUidChanges();
23049 final int appId = UserHandle.getAppId(pkgUid);
23050 final int N = mActiveUids.size();
23051 for (int i=N-1; i>=0; i--) {
23052 final UidRecord uidRec = mActiveUids.valueAt(i);
23053 final long bgTime = uidRec.lastBackgroundTime;
23054 if (bgTime > 0 && !uidRec.idle) {
23055 if (UserHandle.getAppId(uidRec.uid) == appId) {
23056 if (userId == UserHandle.USER_ALL ||
23057 userId == UserHandle.getUserId(uidRec.uid)) {
23058 EventLogTags.writeAmUidIdle(uidRec.uid);
23059 uidRec.idle = true;
23060 uidRec.setIdle = true;
23061 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23062 + " from package " + packageName + " user " + userId);
23063 doStopUidLocked(uidRec.uid, uidRec);
23069 if (mLocalPowerManager != null) {
23070 mLocalPowerManager.finishUidChanges();
23072 Binder.restoreCallingIdentity(callingId);
23077 final void idleUids() {
23078 synchronized (this) {
23079 final int N = mActiveUids.size();
23083 final long nowElapsed = SystemClock.elapsedRealtime();
23084 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23086 if (mLocalPowerManager != null) {
23087 mLocalPowerManager.startUidChanges();
23089 for (int i=N-1; i>=0; i--) {
23090 final UidRecord uidRec = mActiveUids.valueAt(i);
23091 final long bgTime = uidRec.lastBackgroundTime;
23092 if (bgTime > 0 && !uidRec.idle) {
23093 if (bgTime <= maxBgTime) {
23094 EventLogTags.writeAmUidIdle(uidRec.uid);
23095 uidRec.idle = true;
23096 uidRec.setIdle = true;
23097 doStopUidLocked(uidRec.uid, uidRec);
23099 if (nextTime == 0 || nextTime > bgTime) {
23105 if (mLocalPowerManager != null) {
23106 mLocalPowerManager.finishUidChanges();
23108 if (nextTime > 0) {
23109 mHandler.removeMessages(IDLE_UIDS_MSG);
23110 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23111 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23117 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23118 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23119 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23123 void incrementProcStateSeqAndNotifyAppsLocked() {
23124 if (mWaitForNetworkTimeoutMs <= 0) {
23127 // Used for identifying which uids need to block for network.
23128 ArrayList<Integer> blockingUids = null;
23129 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23130 final UidRecord uidRec = mActiveUids.valueAt(i);
23131 // If the network is not restricted for uid, then nothing to do here.
23132 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23135 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23138 // If process state is not changed, then there's nothing to do.
23139 if (uidRec.setProcState == uidRec.curProcState) {
23142 final int blockState = getBlockStateForUid(uidRec);
23143 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23144 // there's nothing the app needs to do in this scenario.
23145 if (blockState == NETWORK_STATE_NO_CHANGE) {
23148 synchronized (uidRec.networkStateLock) {
23149 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23150 if (blockState == NETWORK_STATE_BLOCK) {
23151 if (blockingUids == null) {
23152 blockingUids = new ArrayList<>();
23154 blockingUids.add(uidRec.uid);
23156 if (DEBUG_NETWORK) {
23157 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23158 + " threads for uid: " + uidRec);
23160 if (uidRec.waitingForNetwork) {
23161 uidRec.networkStateLock.notifyAll();
23167 // There are no uids that need to block, so nothing more to do.
23168 if (blockingUids == null) {
23172 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23173 final ProcessRecord app = mLruProcesses.get(i);
23174 if (!blockingUids.contains(app.uid)) {
23177 if (!app.killedByAm && app.thread != null) {
23178 final UidRecord uidRec = mActiveUids.get(app.uid);
23180 if (DEBUG_NETWORK) {
23181 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23184 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23185 } catch (RemoteException ignored) {
23192 * Checks if the uid is coming from background to foreground or vice versa and returns
23193 * appropriate block state based on this.
23195 * @return blockState based on whether the uid is coming from background to foreground or
23196 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23197 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23198 * {@link #NETWORK_STATE_NO_CHANGE}.
23201 int getBlockStateForUid(UidRecord uidRec) {
23202 // Denotes whether uid's process state is currently allowed network access.
23203 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23204 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23205 // Denotes whether uid's process state was previously allowed network access.
23206 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23207 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23209 // When the uid is coming to foreground, AMS should inform the app thread that it should
23210 // block for the network rules to get updated before launching an activity.
23211 if (!wasAllowed && isAllowed) {
23212 return NETWORK_STATE_BLOCK;
23214 // When the uid is going to background, AMS should inform the app thread that if an
23215 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23216 if (wasAllowed && !isAllowed) {
23217 return NETWORK_STATE_UNBLOCK;
23219 return NETWORK_STATE_NO_CHANGE;
23222 final void runInBackgroundDisabled(int uid) {
23223 synchronized (this) {
23224 UidRecord uidRec = mActiveUids.get(uid);
23225 if (uidRec != null) {
23226 // This uid is actually running... should it be considered background now?
23228 doStopUidLocked(uidRec.uid, uidRec);
23231 // This uid isn't actually running... still send a report about it being "stopped".
23232 doStopUidLocked(uid, null);
23237 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23238 mServices.stopInBackgroundLocked(uid);
23239 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23243 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23245 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23246 long duration, String tag) {
23247 if (DEBUG_WHITELISTS) {
23248 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23249 + targetUid + ", " + duration + ")");
23252 synchronized (mPidsSelfLocked) {
23253 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23255 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23259 if (!pr.whitelistManager) {
23260 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23261 != PackageManager.PERMISSION_GRANTED) {
23262 if (DEBUG_WHITELISTS) {
23263 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23264 + ": pid " + callerPid + " is not allowed");
23271 tempWhitelistUidLocked(targetUid, duration, tag);
23275 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23277 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23278 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23279 setUidTempWhitelistStateLocked(targetUid, true);
23280 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23283 void pushTempWhitelist() {
23285 final PendingTempWhitelist[] list;
23287 // First copy out the pending changes... we need to leave them in the map for now,
23288 // in case someone needs to check what is coming up while we don't have the lock held.
23289 synchronized(this) {
23290 N = mPendingTempWhitelist.size();
23291 list = new PendingTempWhitelist[N];
23292 for (int i = 0; i < N; i++) {
23293 list[i] = mPendingTempWhitelist.valueAt(i);
23297 // Now safely dispatch changes to device idle controller.
23298 for (int i = 0; i < N; i++) {
23299 PendingTempWhitelist ptw = list[i];
23300 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23301 ptw.duration, true, ptw.tag);
23304 // And now we can safely remove them from the map.
23305 synchronized(this) {
23306 for (int i = 0; i < N; i++) {
23307 PendingTempWhitelist ptw = list[i];
23308 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23309 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23310 mPendingTempWhitelist.removeAt(index);
23316 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23317 boolean changed = false;
23318 for (int i=mActiveUids.size()-1; i>=0; i--) {
23319 final UidRecord uidRec = mActiveUids.valueAt(i);
23320 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23321 uidRec.curWhitelist = onWhitelist;
23326 updateOomAdjLocked();
23330 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23331 boolean changed = false;
23332 final UidRecord uidRec = mActiveUids.get(uid);
23333 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23334 uidRec.curWhitelist = onWhitelist;
23335 updateOomAdjLocked();
23339 final void trimApplications() {
23340 synchronized (this) {
23343 // First remove any unused application processes whose package
23344 // has been removed.
23345 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23346 final ProcessRecord app = mRemovedProcesses.get(i);
23347 if (app.activities.size() == 0
23348 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23350 TAG, "Exiting empty application process "
23351 + app.toShortString() + " ("
23352 + (app.thread != null ? app.thread.asBinder() : null)
23354 if (app.pid > 0 && app.pid != MY_PID) {
23355 app.kill("empty", false);
23358 app.thread.scheduleExit();
23359 } catch (Exception e) {
23360 // Ignore exceptions.
23363 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23364 mRemovedProcesses.remove(i);
23366 if (app.persistent) {
23367 addAppLocked(app.info, null, false, null /* ABI override */);
23372 // Now update the oom adj for all processes.
23373 updateOomAdjLocked();
23377 /** This method sends the specified signal to each of the persistent apps */
23378 public void signalPersistentProcesses(int sig) throws RemoteException {
23379 if (sig != SIGNAL_USR1) {
23380 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23383 synchronized (this) {
23384 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23385 != PackageManager.PERMISSION_GRANTED) {
23386 throw new SecurityException("Requires permission "
23387 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23390 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23391 ProcessRecord r = mLruProcesses.get(i);
23392 if (r.thread != null && r.persistent) {
23393 sendSignal(r.pid, sig);
23399 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23400 if (proc == null || proc == mProfileProc) {
23401 proc = mProfileProc;
23402 profileType = mProfileType;
23403 clearProfilerLocked();
23405 if (proc == null) {
23409 proc.thread.profilerControl(false, null, profileType);
23410 } catch (RemoteException e) {
23411 throw new IllegalStateException("Process disappeared");
23415 private void clearProfilerLocked() {
23416 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23418 mProfilerInfo.profileFd.close();
23419 } catch (IOException e) {
23422 mProfileApp = null;
23423 mProfileProc = null;
23424 mProfilerInfo = null;
23427 public boolean profileControl(String process, int userId, boolean start,
23428 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23431 synchronized (this) {
23432 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23433 // its own permission.
23434 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23435 != PackageManager.PERMISSION_GRANTED) {
23436 throw new SecurityException("Requires permission "
23437 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23440 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23441 throw new IllegalArgumentException("null profile info or fd");
23444 ProcessRecord proc = null;
23445 if (process != null) {
23446 proc = findProcessLocked(process, userId, "profileControl");
23449 if (start && (proc == null || proc.thread == null)) {
23450 throw new IllegalArgumentException("Unknown process: " + process);
23454 stopProfilerLocked(null, 0);
23455 setProfileApp(proc.info, proc.processName, profilerInfo);
23456 mProfileProc = proc;
23457 mProfileType = profileType;
23458 ParcelFileDescriptor fd = profilerInfo.profileFd;
23461 } catch (IOException e) {
23464 profilerInfo.profileFd = fd;
23465 proc.thread.profilerControl(start, profilerInfo, profileType);
23468 mProfilerInfo.profileFd.close();
23469 } catch (IOException e) {
23471 mProfilerInfo.profileFd = null;
23473 stopProfilerLocked(proc, profileType);
23474 if (profilerInfo != null && profilerInfo.profileFd != null) {
23476 profilerInfo.profileFd.close();
23477 } catch (IOException e) {
23484 } catch (RemoteException e) {
23485 throw new IllegalStateException("Process disappeared");
23487 if (profilerInfo != null && profilerInfo.profileFd != null) {
23489 profilerInfo.profileFd.close();
23490 } catch (IOException e) {
23496 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23497 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23498 userId, true, ALLOW_FULL_ONLY, callName, null);
23499 ProcessRecord proc = null;
23501 int pid = Integer.parseInt(process);
23502 synchronized (mPidsSelfLocked) {
23503 proc = mPidsSelfLocked.get(pid);
23505 } catch (NumberFormatException e) {
23508 if (proc == null) {
23509 ArrayMap<String, SparseArray<ProcessRecord>> all
23510 = mProcessNames.getMap();
23511 SparseArray<ProcessRecord> procs = all.get(process);
23512 if (procs != null && procs.size() > 0) {
23513 proc = procs.valueAt(0);
23514 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23515 for (int i=1; i<procs.size(); i++) {
23516 ProcessRecord thisProc = procs.valueAt(i);
23517 if (thisProc.userId == userId) {
23529 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23530 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23533 synchronized (this) {
23534 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23535 // its own permission (same as profileControl).
23536 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23537 != PackageManager.PERMISSION_GRANTED) {
23538 throw new SecurityException("Requires permission "
23539 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23543 throw new IllegalArgumentException("null fd");
23546 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23547 if (proc == null || proc.thread == null) {
23548 throw new IllegalArgumentException("Unknown process: " + process);
23551 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23552 if (!isDebuggable) {
23553 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23554 throw new SecurityException("Process not debuggable: " + proc);
23558 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23562 } catch (RemoteException e) {
23563 throw new IllegalStateException("Process disappeared");
23568 } catch (IOException e) {
23575 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23576 String reportPackage) {
23577 if (processName != null) {
23578 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23579 "setDumpHeapDebugLimit()");
23581 synchronized (mPidsSelfLocked) {
23582 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23583 if (proc == null) {
23584 throw new SecurityException("No process found for calling pid "
23585 + Binder.getCallingPid());
23587 if (!Build.IS_DEBUGGABLE
23588 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23589 throw new SecurityException("Not running a debuggable build");
23591 processName = proc.processName;
23593 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23594 throw new SecurityException("Package " + reportPackage + " is not running in "
23599 synchronized (this) {
23600 if (maxMemSize > 0) {
23601 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23604 mMemWatchProcesses.remove(processName, uid);
23606 mMemWatchProcesses.getMap().remove(processName);
23613 public void dumpHeapFinished(String path) {
23614 synchronized (this) {
23615 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23616 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23617 + " does not match last pid " + mMemWatchDumpPid);
23620 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23621 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23622 + " does not match last path " + mMemWatchDumpFile);
23625 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23626 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23628 // Forced gc to clean up the remnant hprof fd.
23629 Runtime.getRuntime().gc();
23633 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23634 public void monitor() {
23635 synchronized (this) { }
23638 void onCoreSettingsChange(Bundle settings) {
23639 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23640 ProcessRecord processRecord = mLruProcesses.get(i);
23642 if (processRecord.thread != null) {
23643 processRecord.thread.setCoreSettings(settings);
23645 } catch (RemoteException re) {
23651 // Multi-user methods
23654 * Start user, if its not already running, but don't bring it to foreground.
23657 public boolean startUserInBackground(final int userId) {
23658 return mUserController.startUser(userId, /* foreground */ false);
23662 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23663 return mUserController.unlockUser(userId, token, secret, listener);
23667 public boolean switchUser(final int targetUserId) {
23668 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23670 UserInfo targetUserInfo;
23671 synchronized (this) {
23672 currentUserId = mUserController.getCurrentUserIdLocked();
23673 targetUserInfo = mUserController.getUserInfo(targetUserId);
23674 if (targetUserId == currentUserId) {
23675 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23678 if (targetUserInfo == null) {
23679 Slog.w(TAG, "No user info for user #" + targetUserId);
23682 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23683 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23684 + " when device is in demo mode");
23687 if (!targetUserInfo.supportsSwitchTo()) {
23688 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23691 if (targetUserInfo.isManagedProfile()) {
23692 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23695 mUserController.setTargetUserIdLocked(targetUserId);
23697 if (mUserController.mUserSwitchUiEnabled) {
23698 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23699 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23700 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23701 mUiHandler.sendMessage(mHandler.obtainMessage(
23702 START_USER_SWITCH_UI_MSG, userNames));
23704 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23705 mHandler.sendMessage(mHandler.obtainMessage(
23706 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23711 void scheduleStartProfilesLocked() {
23712 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23713 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23714 DateUtils.SECOND_IN_MILLIS);
23719 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23720 return mUserController.stopUser(userId, force, callback);
23724 public UserInfo getCurrentUser() {
23725 return mUserController.getCurrentUser();
23728 String getStartedUserState(int userId) {
23729 synchronized (this) {
23730 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23731 return UserState.stateToString(userState.state);
23736 public boolean isUserRunning(int userId, int flags) {
23737 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23738 && checkCallingPermission(INTERACT_ACROSS_USERS)
23739 != PackageManager.PERMISSION_GRANTED) {
23740 String msg = "Permission Denial: isUserRunning() from pid="
23741 + Binder.getCallingPid()
23742 + ", uid=" + Binder.getCallingUid()
23743 + " requires " + INTERACT_ACROSS_USERS;
23745 throw new SecurityException(msg);
23747 synchronized (this) {
23748 return mUserController.isUserRunningLocked(userId, flags);
23753 public int[] getRunningUserIds() {
23754 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23755 != PackageManager.PERMISSION_GRANTED) {
23756 String msg = "Permission Denial: isUserRunning() from pid="
23757 + Binder.getCallingPid()
23758 + ", uid=" + Binder.getCallingUid()
23759 + " requires " + INTERACT_ACROSS_USERS;
23761 throw new SecurityException(msg);
23763 synchronized (this) {
23764 return mUserController.getStartedUserArrayLocked();
23769 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23770 mUserController.registerUserSwitchObserver(observer, name);
23774 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23775 mUserController.unregisterUserSwitchObserver(observer);
23778 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23779 if (info == null) return null;
23780 ApplicationInfo newInfo = new ApplicationInfo(info);
23781 newInfo.initForUser(userId);
23785 public boolean isUserStopped(int userId) {
23786 synchronized (this) {
23787 return mUserController.getStartedUserStateLocked(userId) == null;
23791 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23793 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23797 ActivityInfo info = new ActivityInfo(aInfo);
23798 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23802 private boolean processSanityChecksLocked(ProcessRecord process) {
23803 if (process == null || process.thread == null) {
23807 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23808 if (!isDebuggable) {
23809 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23817 public boolean startBinderTracking() throws RemoteException {
23818 synchronized (this) {
23819 mBinderTransactionTrackingEnabled = true;
23820 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23821 // permission (same as profileControl).
23822 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23823 != PackageManager.PERMISSION_GRANTED) {
23824 throw new SecurityException("Requires permission "
23825 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23828 for (int i = 0; i < mLruProcesses.size(); i++) {
23829 ProcessRecord process = mLruProcesses.get(i);
23830 if (!processSanityChecksLocked(process)) {
23834 process.thread.startBinderTracking();
23835 } catch (RemoteException e) {
23836 Log.v(TAG, "Process disappared");
23843 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23845 synchronized (this) {
23846 mBinderTransactionTrackingEnabled = false;
23847 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23848 // permission (same as profileControl).
23849 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23850 != PackageManager.PERMISSION_GRANTED) {
23851 throw new SecurityException("Requires permission "
23852 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23856 throw new IllegalArgumentException("null fd");
23859 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23860 pw.println("Binder transaction traces for all processes.\n");
23861 for (ProcessRecord process : mLruProcesses) {
23862 if (!processSanityChecksLocked(process)) {
23866 pw.println("Traces for process: " + process.processName);
23869 TransferPipe tp = new TransferPipe();
23871 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23872 tp.go(fd.getFileDescriptor());
23876 } catch (IOException e) {
23877 pw.println("Failure while dumping IPC traces from " + process +
23878 ". Exception: " + e);
23880 } catch (RemoteException e) {
23881 pw.println("Got a RemoteException while dumping IPC traces from " +
23882 process + ". Exception: " + e);
23893 } catch (IOException e) {
23900 final class LocalService extends ActivityManagerInternal {
23902 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23903 int targetUserId) {
23904 synchronized (ActivityManagerService.this) {
23905 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23906 targetPkg, intent, null, targetUserId);
23911 public String checkContentProviderAccess(String authority, int userId) {
23912 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23916 public void onWakefulnessChanged(int wakefulness) {
23917 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23921 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23922 String processName, String abiOverride, int uid, Runnable crashHandler) {
23923 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23924 processName, abiOverride, uid, crashHandler);
23928 public SleepToken acquireSleepToken(String tag, int displayId) {
23929 Preconditions.checkNotNull(tag);
23930 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23934 public ComponentName getHomeActivityForUser(int userId) {
23935 synchronized (ActivityManagerService.this) {
23936 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23937 return homeActivity == null ? null : homeActivity.realActivity;
23942 public void onUserRemoved(int userId) {
23943 synchronized (ActivityManagerService.this) {
23944 ActivityManagerService.this.onUserStoppedLocked(userId);
23946 mBatteryStatsService.onUserRemoved(userId);
23950 public void onLocalVoiceInteractionStarted(IBinder activity,
23951 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23952 synchronized (ActivityManagerService.this) {
23953 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23954 voiceSession, voiceInteractor);
23959 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23960 synchronized (ActivityManagerService.this) {
23961 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23962 reasons, timestamp);
23967 public void notifyAppTransitionFinished() {
23968 synchronized (ActivityManagerService.this) {
23969 mStackSupervisor.notifyAppTransitionDone();
23974 public void notifyAppTransitionCancelled() {
23975 synchronized (ActivityManagerService.this) {
23976 mStackSupervisor.notifyAppTransitionDone();
23981 public List<IBinder> getTopVisibleActivities() {
23982 synchronized (ActivityManagerService.this) {
23983 return mStackSupervisor.getTopVisibleActivities();
23988 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23989 synchronized (ActivityManagerService.this) {
23990 mStackSupervisor.setDockedStackMinimized(minimized);
23995 public void killForegroundAppsForUser(int userHandle) {
23996 synchronized (ActivityManagerService.this) {
23997 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23998 final int NP = mProcessNames.getMap().size();
23999 for (int ip = 0; ip < NP; ip++) {
24000 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
24001 final int NA = apps.size();
24002 for (int ia = 0; ia < NA; ia++) {
24003 final ProcessRecord app = apps.valueAt(ia);
24004 if (app.persistent) {
24005 // We don't kill persistent processes.
24010 } else if (app.userId == userHandle && app.foregroundActivities) {
24011 app.removed = true;
24017 final int N = procs.size();
24018 for (int i = 0; i < N; i++) {
24019 removeProcessLocked(procs.get(i), false, true, "kill all fg");
24025 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24027 if (!(target instanceof PendingIntentRecord)) {
24028 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24031 synchronized (ActivityManagerService.this) {
24032 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24037 public void setDeviceIdleWhitelist(int[] appids) {
24038 synchronized (ActivityManagerService.this) {
24039 mDeviceIdleWhitelist = appids;
24044 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24045 synchronized (ActivityManagerService.this) {
24046 mDeviceIdleTempWhitelist = appids;
24047 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24052 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24054 Preconditions.checkNotNull(values, "Configuration must not be null");
24055 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24056 synchronized (ActivityManagerService.this) {
24057 updateConfigurationLocked(values, null, false, true, userId,
24058 false /* deferResume */);
24063 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24065 Preconditions.checkNotNull(intents, "intents");
24066 final String[] resolvedTypes = new String[intents.length];
24067 for (int i = 0; i < intents.length; i++) {
24068 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24071 // UID of the package on user userId.
24072 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24073 // packageUid may not be initialized.
24074 int packageUid = 0;
24076 packageUid = AppGlobals.getPackageManager().getPackageUid(
24077 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24078 } catch (RemoteException e) {
24079 // Shouldn't happen.
24082 synchronized (ActivityManagerService.this) {
24083 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24084 /*resultTo*/ null, bOptions, userId);
24089 public int getUidProcessState(int uid) {
24090 return getUidState(uid);
24094 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24095 synchronized (ActivityManagerService.this) {
24097 // We might change the visibilities here, so prepare an empty app transition which
24098 // might be overridden later if we actually change visibilities.
24099 final boolean wasTransitionSet =
24100 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24101 if (!wasTransitionSet) {
24102 mWindowManager.prepareAppTransition(TRANSIT_NONE,
24103 false /* alwaysKeepCurrent */);
24105 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24107 // If there was a transition set already we don't want to interfere with it as we
24108 // might be starting it too early.
24109 if (!wasTransitionSet) {
24110 mWindowManager.executeAppTransition();
24113 if (callback != null) {
24119 public boolean isSystemReady() {
24120 // no need to synchronize(this) just to read & return the value
24121 return mSystemReady;
24125 public void notifyKeyguardTrustedChanged() {
24126 synchronized (ActivityManagerService.this) {
24127 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24128 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24134 * Sets if the given pid has an overlay UI or not.
24136 * @param pid The pid we are setting overlay UI for.
24137 * @param hasOverlayUi True if the process has overlay UI.
24138 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24141 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24142 synchronized (ActivityManagerService.this) {
24143 final ProcessRecord pr;
24144 synchronized (mPidsSelfLocked) {
24145 pr = mPidsSelfLocked.get(pid);
24147 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24151 if (pr.hasOverlayUi == hasOverlayUi) {
24154 pr.hasOverlayUi = hasOverlayUi;
24155 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24156 updateOomAdjLocked(pr, true);
24161 * Called after the network policy rules are updated by
24162 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24163 * and {@param procStateSeq}.
24166 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24167 if (DEBUG_NETWORK) {
24168 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24169 + uid + " seq: " + procStateSeq);
24172 synchronized (ActivityManagerService.this) {
24173 record = mActiveUids.get(uid);
24174 if (record == null) {
24175 if (DEBUG_NETWORK) {
24176 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24177 + " procStateSeq: " + procStateSeq);
24182 synchronized (record.networkStateLock) {
24183 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24184 if (DEBUG_NETWORK) {
24185 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24186 + " been handled for uid: " + uid);
24190 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24191 if (record.curProcStateSeq > procStateSeq) {
24192 if (DEBUG_NETWORK) {
24193 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24194 + ", curProcstateSeq: " + record.curProcStateSeq
24195 + ", procStateSeq: " + procStateSeq);
24199 if (record.waitingForNetwork) {
24200 if (DEBUG_NETWORK) {
24201 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24202 + ", procStateSeq: " + procStateSeq);
24204 record.networkStateLock.notifyAll();
24210 * Called after virtual display Id is updated by
24211 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24212 * {@param vrVr2dDisplayId}.
24215 public void setVr2dDisplayId(int vr2dDisplayId) {
24217 Slog.d(TAG, "setVr2dDisplayId called for: " +
24220 synchronized (ActivityManagerService.this) {
24221 mVr2dDisplayId = vr2dDisplayId;
24226 public void saveANRState(String reason) {
24227 synchronized (ActivityManagerService.this) {
24228 final StringWriter sw = new StringWriter();
24229 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24230 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24231 if (reason != null) {
24232 pw.println(" Reason: " + reason);
24235 mActivityStarter.dump(pw, " ", null);
24237 pw.println("-------------------------------------------------------------------------------");
24238 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24239 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24244 mLastANRState = sw.toString();
24249 public void clearSavedANRState() {
24250 synchronized (ActivityManagerService.this) {
24251 mLastANRState = null;
24256 public void setFocusedActivity(IBinder token) {
24257 synchronized (ActivityManagerService.this) {
24258 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24260 throw new IllegalArgumentException(
24261 "setFocusedActivity: No activity record matching token=" + token);
24263 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24264 r, "setFocusedActivity")) {
24265 mStackSupervisor.resumeFocusedStackTopActivityLocked();
24271 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24272 if (packageName == null) return false;
24274 synchronized (ActivityManagerService.this) {
24275 for (int i = 0; i < mLruProcesses.size(); i++) {
24276 final ProcessRecord processRecord = mLruProcesses.get(i);
24277 if (processRecord.uid == uid) {
24278 for (int j = 0; j < processRecord.activities.size(); j++) {
24279 final ActivityRecord activityRecord = processRecord.activities.get(j);
24280 if (packageName.equals(activityRecord.packageName)) {
24292 * Called by app main thread to wait for the network policy rules to get updated.
24294 * @param procStateSeq The sequence number indicating the process state change that the main
24295 * thread is interested in.
24298 public void waitForNetworkStateUpdate(long procStateSeq) {
24299 final int callingUid = Binder.getCallingUid();
24300 if (DEBUG_NETWORK) {
24301 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24304 synchronized (this) {
24305 record = mActiveUids.get(callingUid);
24306 if (record == null) {
24310 synchronized (record.networkStateLock) {
24311 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24312 if (DEBUG_NETWORK) {
24313 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24314 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24315 + " lastProcStateSeqDispatchedToObservers: "
24316 + record.lastDispatchedProcStateSeq);
24320 if (record.curProcStateSeq > procStateSeq) {
24321 if (DEBUG_NETWORK) {
24322 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24323 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24324 + ", procStateSeq: " + procStateSeq);
24328 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24329 if (DEBUG_NETWORK) {
24330 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24331 + procStateSeq + ", so no need to wait. Uid: "
24332 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24333 + record.lastNetworkUpdatedProcStateSeq);
24338 if (DEBUG_NETWORK) {
24339 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24340 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24342 final long startTime = SystemClock.uptimeMillis();
24343 record.waitingForNetwork = true;
24344 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24345 record.waitingForNetwork = false;
24346 final long totalTime = SystemClock.uptimeMillis() - startTime;
24347 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24348 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24349 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24350 + procStateSeq + " UidRec: " + record
24351 + " validateUidRec: " + mValidateUids.get(callingUid));
24353 } catch (InterruptedException e) {
24354 Thread.currentThread().interrupt();
24359 public void waitForBroadcastIdle(PrintWriter pw) {
24360 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24362 boolean idle = true;
24363 synchronized (this) {
24364 for (BroadcastQueue queue : mBroadcastQueues) {
24365 if (!queue.isIdle()) {
24366 final String msg = "Waiting for queue " + queue + " to become idle...";
24376 final String msg = "All broadcast queues are idle!";
24382 SystemClock.sleep(1000);
24388 * Return the user id of the last resumed activity.
24391 public @UserIdInt int getLastResumedActivityUserId() {
24392 enforceCallingPermission(
24393 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24394 synchronized (this) {
24395 if (mLastResumedActivity == null) {
24396 return mUserController.getCurrentUserIdLocked();
24398 return mLastResumedActivity.userId;
24403 * An implementation of IAppTask, that allows an app to manage its own tasks via
24404 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24405 * only the process that calls getAppTasks() can call the AppTask methods.
24407 class AppTaskImpl extends IAppTask.Stub {
24408 private int mTaskId;
24409 private int mCallingUid;
24411 public AppTaskImpl(int taskId, int callingUid) {
24413 mCallingUid = callingUid;
24416 private void checkCaller() {
24417 if (mCallingUid != Binder.getCallingUid()) {
24418 throw new SecurityException("Caller " + mCallingUid
24419 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24424 public void finishAndRemoveTask() {
24427 synchronized (ActivityManagerService.this) {
24428 long origId = Binder.clearCallingIdentity();
24430 // We remove the task from recents to preserve backwards
24431 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24432 REMOVE_FROM_RECENTS)) {
24433 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24436 Binder.restoreCallingIdentity(origId);
24442 public ActivityManager.RecentTaskInfo getTaskInfo() {
24445 synchronized (ActivityManagerService.this) {
24446 long origId = Binder.clearCallingIdentity();
24448 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24450 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24452 return createRecentTaskInfoFromTaskRecord(tr);
24454 Binder.restoreCallingIdentity(origId);
24460 public void moveToFront() {
24462 // Will bring task to front if it already has a root activity.
24463 final long origId = Binder.clearCallingIdentity();
24465 synchronized (this) {
24466 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24469 Binder.restoreCallingIdentity(origId);
24474 public int startActivity(IBinder whoThread, String callingPackage,
24475 Intent intent, String resolvedType, Bundle bOptions) {
24478 int callingUser = UserHandle.getCallingUserId();
24480 IApplicationThread appThread;
24481 synchronized (ActivityManagerService.this) {
24482 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24484 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24486 appThread = IApplicationThread.Stub.asInterface(whoThread);
24487 if (appThread == null) {
24488 throw new IllegalArgumentException("Bad app thread " + appThread);
24491 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24492 resolvedType, null, null, null, null, 0, 0, null, null,
24493 null, bOptions, false, callingUser, tr, "AppTaskImpl");
24497 public void setExcludeFromRecents(boolean exclude) {
24500 synchronized (ActivityManagerService.this) {
24501 long origId = Binder.clearCallingIdentity();
24503 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24505 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24507 Intent intent = tr.getBaseIntent();
24509 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24511 intent.setFlags(intent.getFlags()
24512 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24515 Binder.restoreCallingIdentity(origId);
24522 * Kill processes for the user with id userId and that depend on the package named packageName
24525 public void killPackageDependents(String packageName, int userId) {
24526 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24527 if (packageName == null) {
24528 throw new NullPointerException(
24529 "Cannot kill the dependents of a package without its name.");
24532 long callingId = Binder.clearCallingIdentity();
24533 IPackageManager pm = AppGlobals.getPackageManager();
24536 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24537 } catch (RemoteException e) {
24539 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24540 throw new IllegalArgumentException(
24541 "Cannot kill dependents of non-existing package " + packageName);
24544 synchronized(this) {
24545 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24546 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24547 "dep: " + packageName);
24550 Binder.restoreCallingIdentity(callingId);
24555 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24556 throws RemoteException {
24557 final long callingId = Binder.clearCallingIdentity();
24559 mKeyguardController.dismissKeyguard(token, callback);
24561 Binder.restoreCallingIdentity(callingId);
24566 public int restartUserInBackground(final int userId) {
24567 return mUserController.restartUser(userId, /* foreground */ false);
24571 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24572 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24573 "scheduleApplicationInfoChanged()");
24575 synchronized (this) {
24576 final long origId = Binder.clearCallingIdentity();
24578 updateApplicationInfoLocked(packageNames, userId);
24580 Binder.restoreCallingIdentity(origId);
24585 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24586 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24587 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24588 final ProcessRecord app = mLruProcesses.get(i);
24589 if (app.thread == null) {
24593 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24597 final int packageCount = app.pkgList.size();
24598 for (int j = 0; j < packageCount; j++) {
24599 final String packageName = app.pkgList.keyAt(j);
24600 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24602 final ApplicationInfo ai = AppGlobals.getPackageManager()
24603 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24605 app.thread.scheduleApplicationInfoChanged(ai);
24607 } catch (RemoteException e) {
24608 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24609 packageName, app));
24617 * Attach an agent to the specified process (proces name or PID)
24619 public void attachAgent(String process, String path) {
24621 synchronized (this) {
24622 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24623 if (proc == null || proc.thread == null) {
24624 throw new IllegalArgumentException("Unknown process: " + process);
24627 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24628 if (!isDebuggable) {
24629 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24630 throw new SecurityException("Process not debuggable: " + proc);
24634 proc.thread.attachAgent(path);
24636 } catch (RemoteException e) {
24637 throw new IllegalStateException("Process disappeared");
24642 public static class Injector {
24643 private NetworkManagementInternal mNmi;
24645 public Context getContext() {
24649 public AppOpsService getAppOpsService(File file, Handler handler) {
24650 return new AppOpsService(file, handler);
24653 public Handler getUiHandler(ActivityManagerService service) {
24654 return service.new UiHandler();
24657 public boolean isNetworkRestrictedForUid(int uid) {
24658 if (ensureHasNetworkManagementInternal()) {
24659 return mNmi.isNetworkRestrictedForUid(uid);
24664 private boolean ensureHasNetworkManagementInternal() {
24665 if (mNmi == null) {
24666 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24668 return mNmi != null;
24673 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24674 throws RemoteException {
24675 synchronized (this) {
24676 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24680 final long origId = Binder.clearCallingIdentity();
24682 r.setShowWhenLocked(showWhenLocked);
24684 Binder.restoreCallingIdentity(origId);
24690 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24691 synchronized (this) {
24692 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24696 final long origId = Binder.clearCallingIdentity();
24698 r.setTurnScreenOn(turnScreenOn);
24700 Binder.restoreCallingIdentity(origId);