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.ScreenObserver;
204 import android.app.ActivityManagerInternal.SleepToken;
205 import android.app.ActivityOptions;
206 import android.app.ActivityThread;
207 import android.app.AlertDialog;
208 import android.app.AppGlobals;
209 import android.app.AppOpsManager;
210 import android.app.ApplicationErrorReport;
211 import android.app.ApplicationThreadConstants;
212 import android.app.BroadcastOptions;
213 import android.app.ContentProviderHolder;
214 import android.app.Dialog;
215 import android.app.IActivityController;
216 import android.app.IActivityManager;
217 import android.app.IAppTask;
218 import android.app.IApplicationThread;
219 import android.app.IInstrumentationWatcher;
220 import android.app.INotificationManager;
221 import android.app.IProcessObserver;
222 import android.app.IServiceConnection;
223 import android.app.IStopUserCallback;
224 import android.app.ITaskStackListener;
225 import android.app.IUiAutomationConnection;
226 import android.app.IUidObserver;
227 import android.app.IUserSwitchObserver;
228 import android.app.Instrumentation;
229 import android.app.Notification;
230 import android.app.NotificationManager;
231 import android.app.PendingIntent;
232 import android.app.PictureInPictureParams;
233 import android.app.ProfilerInfo;
234 import android.app.RemoteAction;
235 import android.app.WaitResult;
236 import android.app.admin.DevicePolicyManager;
237 import android.app.assist.AssistContent;
238 import android.app.assist.AssistStructure;
239 import android.app.backup.IBackupManager;
240 import android.app.usage.UsageEvents;
241 import android.app.usage.UsageStatsManagerInternal;
242 import android.appwidget.AppWidgetManager;
243 import android.content.ActivityNotFoundException;
244 import android.content.BroadcastReceiver;
245 import android.content.ClipData;
246 import android.content.ComponentCallbacks2;
247 import android.content.ComponentName;
248 import android.content.ContentProvider;
249 import android.content.ContentResolver;
250 import android.content.Context;
251 import android.content.DialogInterface;
252 import android.content.IContentProvider;
253 import android.content.IIntentReceiver;
254 import android.content.IIntentSender;
255 import android.content.Intent;
256 import android.content.IntentFilter;
257 import android.content.pm.ActivityInfo;
258 import android.content.pm.ApplicationInfo;
259 import android.content.pm.ConfigurationInfo;
260 import android.content.pm.IPackageDataObserver;
261 import android.content.pm.IPackageManager;
262 import android.content.pm.InstrumentationInfo;
263 import android.content.pm.PackageInfo;
264 import android.content.pm.PackageManager;
265 import android.content.pm.PackageManager.NameNotFoundException;
266 import android.content.pm.PackageManagerInternal;
267 import android.content.pm.ParceledListSlice;
268 import android.content.pm.PathPermission;
269 import android.content.pm.PermissionInfo;
270 import android.content.pm.ProviderInfo;
271 import android.content.pm.ResolveInfo;
272 import android.content.pm.SELinuxUtil;
273 import android.content.pm.ServiceInfo;
274 import android.content.pm.UserInfo;
275 import android.content.res.CompatibilityInfo;
276 import android.content.res.Configuration;
277 import android.content.res.Resources;
278 import android.database.ContentObserver;
279 import android.graphics.Bitmap;
280 import android.graphics.Point;
281 import android.graphics.Rect;
282 import android.location.LocationManager;
283 import android.media.audiofx.AudioEffect;
284 import android.metrics.LogMaker;
285 import android.net.Proxy;
286 import android.net.ProxyInfo;
287 import android.net.Uri;
288 import android.os.BatteryStats;
289 import android.os.Binder;
290 import android.os.Build;
291 import android.os.Bundle;
292 import android.os.Debug;
293 import android.os.DropBoxManager;
294 import android.os.Environment;
295 import android.os.FactoryTest;
296 import android.os.FileObserver;
297 import android.os.FileUtils;
298 import android.os.Handler;
299 import android.os.IBinder;
300 import android.os.IDeviceIdentifiersPolicyService;
301 import android.os.IPermissionController;
302 import android.os.IProcessInfoService;
303 import android.os.IProgressListener;
304 import android.os.LocaleList;
305 import android.os.Looper;
306 import android.os.Message;
307 import android.os.Parcel;
308 import android.os.ParcelFileDescriptor;
309 import android.os.PersistableBundle;
310 import android.os.PowerManager;
311 import android.os.PowerManagerInternal;
312 import android.os.Process;
313 import android.os.RemoteCallbackList;
314 import android.os.RemoteException;
315 import android.os.ResultReceiver;
316 import android.os.ServiceManager;
317 import android.os.ShellCallback;
318 import android.os.StrictMode;
319 import android.os.SystemClock;
320 import android.os.SystemProperties;
321 import android.os.Trace;
322 import android.os.TransactionTooLargeException;
323 import android.os.UpdateLock;
324 import android.os.UserHandle;
325 import android.os.UserManager;
326 import android.os.WorkSource;
327 import android.os.storage.IStorageManager;
328 import android.os.storage.StorageManager;
329 import android.os.storage.StorageManagerInternal;
330 import android.provider.Downloads;
331 import android.provider.Settings;
332 import android.service.voice.IVoiceInteractionSession;
333 import android.service.voice.VoiceInteractionManagerInternal;
334 import android.service.voice.VoiceInteractionSession;
335 import android.telecom.TelecomManager;
336 import android.text.TextUtils;
337 import android.text.format.DateUtils;
338 import android.text.format.Time;
339 import android.text.style.SuggestionSpan;
340 import android.util.ArrayMap;
341 import android.util.ArraySet;
342 import android.util.AtomicFile;
343 import android.util.TimingsTraceLog;
344 import android.util.DebugUtils;
345 import android.util.DisplayMetrics;
346 import android.util.EventLog;
347 import android.util.Log;
348 import android.util.Pair;
349 import android.util.PrintWriterPrinter;
350 import android.util.Slog;
351 import android.util.SparseArray;
352 import android.util.SparseIntArray;
353 import android.util.TimeUtils;
354 import android.util.Xml;
355 import android.view.Gravity;
356 import android.view.LayoutInflater;
357 import android.view.View;
358 import android.view.WindowManager;
360 import com.android.server.job.JobSchedulerInternal;
361 import com.google.android.collect.Lists;
362 import com.google.android.collect.Maps;
364 import com.android.internal.R;
365 import com.android.internal.annotations.GuardedBy;
366 import com.android.internal.annotations.VisibleForTesting;
367 import com.android.internal.app.AssistUtils;
368 import com.android.internal.app.DumpHeapActivity;
369 import com.android.internal.app.IAppOpsCallback;
370 import com.android.internal.app.IAppOpsService;
371 import com.android.internal.app.IVoiceInteractor;
372 import com.android.internal.app.ProcessMap;
373 import com.android.internal.app.SystemUserHomeActivity;
374 import com.android.internal.app.procstats.ProcessStats;
375 import com.android.internal.logging.MetricsLogger;
376 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
377 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
378 import com.android.internal.notification.SystemNotificationChannels;
379 import com.android.internal.os.BackgroundThread;
380 import com.android.internal.os.BatteryStatsImpl;
381 import com.android.internal.os.IResultReceiver;
382 import com.android.internal.os.ProcessCpuTracker;
383 import com.android.internal.os.TransferPipe;
384 import com.android.internal.os.Zygote;
385 import com.android.internal.policy.IKeyguardDismissCallback;
386 import com.android.internal.telephony.TelephonyIntents;
387 import com.android.internal.util.ArrayUtils;
388 import com.android.internal.util.DumpUtils;
389 import com.android.internal.util.FastPrintWriter;
390 import com.android.internal.util.FastXmlSerializer;
391 import com.android.internal.util.MemInfoReader;
392 import com.android.internal.util.Preconditions;
393 import com.android.server.AppOpsService;
394 import com.android.server.AttributeCache;
395 import com.android.server.DeviceIdleController;
396 import com.android.server.IntentResolver;
397 import com.android.server.LocalServices;
398 import com.android.server.LockGuard;
399 import com.android.server.NetworkManagementInternal;
400 import com.android.server.RescueParty;
401 import com.android.server.ServiceThread;
402 import com.android.server.SystemConfig;
403 import com.android.server.SystemService;
404 import com.android.server.SystemServiceManager;
405 import com.android.server.ThreadPriorityBooster;
406 import com.android.server.Watchdog;
407 import com.android.server.am.ActivityStack.ActivityState;
408 import com.android.server.firewall.IntentFirewall;
409 import com.android.server.pm.Installer;
410 import com.android.server.pm.Installer.InstallerException;
411 import com.android.server.statusbar.StatusBarManagerInternal;
412 import com.android.server.vr.VrManagerInternal;
413 import com.android.server.wm.PinnedStackWindowController;
414 import com.android.server.wm.WindowManagerService;
416 import java.text.SimpleDateFormat;
417 import org.xmlpull.v1.XmlPullParser;
418 import org.xmlpull.v1.XmlPullParserException;
419 import org.xmlpull.v1.XmlSerializer;
422 import java.io.FileDescriptor;
423 import java.io.FileInputStream;
424 import java.io.FileNotFoundException;
425 import java.io.FileOutputStream;
426 import java.io.IOException;
427 import java.io.InputStreamReader;
428 import java.io.PrintWriter;
429 import java.io.StringWriter;
430 import java.io.UnsupportedEncodingException;
431 import java.lang.ref.WeakReference;
432 import java.nio.charset.StandardCharsets;
433 import java.text.DateFormat;
434 import java.util.ArrayList;
435 import java.util.Arrays;
436 import java.util.Collections;
437 import java.util.Comparator;
438 import java.util.Date;
439 import java.util.HashMap;
440 import java.util.HashSet;
441 import java.util.Iterator;
442 import java.util.List;
443 import java.util.Locale;
444 import java.util.Map;
445 import java.util.Objects;
446 import java.util.Set;
447 import java.util.concurrent.CountDownLatch;
448 import java.util.concurrent.atomic.AtomicBoolean;
449 import java.util.concurrent.atomic.AtomicLong;
451 import dalvik.system.VMRuntime;
452 import libcore.io.IoUtils;
453 import libcore.util.EmptyArray;
455 public class ActivityManagerService extends IActivityManager.Stub
456 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
459 * Priority we boost main thread and RT of top app to.
461 public static final int TOP_APP_PRIORITY_BOOST = -10;
463 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
464 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
465 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
466 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
467 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
468 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
469 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
470 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
471 private static final String TAG_LRU = TAG + POSTFIX_LRU;
472 private static final String TAG_MU = TAG + POSTFIX_MU;
473 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
474 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
475 private static final String TAG_POWER = TAG + POSTFIX_POWER;
476 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
477 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
478 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
479 private static final String TAG_PSS = TAG + POSTFIX_PSS;
480 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
481 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
482 private static final String TAG_STACK = TAG + POSTFIX_STACK;
483 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
484 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
485 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
486 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
488 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
489 // here so that while the job scheduler can depend on AMS, the other way around
490 // need not be the case.
491 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
493 /** Control over CPU and battery monitoring */
494 // write battery stats every 30 minutes.
495 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
496 static final boolean MONITOR_CPU_USAGE = true;
497 // don't sample cpu less than every 5 seconds.
498 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
499 // wait possibly forever for next cpu sample.
500 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
501 static final boolean MONITOR_THREAD_CPU_USAGE = false;
503 // The flags that are set for all calls we make to the package manager.
504 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
506 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
508 // Amount of time after a call to stopAppSwitches() during which we will
509 // prevent further untrusted switches from happening.
510 static final long APP_SWITCH_DELAY_TIME = 5*1000;
512 // How long we wait for a launched process to attach to the activity manager
513 // before we decide it's never going to come up for real.
514 static final int PROC_START_TIMEOUT = 10*1000;
515 // How long we wait for an attached process to publish its content providers
516 // before we decide it must be hung.
517 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
519 // How long we wait for a launched process to attach to the activity manager
520 // before we decide it's never going to come up for real, when the process was
521 // started with a wrapper for instrumentation (such as Valgrind) because it
522 // could take much longer than usual.
523 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
525 // How long we allow a receiver to run before giving up on it.
526 static final int BROADCAST_FG_TIMEOUT = 10*1000;
527 static final int BROADCAST_BG_TIMEOUT = 60*1000;
529 // How long we wait until we timeout on key dispatching.
530 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
532 // How long we wait until we timeout on key dispatching during instrumentation.
533 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
535 // How long to wait in getAssistContextExtras for the activity and foreground services
536 // to respond with the result.
537 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
539 // How long top wait when going through the modern assist (which doesn't need to block
540 // on getting this result before starting to launch its UI).
541 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
543 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
544 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
546 // Maximum number of persisted Uri grants a package is allowed
547 static final int MAX_PERSISTED_URI_GRANTS = 128;
549 static final int MY_PID = myPid();
551 static final String[] EMPTY_STRING_ARRAY = new String[0];
553 // How many bytes to write into the dropbox log before truncating
554 static final int DROPBOX_MAX_SIZE = 192 * 1024;
555 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
556 // as one line, but close enough for now.
557 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
559 // Access modes for handleIncomingUser.
560 static final int ALLOW_NON_FULL = 0;
561 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
562 static final int ALLOW_FULL_ONLY = 2;
564 // Necessary ApplicationInfo flags to mark an app as persistent
565 private static final int PERSISTENT_MASK =
566 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
568 // Intent sent when remote bugreport collection has been completed
569 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
570 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
572 // Used to indicate that an app transition should be animated.
573 static final boolean ANIMATE = true;
575 // Determines whether to take full screen screenshots
576 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
579 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
581 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
584 * State indicating that there is no need for any blocking for network.
587 static final int NETWORK_STATE_NO_CHANGE = 0;
590 * State indicating that the main thread needs to be informed about the network wait.
593 static final int NETWORK_STATE_BLOCK = 1;
596 * State indicating that any threads waiting for network state to get updated can be unblocked.
599 static final int NETWORK_STATE_UNBLOCK = 2;
601 // Max character limit for a notification title. If the notification title is larger than this
602 // the notification will not be legible to the user.
603 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
605 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
607 /** All system services */
608 SystemServiceManager mSystemServiceManager;
609 AssistUtils mAssistUtils;
611 private Installer mInstaller;
613 /** Run all ActivityStacks through this */
614 final ActivityStackSupervisor mStackSupervisor;
615 private final KeyguardController mKeyguardController;
617 final ActivityStarter mActivityStarter;
619 final TaskChangeNotificationController mTaskChangeNotificationController;
621 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
623 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
625 public final IntentFirewall mIntentFirewall;
627 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
628 // default action automatically. Important for devices without direct input
630 private boolean mShowDialogs = true;
632 private final VrController mVrController;
634 // VR Vr2d Display Id.
635 int mVr2dDisplayId = INVALID_DISPLAY;
637 // Whether we should use SCHED_FIFO for UI and RenderThreads.
638 private boolean mUseFifoUiScheduling = false;
640 BroadcastQueue mFgBroadcastQueue;
641 BroadcastQueue mBgBroadcastQueue;
642 // Convenient for easy iteration over the queues. Foreground is first
643 // so that dispatch of foreground broadcasts gets precedence.
644 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
646 BroadcastStats mLastBroadcastStats;
647 BroadcastStats mCurBroadcastStats;
649 BroadcastQueue broadcastQueueForIntent(Intent intent) {
650 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
651 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
652 "Broadcast intent " + intent + " on "
653 + (isFg ? "foreground" : "background") + " queue");
654 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
658 * The last resumed activity. This is identical to the current resumed activity most
659 * of the time but could be different when we're pausing one activity before we resume
662 private ActivityRecord mLastResumedActivity;
665 * If non-null, we are tracking the time the user spends in the currently focused app.
667 private AppTimeTracker mCurAppTimeTracker;
670 * List of intents that were used to start the most recent tasks.
672 final RecentTasks mRecentTasks;
675 * For addAppTask: cached of the last activity component that was added.
677 ComponentName mLastAddedTaskComponent;
680 * For addAppTask: cached of the last activity uid that was added.
682 int mLastAddedTaskUid;
685 * For addAppTask: cached of the last ActivityInfo that was added.
687 ActivityInfo mLastAddedTaskActivity;
690 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
692 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
695 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
697 String mDeviceOwnerName;
699 final UserController mUserController;
701 final AppErrors mAppErrors;
704 * Dump of the activity state at the time of the last ANR. Cleared after
705 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
707 String mLastANRState;
710 * Indicates the maximum time spent waiting for the network rules to get updated.
713 long mWaitForNetworkTimeoutMs;
715 public boolean canShowErrorDialogs() {
716 return mShowDialogs && !mSleeping && !mShuttingDown
717 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
718 && !(UserManager.isDeviceInDemoMode(mContext)
719 && mUserController.getCurrentUser().isDemo());
722 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
723 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
725 static void boostPriorityForLockedSection() {
726 sThreadPriorityBooster.boost();
729 static void resetPriorityAfterLockedSection() {
730 sThreadPriorityBooster.reset();
733 public class PendingAssistExtras extends Binder implements Runnable {
734 public final ActivityRecord activity;
735 public boolean isHome;
736 public final Bundle extras;
737 public final Intent intent;
738 public final String hint;
739 public final IResultReceiver receiver;
740 public final int userHandle;
741 public boolean haveResult = false;
742 public Bundle result = null;
743 public AssistStructure structure = null;
744 public AssistContent content = null;
745 public Bundle receiverExtras;
747 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
748 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
749 activity = _activity;
753 receiver = _receiver;
754 receiverExtras = _receiverExtras;
755 userHandle = _userHandle;
760 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
761 synchronized (this) {
765 pendingAssistExtrasTimedOut(this);
769 final ArrayList<PendingAssistExtras> mPendingAssistExtras
770 = new ArrayList<PendingAssistExtras>();
773 * Process management.
775 final ProcessList mProcessList = new ProcessList();
778 * All of the applications we currently have running organized by name.
779 * The keys are strings of the application package name (as
780 * returned by the package manager), and the keys are ApplicationRecord
783 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
786 * Tracking long-term execution of processes to look for abuse and other
789 final ProcessStatsService mProcessStats;
792 * The currently running isolated processes.
794 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
797 * Counter for assigning isolated process uids, to avoid frequently reusing the
800 int mNextIsolatedProcessUid = 0;
803 * The currently running heavy-weight process, if any.
805 ProcessRecord mHeavyWeightProcess = null;
808 * Non-persistent appId whitelist for background restrictions
810 int[] mBackgroundAppIdWhitelist = new int[] {
815 * Broadcast actions that will always be deliverable to unlaunched/background apps
817 ArraySet<String> mBackgroundLaunchBroadcasts;
820 * All of the processes we currently have running organized by pid.
821 * The keys are the pid running the application.
823 * <p>NOTE: This object is protected by its own lock, NOT the global
824 * activity manager lock!
826 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
829 * All of the processes that have been forced to be important. The key
830 * is the pid of the caller who requested it (we hold a death
833 abstract class ImportanceToken implements IBinder.DeathRecipient {
838 ImportanceToken(int _pid, IBinder _token, String _reason) {
845 public String toString() {
846 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
847 + " " + reason + " " + pid + " " + token + " }";
850 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
853 * List of records for processes that someone had tried to start before the
854 * system was ready. We don't start them at that point, but ensure they
855 * are started by the time booting is complete.
857 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
860 * List of persistent applications that are in the process
863 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
866 * Processes that are being forcibly torn down.
868 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
871 * List of running applications, sorted by recent usage.
872 * The first entry in the list is the least recently used.
874 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
877 * Where in mLruProcesses that the processes hosting activities start.
879 int mLruProcessActivityStart = 0;
882 * Where in mLruProcesses that the processes hosting services start.
883 * This is after (lower index) than mLruProcessesActivityStart.
885 int mLruProcessServiceStart = 0;
888 * List of processes that should gc as soon as things are idle.
890 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
893 * Processes we want to collect PSS data from.
895 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
897 private boolean mBinderTransactionTrackingEnabled = false;
900 * Last time we requested PSS data of all processes.
902 long mLastFullPssTime = SystemClock.uptimeMillis();
905 * If set, the next time we collect PSS data we should do a full collection
906 * with data from native processes and the kernel.
908 boolean mFullPssPending = false;
911 * This is the process holding what we currently consider to be
912 * the "home" activity.
914 ProcessRecord mHomeProcess;
917 * This is the process holding the activity the user last visited that
918 * is in a different process from the one they are currently in.
920 ProcessRecord mPreviousProcess;
923 * The time at which the previous process was last visible.
925 long mPreviousProcessVisibleTime;
928 * Track all uids that have actively running processes.
930 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
933 * This is for verifying the UID report flow.
935 static final boolean VALIDATE_UID_STATES = true;
936 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
939 * Packages that the user has asked to have run in screen size
940 * compatibility mode instead of filling the screen.
942 final CompatModePackages mCompatModePackages;
945 * Set of IntentSenderRecord objects that are currently active.
947 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
948 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
951 * Fingerprints (hashCode()) of stack traces that we've
952 * already logged DropBox entries for. Guarded by itself. If
953 * something (rogue user app) forces this over
954 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
956 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
957 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
960 * Strict Mode background batched logging state.
962 * The string buffer is guarded by itself, and its lock is also
963 * used to determine if another batched write is already
966 private final StringBuilder mStrictModeBuffer = new StringBuilder();
969 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
970 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
972 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
975 * Resolver for broadcast intents to registered receivers.
976 * Holds BroadcastFilter (subclass of IntentFilter).
978 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
979 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
981 protected boolean allowFilterResult(
982 BroadcastFilter filter, List<BroadcastFilter> dest) {
983 IBinder target = filter.receiverList.receiver.asBinder();
984 for (int i = dest.size() - 1; i >= 0; i--) {
985 if (dest.get(i).receiverList.receiver.asBinder() == target) {
993 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
994 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
995 || userId == filter.owningUserId) {
996 return super.newResult(filter, match, userId);
1002 protected BroadcastFilter[] newArray(int size) {
1003 return new BroadcastFilter[size];
1007 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1008 return packageName.equals(filter.packageName);
1013 * State of all active sticky broadcasts per user. Keys are the action of the
1014 * sticky Intent, values are an ArrayList of all broadcasted intents with
1015 * that action (which should usually be one). The SparseArray is keyed
1016 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1017 * for stickies that are sent to all users.
1019 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1020 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1022 final ActiveServices mServices;
1024 final static class Association {
1025 final int mSourceUid;
1026 final String mSourceProcess;
1027 final int mTargetUid;
1028 final ComponentName mTargetComponent;
1029 final String mTargetProcess;
1037 // states of the source process when the bind occurred.
1038 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1039 long mLastStateUptime;
1040 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1041 - ActivityManager.MIN_PROCESS_STATE+1];
1043 Association(int sourceUid, String sourceProcess, int targetUid,
1044 ComponentName targetComponent, String targetProcess) {
1045 mSourceUid = sourceUid;
1046 mSourceProcess = sourceProcess;
1047 mTargetUid = targetUid;
1048 mTargetComponent = targetComponent;
1049 mTargetProcess = targetProcess;
1054 * When service association tracking is enabled, this is all of the associations we
1055 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1056 * -> association data.
1058 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1059 mAssociations = new SparseArray<>();
1060 boolean mTrackingAssociations;
1063 * Backup/restore process management
1065 String mBackupAppName = null;
1066 BackupRecord mBackupTarget = null;
1068 final ProviderMap mProviderMap;
1071 * List of content providers who have clients waiting for them. The
1072 * application is currently being launched and the provider will be
1073 * removed from this list once it is published.
1075 final ArrayList<ContentProviderRecord> mLaunchingProviders
1076 = new ArrayList<ContentProviderRecord>();
1079 * File storing persisted {@link #mGrantedUriPermissions}.
1081 private final AtomicFile mGrantFile;
1083 /** XML constants used in {@link #mGrantFile} */
1084 private static final String TAG_URI_GRANTS = "uri-grants";
1085 private static final String TAG_URI_GRANT = "uri-grant";
1086 private static final String ATTR_USER_HANDLE = "userHandle";
1087 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1088 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1089 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1090 private static final String ATTR_TARGET_PKG = "targetPkg";
1091 private static final String ATTR_URI = "uri";
1092 private static final String ATTR_MODE_FLAGS = "modeFlags";
1093 private static final String ATTR_CREATED_TIME = "createdTime";
1094 private static final String ATTR_PREFIX = "prefix";
1097 * Global set of specific {@link Uri} permissions that have been granted.
1098 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1099 * to {@link UriPermission#uri} to {@link UriPermission}.
1102 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1103 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1105 public static class GrantUri {
1106 public final int sourceUserId;
1107 public final Uri uri;
1108 public boolean prefix;
1110 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1111 this.sourceUserId = sourceUserId;
1113 this.prefix = prefix;
1117 public int hashCode() {
1119 hashCode = 31 * hashCode + sourceUserId;
1120 hashCode = 31 * hashCode + uri.hashCode();
1121 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1126 public boolean equals(Object o) {
1127 if (o instanceof GrantUri) {
1128 GrantUri other = (GrantUri) o;
1129 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1130 && prefix == other.prefix;
1136 public String toString() {
1137 String result = uri.toString() + " [user " + sourceUserId + "]";
1138 if (prefix) result += " [prefix]";
1142 public String toSafeString() {
1143 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1144 if (prefix) result += " [prefix]";
1148 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1149 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1150 ContentProvider.getUriWithoutUserId(uri), false);
1154 CoreSettingsObserver mCoreSettingsObserver;
1156 FontScaleSettingObserver mFontScaleSettingObserver;
1158 private final class FontScaleSettingObserver extends ContentObserver {
1159 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1161 public FontScaleSettingObserver() {
1163 ContentResolver resolver = mContext.getContentResolver();
1164 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1168 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1169 if (mFontScaleUri.equals(uri)) {
1170 updateFontScaleIfNeeded(userId);
1176 * Thread-local storage used to carry caller permissions over through
1177 * indirect content-provider access.
1179 private class Identity {
1180 public final IBinder token;
1181 public final int pid;
1182 public final int uid;
1184 Identity(IBinder _token, int _pid, int _uid) {
1191 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1194 * All information we have collected about the runtime performance of
1195 * any user id that can impact battery performance.
1197 final BatteryStatsService mBatteryStatsService;
1200 * Information about component usage
1202 UsageStatsManagerInternal mUsageStatsService;
1205 * Access to DeviceIdleController service.
1207 DeviceIdleController.LocalService mLocalDeviceIdleController;
1210 * Set of app ids that are whitelisted for device idle and thus background check.
1212 int[] mDeviceIdleWhitelist = new int[0];
1215 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1217 int[] mDeviceIdleTempWhitelist = new int[0];
1219 static final class PendingTempWhitelist {
1220 final int targetUid;
1221 final long duration;
1224 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1225 targetUid = _targetUid;
1226 duration = _duration;
1231 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1234 * Information about and control over application operations
1236 final AppOpsService mAppOpsService;
1238 /** Current sequencing integer of the configuration, for skipping old configurations. */
1239 private int mConfigurationSeq;
1242 * Temp object used when global and/or display override configuration is updated. It is also
1243 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1246 private Configuration mTempConfig = new Configuration();
1248 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1249 new UpdateConfigurationResult();
1250 private static final class UpdateConfigurationResult {
1251 // Configuration changes that were updated.
1253 // If the activity was relaunched to match the new configuration.
1254 boolean activityRelaunched;
1258 activityRelaunched = false;
1262 boolean mSuppressResizeConfigChanges;
1265 * Hardware-reported OpenGLES version.
1267 final int GL_ES_VERSION;
1270 * List of initialization arguments to pass to all processes when binding applications to them.
1271 * For example, references to the commonly used services.
1273 HashMap<String, IBinder> mAppBindArgs;
1274 HashMap<String, IBinder> mIsolatedAppBindArgs;
1277 * Temporary to avoid allocations. Protected by main lock.
1279 final StringBuilder mStringBuilder = new StringBuilder(256);
1282 * Used to control how we initialize the service.
1284 ComponentName mTopComponent;
1285 String mTopAction = Intent.ACTION_MAIN;
1288 volatile boolean mProcessesReady = false;
1289 volatile boolean mSystemReady = false;
1290 volatile boolean mOnBattery = false;
1291 volatile int mFactoryTest;
1293 @GuardedBy("this") boolean mBooting = false;
1294 @GuardedBy("this") boolean mCallFinishBooting = false;
1295 @GuardedBy("this") boolean mBootAnimationComplete = false;
1296 @GuardedBy("this") boolean mLaunchWarningShown = false;
1297 @GuardedBy("this") boolean mCheckedForSetup = false;
1299 final Context mContext;
1302 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1303 * change at runtime. Use mContext for non-UI purposes.
1305 final Context mUiContext;
1308 * The time at which we will allow normal application switches again,
1309 * after a call to {@link #stopAppSwitches()}.
1311 long mAppSwitchesAllowedTime;
1314 * This is set to true after the first switch after mAppSwitchesAllowedTime
1315 * is set; any switches after that will clear the time.
1317 boolean mDidAppSwitch;
1320 * Last time (in uptime) at which we checked for power usage.
1322 long mLastPowerCheckUptime;
1325 * Set while we are wanting to sleep, to prevent any
1326 * activities from being started/resumed.
1328 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1330 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1331 * while in the sleep state until there is a pending transition out of sleep, in which case
1332 * mSleeping is set to false, and remains false while awake.
1334 * Whether mSleeping can quickly toggled between true/false without the device actually
1335 * display changing states is undefined.
1337 private boolean mSleeping = false;
1340 * The process state used for processes that are running the top activities.
1341 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1343 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1346 * Set while we are running a voice interaction. This overrides
1347 * sleeping while it is active.
1349 IVoiceInteractionSession mRunningVoice;
1352 * For some direct access we need to power manager.
1354 PowerManagerInternal mLocalPowerManager;
1357 * We want to hold a wake lock while running a voice interaction session, since
1358 * this may happen with the screen off and we need to keep the CPU running to
1359 * be able to continue to interact with the user.
1361 PowerManager.WakeLock mVoiceWakeLock;
1364 * State of external calls telling us if the device is awake or asleep.
1366 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1369 * Set if we are shutting down the system, similar to sleeping.
1371 boolean mShuttingDown = false;
1374 * Current sequence id for oom_adj computation traversal.
1379 * Current sequence id for process LRU updating.
1384 * Keep track of the non-cached/empty process we last found, to help
1385 * determine how to distribute cached/empty processes next time.
1387 int mNumNonCachedProcs = 0;
1390 * Keep track of the number of cached hidden procs, to balance oom adj
1391 * distribution between those and empty procs.
1393 int mNumCachedHiddenProcs = 0;
1396 * Keep track of the number of service processes we last found, to
1397 * determine on the next iteration which should be B services.
1399 int mNumServiceProcs = 0;
1400 int mNewNumAServiceProcs = 0;
1401 int mNewNumServiceProcs = 0;
1404 * Allow the current computed overall memory level of the system to go down?
1405 * This is set to false when we are killing processes for reasons other than
1406 * memory management, so that the now smaller process list will not be taken as
1407 * an indication that memory is tighter.
1409 boolean mAllowLowerMemLevel = false;
1412 * The last computed memory level, for holding when we are in a state that
1413 * processes are going away for other reasons.
1415 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1418 * The last total number of process we have, to determine if changes actually look
1419 * like a shrinking number of process due to lower RAM.
1421 int mLastNumProcesses;
1424 * The uptime of the last time we performed idle maintenance.
1426 long mLastIdleTime = SystemClock.uptimeMillis();
1429 * Total time spent with RAM that has been added in the past since the last idle time.
1431 long mLowRamTimeSinceLastIdle = 0;
1434 * If RAM is currently low, when that horrible situation started.
1436 long mLowRamStartTime = 0;
1439 * For reporting to battery stats the current top application.
1441 private String mCurResumedPackage = null;
1442 private int mCurResumedUid = -1;
1445 * For reporting to battery stats the apps currently running foreground
1446 * service. The ProcessMap is package/uid tuples; each of these contain
1447 * an array of the currently foreground processes.
1449 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1450 = new ProcessMap<ArrayList<ProcessRecord>>();
1453 * Set if the systemServer made a call to enterSafeMode.
1458 * If true, we are running under a test environment so will sample PSS from processes
1459 * much more rapidly to try to collect better data when the tests are rapidly
1460 * running through apps.
1462 boolean mTestPssMode = false;
1464 String mDebugApp = null;
1465 boolean mWaitForDebugger = false;
1466 boolean mDebugTransient = false;
1467 String mOrigDebugApp = null;
1468 boolean mOrigWaitForDebugger = false;
1469 boolean mAlwaysFinishActivities = false;
1470 boolean mForceResizableActivities;
1472 * Flag that indicates if multi-window is enabled.
1474 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1475 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1476 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1477 * At least one of the forms of multi-window must be enabled in order for this flag to be
1478 * initialized to 'true'.
1480 * @see #mSupportsSplitScreenMultiWindow
1481 * @see #mSupportsFreeformWindowManagement
1482 * @see #mSupportsPictureInPicture
1483 * @see #mSupportsMultiDisplay
1485 boolean mSupportsMultiWindow;
1486 boolean mSupportsSplitScreenMultiWindow;
1487 boolean mSupportsFreeformWindowManagement;
1488 boolean mSupportsPictureInPicture;
1489 boolean mSupportsMultiDisplay;
1490 boolean mSupportsLeanbackOnly;
1491 IActivityController mController = null;
1492 boolean mControllerIsAMonkey = false;
1493 String mProfileApp = null;
1494 ProcessRecord mProfileProc = null;
1495 ProfilerInfo mProfilerInfo = null;
1496 int mProfileType = 0;
1497 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1498 String mMemWatchDumpProcName;
1499 String mMemWatchDumpFile;
1500 int mMemWatchDumpPid;
1501 int mMemWatchDumpUid;
1502 String mTrackAllocationApp = null;
1503 String mNativeDebuggingApp = null;
1505 final long[] mTmpLong = new long[2];
1507 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1510 * A global counter for generating sequence numbers.
1511 * This value will be used when incrementing sequence numbers in individual uidRecords.
1513 * Having a global counter ensures that seq numbers are monotonically increasing for a
1514 * particular uid even when the uidRecord is re-created.
1518 long mProcStateSeqCounter = 0;
1520 private final Injector mInjector;
1522 static final class ProcessChangeItem {
1523 static final int CHANGE_ACTIVITIES = 1<<0;
1528 boolean foregroundActivities;
1531 static final class UidObserverRegistration {
1537 final SparseIntArray lastProcStates;
1539 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1543 cutpoint = _cutpoint;
1544 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1545 lastProcStates = new SparseIntArray();
1547 lastProcStates = null;
1552 final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1554 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1555 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1557 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1558 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1560 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1561 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1563 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1564 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1566 OomAdjObserver mCurOomAdjObserver;
1569 interface OomAdjObserver {
1570 void onOomAdjMessage(String msg);
1574 * Runtime CPU use collection thread. This object's lock is used to
1575 * perform synchronization with the thread (notifying it to run).
1577 final Thread mProcessCpuThread;
1580 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1581 * Must acquire this object's lock when accessing it.
1582 * NOTE: this lock will be held while doing long operations (trawling
1583 * through all processes in /proc), so it should never be acquired by
1584 * any critical paths such as when holding the main activity manager lock.
1586 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1587 MONITOR_THREAD_CPU_USAGE);
1588 final AtomicLong mLastCpuTime = new AtomicLong(0);
1589 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1590 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1592 long mLastWriteTime = 0;
1595 * Used to retain an update lock when the foreground activity is in
1598 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1601 * Set to true after the system has finished booting.
1603 boolean mBooted = false;
1605 WindowManagerService mWindowManager;
1606 final ActivityThread mSystemThread;
1608 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1609 final ProcessRecord mApp;
1611 final IApplicationThread mAppThread;
1613 AppDeathRecipient(ProcessRecord app, int pid,
1614 IApplicationThread thread) {
1615 if (DEBUG_ALL) Slog.v(
1616 TAG, "New death recipient " + this
1617 + " for thread " + thread.asBinder());
1620 mAppThread = thread;
1624 public void binderDied() {
1625 if (DEBUG_ALL) Slog.v(
1626 TAG, "Death received in " + this
1627 + " for thread " + mAppThread.asBinder());
1628 synchronized(ActivityManagerService.this) {
1629 appDiedLocked(mApp, mPid, mAppThread, true);
1634 static final int SHOW_ERROR_UI_MSG = 1;
1635 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1636 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1637 static final int UPDATE_CONFIGURATION_MSG = 4;
1638 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1639 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1640 static final int SERVICE_TIMEOUT_MSG = 12;
1641 static final int UPDATE_TIME_ZONE = 13;
1642 static final int SHOW_UID_ERROR_UI_MSG = 14;
1643 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1644 static final int PROC_START_TIMEOUT_MSG = 20;
1645 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1646 static final int KILL_APPLICATION_MSG = 22;
1647 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1648 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1649 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1650 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1651 static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1652 static final int CLEAR_DNS_CACHE_MSG = 28;
1653 static final int UPDATE_HTTP_PROXY_MSG = 29;
1654 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1655 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1656 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1657 static final int REPORT_MEM_USAGE_MSG = 33;
1658 static final int REPORT_USER_SWITCH_MSG = 34;
1659 static final int CONTINUE_USER_SWITCH_MSG = 35;
1660 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1661 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1662 static final int PERSIST_URI_GRANTS_MSG = 38;
1663 static final int REQUEST_ALL_PSS_MSG = 39;
1664 static final int START_PROFILES_MSG = 40;
1665 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1666 static final int SYSTEM_USER_START_MSG = 42;
1667 static final int SYSTEM_USER_CURRENT_MSG = 43;
1668 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1669 static final int FINISH_BOOTING_MSG = 45;
1670 static final int START_USER_SWITCH_UI_MSG = 46;
1671 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1672 static final int DISMISS_DIALOG_UI_MSG = 48;
1673 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1674 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1675 static final int DELETE_DUMPHEAP_MSG = 51;
1676 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1677 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1678 static final int REPORT_TIME_TRACKER_MSG = 54;
1679 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1680 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1681 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1682 static final int IDLE_UIDS_MSG = 58;
1683 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1684 static final int LOG_STACK_STATE = 60;
1685 static final int VR_MODE_CHANGE_MSG = 61;
1686 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1687 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1688 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1689 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1690 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1691 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1692 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1693 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1694 static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1695 static final int DISPATCH_SCREEN_AWAKE_MSG = 71;
1696 static final int DISPATCH_SCREEN_KEYGUARD_MSG = 72;
1697 static final int START_USER_SWITCH_FG_MSG = 712;
1698 static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1700 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1701 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1702 static final int FIRST_COMPAT_MODE_MSG = 300;
1703 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1705 static ServiceThread sKillThread = null;
1706 static KillHandler sKillHandler = null;
1708 CompatModeDialog mCompatModeDialog;
1709 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1710 long mLastMemUsageReportTime = 0;
1713 * Flag whether the current user is a "monkey", i.e. whether
1714 * the UI is driven by a UI automation tool.
1716 private boolean mUserIsMonkey;
1718 /** Flag whether the device has a Recents UI */
1719 boolean mHasRecents;
1721 /** The dimensions of the thumbnails in the Recents UI. */
1722 int mThumbnailWidth;
1723 int mThumbnailHeight;
1724 float mFullscreenThumbnailScale;
1726 final ServiceThread mHandlerThread;
1727 final MainHandler mHandler;
1728 final Handler mUiHandler;
1730 final ActivityManagerConstants mConstants;
1732 PackageManagerInternal mPackageManagerInt;
1734 // VoiceInteraction session ID that changes for each new request except when
1735 // being called for multiwindow assist in a single session.
1736 private int mViSessionId = 1000;
1738 final boolean mPermissionReviewRequired;
1740 private static String sTheRealBuildSerial = Build.UNKNOWN;
1743 * Current global configuration information. Contains general settings for the entire system,
1744 * also corresponds to the merged configuration of the default display.
1746 Configuration getGlobalConfiguration() {
1747 return mStackSupervisor.getConfiguration();
1750 final class KillHandler extends Handler {
1751 static final int KILL_PROCESS_GROUP_MSG = 4000;
1753 public KillHandler(Looper looper) {
1754 super(looper, null, true);
1758 public void handleMessage(Message msg) {
1760 case KILL_PROCESS_GROUP_MSG:
1762 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1763 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1764 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1769 super.handleMessage(msg);
1774 final class UiHandler extends Handler {
1775 public UiHandler() {
1776 super(com.android.server.UiThread.get().getLooper(), null, true);
1780 public void handleMessage(Message msg) {
1782 case SHOW_ERROR_UI_MSG: {
1783 mAppErrors.handleShowAppErrorUi(msg);
1784 ensureBootCompleted();
1786 case SHOW_NOT_RESPONDING_UI_MSG: {
1787 mAppErrors.handleShowAnrUi(msg);
1788 ensureBootCompleted();
1790 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1791 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1792 synchronized (ActivityManagerService.this) {
1793 ProcessRecord proc = (ProcessRecord) data.get("app");
1795 Slog.e(TAG, "App not found when showing strict mode dialog.");
1798 if (proc.crashDialog != null) {
1799 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1802 AppErrorResult res = (AppErrorResult) data.get("result");
1803 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1804 Dialog d = new StrictModeViolationDialog(mUiContext,
1805 ActivityManagerService.this, res, proc);
1807 proc.crashDialog = d;
1809 // The device is asleep, so just pretend that the user
1810 // saw a crash dialog and hit "force quit".
1814 ensureBootCompleted();
1816 case SHOW_FACTORY_ERROR_UI_MSG: {
1817 Dialog d = new FactoryErrorDialog(
1818 mUiContext, msg.getData().getCharSequence("msg"));
1820 ensureBootCompleted();
1822 case WAIT_FOR_DEBUGGER_UI_MSG: {
1823 synchronized (ActivityManagerService.this) {
1824 ProcessRecord app = (ProcessRecord)msg.obj;
1825 if (msg.arg1 != 0) {
1826 if (!app.waitedForDebugger) {
1827 Dialog d = new AppWaitingForDebuggerDialog(
1828 ActivityManagerService.this,
1831 app.waitedForDebugger = true;
1835 if (app.waitDialog != null) {
1836 app.waitDialog.dismiss();
1837 app.waitDialog = null;
1842 case SHOW_UID_ERROR_UI_MSG: {
1844 AlertDialog d = new BaseErrorDialog(mUiContext);
1845 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1846 d.setCancelable(false);
1847 d.setTitle(mUiContext.getText(R.string.android_system_label));
1848 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1849 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1850 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1854 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1856 AlertDialog d = new BaseErrorDialog(mUiContext);
1857 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1858 d.setCancelable(false);
1859 d.setTitle(mUiContext.getText(R.string.android_system_label));
1860 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1861 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1862 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1866 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1867 synchronized (ActivityManagerService.this) {
1868 ActivityRecord ar = (ActivityRecord) msg.obj;
1869 if (mCompatModeDialog != null) {
1870 if (mCompatModeDialog.mAppInfo.packageName.equals(
1871 ar.info.applicationInfo.packageName)) {
1874 mCompatModeDialog.dismiss();
1875 mCompatModeDialog = null;
1877 if (ar != null && false) {
1878 if (mCompatModePackages.getPackageAskCompatModeLocked(
1880 int mode = mCompatModePackages.computeCompatModeLocked(
1881 ar.info.applicationInfo);
1882 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1883 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1884 mCompatModeDialog = new CompatModeDialog(
1885 ActivityManagerService.this, mUiContext,
1886 ar.info.applicationInfo);
1887 mCompatModeDialog.show();
1894 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1895 synchronized (ActivityManagerService.this) {
1896 final ActivityRecord ar = (ActivityRecord) msg.obj;
1897 if (mUnsupportedDisplaySizeDialog != null) {
1898 mUnsupportedDisplaySizeDialog.dismiss();
1899 mUnsupportedDisplaySizeDialog = null;
1901 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1903 // TODO(multi-display): Show dialog on appropriate display.
1904 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1905 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1906 mUnsupportedDisplaySizeDialog.show();
1911 case START_USER_SWITCH_UI_MSG: {
1912 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1915 case DISMISS_DIALOG_UI_MSG: {
1916 final Dialog d = (Dialog) msg.obj;
1920 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1921 dispatchProcessesChanged();
1924 case DISPATCH_PROCESS_DIED_UI_MSG: {
1925 final int pid = msg.arg1;
1926 final int uid = msg.arg2;
1927 dispatchProcessDied(pid, uid);
1930 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1931 dispatchUidsChanged();
1933 case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1934 dispatchOomAdjObserver((String)msg.obj);
1936 case PUSH_TEMP_WHITELIST_UI_MSG: {
1937 pushTempWhitelist();
1943 final class MainHandler extends Handler {
1944 public MainHandler(Looper looper) {
1945 super(looper, null, true);
1949 public void handleMessage(Message msg) {
1951 case UPDATE_CONFIGURATION_MSG: {
1952 final ContentResolver resolver = mContext.getContentResolver();
1953 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1956 case GC_BACKGROUND_PROCESSES_MSG: {
1957 synchronized (ActivityManagerService.this) {
1958 performAppGcsIfAppropriateLocked();
1961 case SERVICE_TIMEOUT_MSG: {
1962 mServices.serviceTimeout((ProcessRecord)msg.obj);
1964 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1965 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1967 case SERVICE_FOREGROUND_CRASH_MSG: {
1968 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1970 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1971 RemoteCallbackList<IResultReceiver> callbacks
1972 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1973 int N = callbacks.beginBroadcast();
1974 for (int i = 0; i < N; i++) {
1976 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1977 } catch (RemoteException e) {
1980 callbacks.finishBroadcast();
1982 case UPDATE_TIME_ZONE: {
1983 synchronized (ActivityManagerService.this) {
1984 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1985 ProcessRecord r = mLruProcesses.get(i);
1986 if (r.thread != null) {
1988 r.thread.updateTimeZone();
1989 } catch (RemoteException ex) {
1990 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1996 case CLEAR_DNS_CACHE_MSG: {
1997 synchronized (ActivityManagerService.this) {
1998 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1999 ProcessRecord r = mLruProcesses.get(i);
2000 if (r.thread != null) {
2002 r.thread.clearDnsCache();
2003 } catch (RemoteException ex) {
2004 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2010 case UPDATE_HTTP_PROXY_MSG: {
2011 ProxyInfo proxy = (ProxyInfo)msg.obj;
2014 String exclList = "";
2015 Uri pacFileUrl = Uri.EMPTY;
2016 if (proxy != null) {
2017 host = proxy.getHost();
2018 port = Integer.toString(proxy.getPort());
2019 exclList = proxy.getExclusionListAsString();
2020 pacFileUrl = proxy.getPacFileUrl();
2022 synchronized (ActivityManagerService.this) {
2023 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2024 ProcessRecord r = mLruProcesses.get(i);
2025 if (r.thread != null) {
2027 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2028 } catch (RemoteException ex) {
2029 Slog.w(TAG, "Failed to update http proxy for: " +
2030 r.info.processName);
2036 case PROC_START_TIMEOUT_MSG: {
2037 ProcessRecord app = (ProcessRecord)msg.obj;
2038 synchronized (ActivityManagerService.this) {
2039 processStartTimedOutLocked(app);
2042 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2043 ProcessRecord app = (ProcessRecord)msg.obj;
2044 synchronized (ActivityManagerService.this) {
2045 processContentProviderPublishTimedOutLocked(app);
2048 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2049 synchronized (ActivityManagerService.this) {
2050 mActivityStarter.doPendingActivityLaunchesLocked(true);
2053 case KILL_APPLICATION_MSG: {
2054 synchronized (ActivityManagerService.this) {
2055 final int appId = msg.arg1;
2056 final int userId = msg.arg2;
2057 Bundle bundle = (Bundle)msg.obj;
2058 String pkg = bundle.getString("pkg");
2059 String reason = bundle.getString("reason");
2060 forceStopPackageLocked(pkg, appId, false, false, true, false,
2061 false, userId, reason);
2064 case FINALIZE_PENDING_INTENT_MSG: {
2065 ((PendingIntentRecord)msg.obj).completeFinalize();
2067 case POST_HEAVY_NOTIFICATION_MSG: {
2068 INotificationManager inm = NotificationManager.getService();
2073 ActivityRecord root = (ActivityRecord)msg.obj;
2074 ProcessRecord process = root.app;
2075 if (process == null) {
2080 Context context = mContext.createPackageContext(process.info.packageName, 0);
2081 String text = mContext.getString(R.string.heavy_weight_notification,
2082 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2083 Notification notification =
2084 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2085 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2089 .setColor(mContext.getColor(
2090 com.android.internal.R.color.system_notification_accent_color))
2091 .setContentTitle(text)
2093 mContext.getText(R.string.heavy_weight_notification_detail))
2094 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2095 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2096 new UserHandle(root.userId)))
2099 inm.enqueueNotificationWithTag("android", "android", null,
2100 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2101 notification, root.userId);
2102 } catch (RuntimeException e) {
2103 Slog.w(ActivityManagerService.TAG,
2104 "Error showing notification for heavy-weight app", e);
2105 } catch (RemoteException e) {
2107 } catch (NameNotFoundException e) {
2108 Slog.w(TAG, "Unable to create context for heavy notification", e);
2111 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2112 INotificationManager inm = NotificationManager.getService();
2117 inm.cancelNotificationWithTag("android", null,
2118 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2119 } catch (RuntimeException e) {
2120 Slog.w(ActivityManagerService.TAG,
2121 "Error canceling notification for service", e);
2122 } catch (RemoteException e) {
2125 case CHECK_EXCESSIVE_POWER_USE_MSG: {
2126 synchronized (ActivityManagerService.this) {
2127 checkExcessivePowerUsageLocked();
2128 removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2129 Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2130 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2133 case REPORT_MEM_USAGE_MSG: {
2134 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2135 Thread thread = new Thread() {
2136 @Override public void run() {
2137 reportMemUsage(memInfos);
2143 case START_USER_SWITCH_FG_MSG: {
2144 mUserController.startUserInForeground(msg.arg1);
2147 case REPORT_USER_SWITCH_MSG: {
2148 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2151 case CONTINUE_USER_SWITCH_MSG: {
2152 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2155 case USER_SWITCH_TIMEOUT_MSG: {
2156 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2159 case IMMERSIVE_MODE_LOCK_MSG: {
2160 final boolean nextState = (msg.arg1 != 0);
2161 if (mUpdateLock.isHeld() != nextState) {
2162 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2163 "Applying new update lock state '" + nextState
2164 + "' for " + (ActivityRecord)msg.obj);
2166 mUpdateLock.acquire();
2168 mUpdateLock.release();
2173 case PERSIST_URI_GRANTS_MSG: {
2174 writeGrantedUriPermissions();
2177 case REQUEST_ALL_PSS_MSG: {
2178 synchronized (ActivityManagerService.this) {
2179 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2183 case START_PROFILES_MSG: {
2184 synchronized (ActivityManagerService.this) {
2185 mUserController.startProfilesLocked();
2189 case UPDATE_TIME_PREFERENCE_MSG: {
2190 // The user's time format preference might have changed.
2191 // For convenience we re-use the Intent extra values.
2192 synchronized (ActivityManagerService.this) {
2193 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2194 ProcessRecord r = mLruProcesses.get(i);
2195 if (r.thread != null) {
2197 r.thread.updateTimePrefs(msg.arg1);
2198 } catch (RemoteException ex) {
2199 Slog.w(TAG, "Failed to update preferences for: "
2200 + r.info.processName);
2207 case SYSTEM_USER_START_MSG: {
2208 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2209 Integer.toString(msg.arg1), msg.arg1);
2210 mSystemServiceManager.startUser(msg.arg1);
2213 case SYSTEM_USER_UNLOCK_MSG: {
2214 final int userId = msg.arg1;
2215 mSystemServiceManager.unlockUser(userId);
2216 synchronized (ActivityManagerService.this) {
2217 mRecentTasks.loadUserRecentsLocked(userId);
2219 if (userId == UserHandle.USER_SYSTEM) {
2220 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2222 installEncryptionUnawareProviders(userId);
2223 mUserController.finishUserUnlocked((UserState) msg.obj);
2226 case SYSTEM_USER_CURRENT_MSG: {
2227 mBatteryStatsService.noteEvent(
2228 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2229 Integer.toString(msg.arg2), msg.arg2);
2230 mBatteryStatsService.noteEvent(
2231 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2232 Integer.toString(msg.arg1), msg.arg1);
2233 mSystemServiceManager.switchUser(msg.arg1);
2236 case ENTER_ANIMATION_COMPLETE_MSG: {
2237 synchronized (ActivityManagerService.this) {
2238 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2239 if (r != null && r.app != null && r.app.thread != null) {
2241 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2242 } catch (RemoteException e) {
2248 case FINISH_BOOTING_MSG: {
2249 if (msg.arg1 != 0) {
2250 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2252 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2254 if (msg.arg2 != 0) {
2255 enableScreenAfterBoot();
2259 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2261 Locale l = (Locale) msg.obj;
2262 IBinder service = ServiceManager.getService("mount");
2263 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2264 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2265 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2266 } catch (RemoteException e) {
2267 Log.e(TAG, "Error storing locale for decryption UI", e);
2271 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2272 final int uid = msg.arg1;
2273 final byte[] firstPacket = (byte[]) msg.obj;
2275 synchronized (mPidsSelfLocked) {
2276 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2277 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2280 p.thread.notifyCleartextNetwork(firstPacket);
2281 } catch (RemoteException ignored) {
2288 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2289 final String procName;
2291 final long memLimit;
2292 final String reportPackage;
2293 synchronized (ActivityManagerService.this) {
2294 procName = mMemWatchDumpProcName;
2295 uid = mMemWatchDumpUid;
2296 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2298 val = mMemWatchProcesses.get(procName, 0);
2301 memLimit = val.first;
2302 reportPackage = val.second;
2305 reportPackage = null;
2308 if (procName == null) {
2312 if (DEBUG_PSS) Slog.d(TAG_PSS,
2313 "Showing dump heap notification from " + procName + "/" + uid);
2315 INotificationManager inm = NotificationManager.getService();
2320 String text = mContext.getString(R.string.dump_heap_notification, procName);
2323 Intent deleteIntent = new Intent();
2324 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2325 Intent intent = new Intent();
2326 intent.setClassName("android", DumpHeapActivity.class.getName());
2327 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2328 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2329 if (reportPackage != null) {
2330 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2332 int userId = UserHandle.getUserId(uid);
2333 Notification notification =
2334 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2335 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2338 .setAutoCancel(true)
2340 .setColor(mContext.getColor(
2341 com.android.internal.R.color.system_notification_accent_color))
2342 .setContentTitle(text)
2344 mContext.getText(R.string.dump_heap_notification_detail))
2345 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2346 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2347 new UserHandle(userId)))
2348 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2349 deleteIntent, 0, UserHandle.SYSTEM))
2353 inm.enqueueNotificationWithTag("android", "android", null,
2354 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2355 notification, userId);
2356 } catch (RuntimeException e) {
2357 Slog.w(ActivityManagerService.TAG,
2358 "Error showing notification for dump heap", e);
2359 } catch (RemoteException e) {
2362 case DELETE_DUMPHEAP_MSG: {
2363 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2364 null, DumpHeapActivity.JAVA_URI,
2365 Intent.FLAG_GRANT_READ_URI_PERMISSION
2366 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2367 UserHandle.myUserId());
2368 synchronized (ActivityManagerService.this) {
2369 mMemWatchDumpFile = null;
2370 mMemWatchDumpProcName = null;
2371 mMemWatchDumpPid = -1;
2372 mMemWatchDumpUid = -1;
2375 case FOREGROUND_PROFILE_CHANGED_MSG: {
2376 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2378 case REPORT_TIME_TRACKER_MSG: {
2379 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2380 tracker.deliverResult(mContext);
2382 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2383 mUserController.dispatchUserSwitchComplete(msg.arg1);
2385 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2386 mUserController.dispatchLockedBootComplete(msg.arg1);
2388 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2389 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2391 connection.shutdown();
2392 } catch (RemoteException e) {
2393 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2395 // Only a UiAutomation can set this flag and now that
2396 // it is finished we make sure it is reset to its default.
2397 mUserIsMonkey = false;
2399 case IDLE_UIDS_MSG: {
2402 case VR_MODE_CHANGE_MSG: {
2403 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2406 synchronized (ActivityManagerService.this) {
2407 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2408 mWindowManager.disableNonVrUi(disableNonVrUi);
2409 if (disableNonVrUi) {
2410 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2411 // then remove the pinned stack.
2412 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2414 if (pinnedStack != null) {
2415 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2420 case DISPATCH_SCREEN_AWAKE_MSG: {
2421 final boolean isAwake = msg.arg1 != 0;
2422 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2423 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2426 case DISPATCH_SCREEN_KEYGUARD_MSG: {
2427 final boolean isShowing = msg.arg1 != 0;
2428 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2429 mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2432 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2433 synchronized (ActivityManagerService.this) {
2434 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2435 ProcessRecord r = mLruProcesses.get(i);
2436 if (r.thread != null) {
2438 r.thread.handleTrustStorageUpdate();
2439 } catch (RemoteException ex) {
2440 Slog.w(TAG, "Failed to handle trust storage update for: " +
2441 r.info.processName);
2451 static final int COLLECT_PSS_BG_MSG = 1;
2453 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2455 public void handleMessage(Message msg) {
2457 case COLLECT_PSS_BG_MSG: {
2458 long start = SystemClock.uptimeMillis();
2459 MemInfoReader memInfo = null;
2460 synchronized (ActivityManagerService.this) {
2461 if (mFullPssPending) {
2462 mFullPssPending = false;
2463 memInfo = new MemInfoReader();
2466 if (memInfo != null) {
2467 updateCpuStatsNow();
2468 long nativeTotalPss = 0;
2469 final List<ProcessCpuTracker.Stats> stats;
2470 synchronized (mProcessCpuTracker) {
2471 stats = mProcessCpuTracker.getStats( (st)-> {
2472 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2475 final int N = stats.size();
2476 for (int j = 0; j < N; j++) {
2477 synchronized (mPidsSelfLocked) {
2478 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2479 // This is one of our own processes; skip it.
2483 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2485 memInfo.readMemInfo();
2486 synchronized (ActivityManagerService.this) {
2487 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2488 + (SystemClock.uptimeMillis()-start) + "ms");
2489 final long cachedKb = memInfo.getCachedSizeKb();
2490 final long freeKb = memInfo.getFreeSizeKb();
2491 final long zramKb = memInfo.getZramTotalSizeKb();
2492 final long kernelKb = memInfo.getKernelUsedSizeKb();
2493 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2494 kernelKb*1024, nativeTotalPss*1024);
2495 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2501 long[] tmp = new long[2];
2507 synchronized (ActivityManagerService.this) {
2508 if (mPendingPssProcesses.size() <= 0) {
2509 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2510 "Collected PSS of " + num + " processes in "
2511 + (SystemClock.uptimeMillis() - start) + "ms");
2512 mPendingPssProcesses.clear();
2515 proc = mPendingPssProcesses.remove(0);
2516 procState = proc.pssProcState;
2517 lastPssTime = proc.lastPssTime;
2518 if (proc.thread != null && procState == proc.setProcState
2519 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2520 < SystemClock.uptimeMillis()) {
2528 long pss = Debug.getPss(pid, tmp, null);
2529 synchronized (ActivityManagerService.this) {
2530 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2531 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2533 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2534 SystemClock.uptimeMillis());
2544 public void setSystemProcess() {
2546 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2547 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2548 ServiceManager.addService("meminfo", new MemBinder(this));
2549 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2550 ServiceManager.addService("dbinfo", new DbBinder(this));
2551 if (MONITOR_CPU_USAGE) {
2552 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2554 ServiceManager.addService("permission", new PermissionController(this));
2555 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2557 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2558 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2559 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2561 synchronized (this) {
2562 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2563 app.persistent = true;
2565 app.maxAdj = ProcessList.SYSTEM_ADJ;
2566 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2567 synchronized (mPidsSelfLocked) {
2568 mPidsSelfLocked.put(app.pid, app);
2570 updateLruProcessLocked(app, false, null);
2571 updateOomAdjLocked();
2573 } catch (PackageManager.NameNotFoundException e) {
2574 throw new RuntimeException(
2575 "Unable to find android system package", e);
2579 public void setWindowManager(WindowManagerService wm) {
2580 mWindowManager = wm;
2581 mStackSupervisor.setWindowManager(wm);
2582 mActivityStarter.setWindowManager(wm);
2585 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2586 mUsageStatsService = usageStatsManager;
2589 public void startObservingNativeCrashes() {
2590 final NativeCrashListener ncl = new NativeCrashListener(this);
2594 public IAppOpsService getAppOpsService() {
2595 return mAppOpsService;
2598 static class MemBinder extends Binder {
2599 ActivityManagerService mActivityManagerService;
2600 MemBinder(ActivityManagerService activityManagerService) {
2601 mActivityManagerService = activityManagerService;
2605 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2606 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2607 "meminfo", pw)) return;
2608 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2612 static class GraphicsBinder extends Binder {
2613 ActivityManagerService mActivityManagerService;
2614 GraphicsBinder(ActivityManagerService activityManagerService) {
2615 mActivityManagerService = activityManagerService;
2619 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2620 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2621 "gfxinfo", pw)) return;
2622 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2626 static class DbBinder extends Binder {
2627 ActivityManagerService mActivityManagerService;
2628 DbBinder(ActivityManagerService activityManagerService) {
2629 mActivityManagerService = activityManagerService;
2633 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2634 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2635 "dbinfo", pw)) return;
2636 mActivityManagerService.dumpDbInfo(fd, pw, args);
2640 static class CpuBinder extends Binder {
2641 ActivityManagerService mActivityManagerService;
2642 CpuBinder(ActivityManagerService activityManagerService) {
2643 mActivityManagerService = activityManagerService;
2647 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2648 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2649 "cpuinfo", pw)) return;
2650 synchronized (mActivityManagerService.mProcessCpuTracker) {
2651 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2652 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2653 SystemClock.uptimeMillis()));
2658 public static final class Lifecycle extends SystemService {
2659 private final ActivityManagerService mService;
2661 public Lifecycle(Context context) {
2663 mService = new ActivityManagerService(context);
2667 public void onStart() {
2672 public void onCleanupUser(int userId) {
2673 mService.mBatteryStatsService.onCleanupUser(userId);
2676 public ActivityManagerService getService() {
2682 public ActivityManagerService(Injector injector) {
2683 mInjector = injector;
2684 mContext = mInjector.getContext();
2687 mActivityStarter = null;
2689 mAppOpsService = mInjector.getAppOpsService(null, null);
2690 mBatteryStatsService = null;
2691 mCompatModePackages = null;
2695 mHandlerThread = null;
2696 mIntentFirewall = null;
2697 mKeyguardController = null;
2698 mPermissionReviewRequired = false;
2699 mProcessCpuThread = null;
2700 mProcessStats = null;
2701 mProviderMap = null;
2702 mRecentTasks = null;
2704 mStackSupervisor = null;
2705 mSystemThread = null;
2706 mTaskChangeNotificationController = null;
2707 mUiHandler = injector.getUiHandler(null);
2708 mUserController = null;
2709 mVrController = null;
2712 // Note: This method is invoked on the main thread but may need to attach various
2713 // handlers to other threads. So take care to be explicit about the looper.
2714 public ActivityManagerService(Context systemContext) {
2715 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2716 mInjector = new Injector();
2717 mContext = systemContext;
2719 mFactoryTest = FactoryTest.getMode();
2720 mSystemThread = ActivityThread.currentActivityThread();
2721 mUiContext = mSystemThread.getSystemUiContext();
2723 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2725 mPermissionReviewRequired = mContext.getResources().getBoolean(
2726 com.android.internal.R.bool.config_permissionReviewRequired);
2728 mHandlerThread = new ServiceThread(TAG,
2729 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2730 mHandlerThread.start();
2731 mHandler = new MainHandler(mHandlerThread.getLooper());
2732 mUiHandler = mInjector.getUiHandler(this);
2734 mConstants = new ActivityManagerConstants(this, mHandler);
2736 /* static; one-time init here */
2737 if (sKillHandler == null) {
2738 sKillThread = new ServiceThread(TAG + ":kill",
2739 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2740 sKillThread.start();
2741 sKillHandler = new KillHandler(sKillThread.getLooper());
2744 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2745 "foreground", BROADCAST_FG_TIMEOUT, false);
2746 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2747 "background", BROADCAST_BG_TIMEOUT, true);
2748 mBroadcastQueues[0] = mFgBroadcastQueue;
2749 mBroadcastQueues[1] = mBgBroadcastQueue;
2751 mServices = new ActiveServices(this);
2752 mProviderMap = new ProviderMap(this);
2753 mAppErrors = new AppErrors(mUiContext, this);
2755 // TODO: Move creation of battery stats service outside of activity manager service.
2756 File dataDir = Environment.getDataDirectory();
2757 File systemDir = new File(dataDir, "system");
2759 mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2760 mBatteryStatsService.getActiveStatistics().readLocked();
2761 mBatteryStatsService.scheduleWriteToDisk();
2762 mOnBattery = DEBUG_POWER ? true
2763 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2764 mBatteryStatsService.getActiveStatistics().setCallback(this);
2766 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2768 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2769 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2770 new IAppOpsCallback.Stub() {
2771 @Override public void opChanged(int op, int uid, String packageName) {
2772 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2773 if (mAppOpsService.checkOperation(op, uid, packageName)
2774 != AppOpsManager.MODE_ALLOWED) {
2775 runInBackgroundDisabled(uid);
2781 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2783 mUserController = new UserController(this);
2785 mVrController = new VrController(this);
2787 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2788 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2790 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2791 mUseFifoUiScheduling = true;
2794 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2795 mTempConfig.setToDefaults();
2796 mTempConfig.setLocales(LocaleList.getDefault());
2797 mConfigurationSeq = mTempConfig.seq = 1;
2798 mStackSupervisor = createStackSupervisor();
2799 mStackSupervisor.onConfigurationChanged(mTempConfig);
2800 mKeyguardController = mStackSupervisor.mKeyguardController;
2801 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2802 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2803 mTaskChangeNotificationController =
2804 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2805 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2806 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2808 mProcessCpuThread = new Thread("CpuTracker") {
2811 synchronized (mProcessCpuTracker) {
2812 mProcessCpuInitLatch.countDown();
2813 mProcessCpuTracker.init();
2818 synchronized(this) {
2819 final long now = SystemClock.uptimeMillis();
2820 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2821 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2822 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2823 // + ", write delay=" + nextWriteDelay);
2824 if (nextWriteDelay < nextCpuDelay) {
2825 nextCpuDelay = nextWriteDelay;
2827 if (nextCpuDelay > 0) {
2828 mProcessCpuMutexFree.set(true);
2829 this.wait(nextCpuDelay);
2832 } catch (InterruptedException e) {
2834 updateCpuStatsNow();
2835 } catch (Exception e) {
2836 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2842 Watchdog.getInstance().addMonitor(this);
2843 Watchdog.getInstance().addThread(mHandler);
2846 protected ActivityStackSupervisor createStackSupervisor() {
2847 return new ActivityStackSupervisor(this, mHandler.getLooper());
2850 public void setSystemServiceManager(SystemServiceManager mgr) {
2851 mSystemServiceManager = mgr;
2854 public void setInstaller(Installer installer) {
2855 mInstaller = installer;
2858 private void start() {
2859 removeAllProcessGroups();
2860 mProcessCpuThread.start();
2862 mBatteryStatsService.publish();
2863 mAppOpsService.publish(mContext);
2864 Slog.d("AppOps", "AppOpsService published");
2865 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2866 // Wait for the synchronized block started in mProcessCpuThread,
2867 // so that any other acccess to mProcessCpuTracker from main thread
2868 // will be blocked during mProcessCpuTracker initialization.
2870 mProcessCpuInitLatch.await();
2871 } catch (InterruptedException e) {
2872 Slog.wtf(TAG, "Interrupted wait during start", e);
2873 Thread.currentThread().interrupt();
2874 throw new IllegalStateException("Interrupted wait during start");
2878 void onUserStoppedLocked(int userId) {
2879 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2882 public void initPowerManagement() {
2883 mStackSupervisor.initPowerManagement();
2884 mBatteryStatsService.initPowerManagement();
2885 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2886 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2887 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2888 mVoiceWakeLock.setReferenceCounted(false);
2891 private ArraySet<String> getBackgroundLaunchBroadcasts() {
2892 if (mBackgroundLaunchBroadcasts == null) {
2893 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2895 return mBackgroundLaunchBroadcasts;
2899 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2900 throws RemoteException {
2901 if (code == SYSPROPS_TRANSACTION) {
2902 // We need to tell all apps about the system property change.
2903 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2904 synchronized(this) {
2905 final int NP = mProcessNames.getMap().size();
2906 for (int ip=0; ip<NP; ip++) {
2907 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2908 final int NA = apps.size();
2909 for (int ia=0; ia<NA; ia++) {
2910 ProcessRecord app = apps.valueAt(ia);
2911 if (app.thread != null) {
2912 procs.add(app.thread.asBinder());
2918 int N = procs.size();
2919 for (int i=0; i<N; i++) {
2920 Parcel data2 = Parcel.obtain();
2922 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2923 Binder.FLAG_ONEWAY);
2924 } catch (RemoteException e) {
2930 return super.onTransact(code, data, reply, flags);
2931 } catch (RuntimeException e) {
2932 // The activity manager only throws security exceptions, so let's
2934 if (!(e instanceof SecurityException)) {
2935 Slog.wtf(TAG, "Activity Manager Crash."
2936 + " UID:" + Binder.getCallingUid()
2937 + " PID:" + Binder.getCallingPid()
2938 + " TRANS:" + code, e);
2944 void updateCpuStats() {
2945 final long now = SystemClock.uptimeMillis();
2946 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2949 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2950 synchronized (mProcessCpuThread) {
2951 mProcessCpuThread.notify();
2956 void updateCpuStatsNow() {
2957 synchronized (mProcessCpuTracker) {
2958 mProcessCpuMutexFree.set(false);
2959 final long now = SystemClock.uptimeMillis();
2960 boolean haveNewCpuStats = false;
2962 if (MONITOR_CPU_USAGE &&
2963 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2964 mLastCpuTime.set(now);
2965 mProcessCpuTracker.update();
2966 if (mProcessCpuTracker.hasGoodLastStats()) {
2967 haveNewCpuStats = true;
2968 //Slog.i(TAG, mProcessCpu.printCurrentState());
2969 //Slog.i(TAG, "Total CPU usage: "
2970 // + mProcessCpu.getTotalCpuPercent() + "%");
2972 // Slog the cpu usage if the property is set.
2973 if ("true".equals(SystemProperties.get("events.cpu"))) {
2974 int user = mProcessCpuTracker.getLastUserTime();
2975 int system = mProcessCpuTracker.getLastSystemTime();
2976 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2977 int irq = mProcessCpuTracker.getLastIrqTime();
2978 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2979 int idle = mProcessCpuTracker.getLastIdleTime();
2981 int total = user + system + iowait + irq + softIrq + idle;
2982 if (total == 0) total = 1;
2984 EventLog.writeEvent(EventLogTags.CPU,
2985 ((user+system+iowait+irq+softIrq) * 100) / total,
2986 (user * 100) / total,
2987 (system * 100) / total,
2988 (iowait * 100) / total,
2989 (irq * 100) / total,
2990 (softIrq * 100) / total);
2995 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2996 synchronized(bstats) {
2997 synchronized(mPidsSelfLocked) {
2998 if (haveNewCpuStats) {
2999 if (bstats.startAddingCpuLocked()) {
3002 final int N = mProcessCpuTracker.countStats();
3003 for (int i=0; i<N; i++) {
3004 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3008 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3009 totalUTime += st.rel_utime;
3010 totalSTime += st.rel_stime;
3012 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3013 if (ps == null || !ps.isActive()) {
3014 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3015 pr.info.uid, pr.processName);
3017 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3018 pr.curCpuTime += st.rel_utime + st.rel_stime;
3019 if (pr.lastCpuTime == 0) {
3020 pr.lastCpuTime = pr.curCpuTime;
3023 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3024 if (ps == null || !ps.isActive()) {
3025 st.batteryStats = ps = bstats.getProcessStatsLocked(
3026 bstats.mapUid(st.uid), st.name);
3028 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3031 final int userTime = mProcessCpuTracker.getLastUserTime();
3032 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3033 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3034 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3035 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3036 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3037 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3038 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3043 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3044 mLastWriteTime = now;
3045 mBatteryStatsService.scheduleWriteToDisk();
3052 public void batteryNeedsCpuUpdate() {
3053 updateCpuStatsNow();
3057 public void batteryPowerChanged(boolean onBattery) {
3058 // When plugging in, update the CPU stats first before changing
3060 updateCpuStatsNow();
3061 synchronized (this) {
3062 synchronized(mPidsSelfLocked) {
3063 mOnBattery = DEBUG_POWER ? true : onBattery;
3069 public void batterySendBroadcast(Intent intent) {
3070 synchronized (this) {
3071 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3072 AppOpsManager.OP_NONE, null, false, false,
3073 -1, SYSTEM_UID, UserHandle.USER_ALL);
3078 * Initialize the application bind args. These are passed to each
3079 * process when the bindApplication() IPC is sent to the process. They're
3080 * lazily setup to make sure the services are running when they're asked for.
3082 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3083 // Isolated processes won't get this optimization, so that we don't
3084 // violate the rules about which services they have access to.
3086 if (mIsolatedAppBindArgs == null) {
3087 mIsolatedAppBindArgs = new HashMap<>();
3088 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3090 return mIsolatedAppBindArgs;
3093 if (mAppBindArgs == null) {
3094 mAppBindArgs = new HashMap<>();
3096 // Setup the application init args
3097 mAppBindArgs.put("package", ServiceManager.getService("package"));
3098 mAppBindArgs.put("window", ServiceManager.getService("window"));
3099 mAppBindArgs.put(Context.ALARM_SERVICE,
3100 ServiceManager.getService(Context.ALARM_SERVICE));
3102 return mAppBindArgs;
3106 * Update AMS states when an activity is resumed. This should only be called by
3107 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3109 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3110 final TaskRecord task = r.getTask();
3111 if (task.isApplicationTask()) {
3112 if (mCurAppTimeTracker != r.appTimeTracker) {
3113 // We are switching app tracking. Complete the current one.
3114 if (mCurAppTimeTracker != null) {
3115 mCurAppTimeTracker.stop();
3116 mHandler.obtainMessage(
3117 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3118 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3119 mCurAppTimeTracker = null;
3121 if (r.appTimeTracker != null) {
3122 mCurAppTimeTracker = r.appTimeTracker;
3123 startTimeTrackingFocusedActivityLocked();
3126 startTimeTrackingFocusedActivityLocked();
3129 r.appTimeTracker = null;
3131 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3132 // TODO: Probably not, because we don't want to resume voice on switching
3133 // back to this activity
3134 if (task.voiceInteractor != null) {
3135 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3137 finishRunningVoiceLocked();
3139 if (mLastResumedActivity != null) {
3140 final IVoiceInteractionSession session;
3142 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3143 if (lastResumedActivityTask != null
3144 && lastResumedActivityTask.voiceSession != null) {
3145 session = lastResumedActivityTask.voiceSession;
3147 session = mLastResumedActivity.voiceSession;
3150 if (session != null) {
3151 // We had been in a voice interaction session, but now focused has
3152 // move to something different. Just finish the session, we can't
3153 // return to it and retain the proper state and synchronization with
3154 // the voice interaction service.
3155 finishVoiceTask(session);
3160 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3161 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3162 mHandler.obtainMessage(
3163 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3165 mLastResumedActivity = r;
3167 mWindowManager.setFocusedApp(r.appToken, true);
3169 applyUpdateLockStateLocked(r);
3170 applyUpdateVrModeLocked(r);
3172 EventLogTags.writeAmSetResumedActivity(
3173 r == null ? -1 : r.userId,
3174 r == null ? "NULL" : r.shortComponentName,
3179 public void setFocusedStack(int stackId) {
3180 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3181 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3182 final long callingId = Binder.clearCallingIdentity();
3184 synchronized (this) {
3185 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3186 if (stack == null) {
3189 final ActivityRecord r = stack.topRunningActivityLocked();
3190 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3191 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3195 Binder.restoreCallingIdentity(callingId);
3200 public void setFocusedTask(int taskId) {
3201 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3202 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3203 final long callingId = Binder.clearCallingIdentity();
3205 synchronized (this) {
3206 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3210 final ActivityRecord r = task.topRunningActivityLocked();
3211 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3212 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3216 Binder.restoreCallingIdentity(callingId);
3220 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3222 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3223 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3224 mTaskChangeNotificationController.registerTaskStackListener(listener);
3228 * Unregister a task stack listener so that it stops receiving callbacks.
3231 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3232 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3233 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3237 public void notifyActivityDrawn(IBinder token) {
3238 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3239 synchronized (this) {
3240 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3242 r.getStack().notifyActivityDrawnLocked(r);
3247 final void applyUpdateLockStateLocked(ActivityRecord r) {
3248 // Modifications to the UpdateLock state are done on our handler, outside
3249 // the activity manager's locks. The new state is determined based on the
3250 // state *now* of the relevant activity record. The object is passed to
3251 // the handler solely for logging detail, not to be consulted/modified.
3252 final boolean nextState = r != null && r.immersive;
3253 mHandler.sendMessage(
3254 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3257 final void applyUpdateVrModeLocked(ActivityRecord r) {
3258 // VR apps are expected to run in a main display. If an app is turning on VR for
3259 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3260 // fullscreen stack before enabling VR Mode.
3261 // TODO: The goal of this code is to keep the VR app on the main display. When the
3262 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3263 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3264 // option would be a better choice here.
3265 if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3266 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3267 + " to main stack for VR");
3268 moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3270 mHandler.sendMessage(
3271 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3274 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3275 Message msg = Message.obtain();
3276 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3277 msg.obj = r.getTask().askedCompatMode ? null : r;
3278 mUiHandler.sendMessage(msg);
3281 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3282 final Configuration globalConfig = getGlobalConfiguration();
3283 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3284 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3285 final Message msg = Message.obtain();
3286 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3288 mUiHandler.sendMessage(msg);
3292 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3293 String what, Object obj, ProcessRecord srcApp) {
3294 app.lastActivityTime = now;
3296 if (app.activities.size() > 0) {
3297 // Don't want to touch dependent processes that are hosting activities.
3301 int lrui = mLruProcesses.lastIndexOf(app);
3303 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3304 + what + " " + obj + " from " + srcApp);
3308 if (lrui >= index) {
3309 // Don't want to cause this to move dependent processes *back* in the
3310 // list as if they were less frequently used.
3314 if (lrui >= mLruProcessActivityStart) {
3315 // Don't want to touch dependent processes that are hosting activities.
3319 mLruProcesses.remove(lrui);
3323 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3324 + " in LRU list: " + app);
3325 mLruProcesses.add(index, app);
3329 static void killProcessGroup(int uid, int pid) {
3330 if (sKillHandler != null) {
3331 sKillHandler.sendMessage(
3332 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3334 Slog.w(TAG, "Asked to kill process group before system bringup!");
3335 Process.killProcessGroup(uid, pid);
3339 final void removeLruProcessLocked(ProcessRecord app) {
3340 int lrui = mLruProcesses.lastIndexOf(app);
3343 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3344 killProcessQuiet(app.pid);
3345 killProcessGroup(app.uid, app.pid);
3347 if (lrui <= mLruProcessActivityStart) {
3348 mLruProcessActivityStart--;
3350 if (lrui <= mLruProcessServiceStart) {
3351 mLruProcessServiceStart--;
3353 mLruProcesses.remove(lrui);
3357 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3358 ProcessRecord client) {
3359 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3360 || app.treatLikeActivity;
3361 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3362 if (!activityChange && hasActivity) {
3363 // The process has activities, so we are only allowing activity-based adjustments
3364 // to move it. It should be kept in the front of the list with other
3365 // processes that have activities, and we don't want those to change their
3366 // order except due to activity operations.
3371 final long now = SystemClock.uptimeMillis();
3372 app.lastActivityTime = now;
3374 // First a quick reject: if the app is already at the position we will
3375 // put it, then there is nothing to do.
3377 final int N = mLruProcesses.size();
3378 if (N > 0 && mLruProcesses.get(N-1) == app) {
3379 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3383 if (mLruProcessServiceStart > 0
3384 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3385 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3390 int lrui = mLruProcesses.lastIndexOf(app);
3392 if (app.persistent && lrui >= 0) {
3393 // We don't care about the position of persistent processes, as long as
3394 // they are in the list.
3395 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3399 /* In progress: compute new position first, so we can avoid doing work
3400 if the process is not actually going to move. Not yet working.
3403 boolean inActivity = false, inService = false;
3405 // Process has activities, put it at the very tipsy-top.
3406 addIndex = mLruProcesses.size();
3407 nextIndex = mLruProcessServiceStart;
3409 } else if (hasService) {
3410 // Process has services, put it at the top of the service list.
3411 addIndex = mLruProcessActivityStart;
3412 nextIndex = mLruProcessServiceStart;
3416 // Process not otherwise of interest, it goes to the top of the non-service area.
3417 addIndex = mLruProcessServiceStart;
3418 if (client != null) {
3419 int clientIndex = mLruProcesses.lastIndexOf(client);
3420 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3422 if (clientIndex >= 0 && addIndex > clientIndex) {
3423 addIndex = clientIndex;
3426 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3429 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3430 + mLruProcessActivityStart + "): " + app);
3434 if (lrui < mLruProcessActivityStart) {
3435 mLruProcessActivityStart--;
3437 if (lrui < mLruProcessServiceStart) {
3438 mLruProcessServiceStart--;
3441 if (addIndex > lrui) {
3444 if (nextIndex > lrui) {
3448 mLruProcesses.remove(lrui);
3452 mLruProcesses.add(addIndex, app);
3454 mLruProcessActivityStart++;
3457 mLruProcessActivityStart++;
3463 final int N = mLruProcesses.size();
3464 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3465 // Process doesn't have activities, but has clients with
3466 // activities... move it up, but one below the top (the top
3467 // should always have a real activity).
3468 if (DEBUG_LRU) Slog.d(TAG_LRU,
3469 "Adding to second-top of LRU activity list: " + app);
3470 mLruProcesses.add(N - 1, app);
3471 // To keep it from spamming the LRU list (by making a bunch of clients),
3472 // we will push down any other entries owned by the app.
3473 final int uid = app.info.uid;
3474 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3475 ProcessRecord subProc = mLruProcesses.get(i);
3476 if (subProc.info.uid == uid) {
3477 // We want to push this one down the list. If the process after
3478 // it is for the same uid, however, don't do so, because we don't
3479 // want them internally to be re-ordered.
3480 if (mLruProcesses.get(i - 1).info.uid != uid) {
3481 if (DEBUG_LRU) Slog.d(TAG_LRU,
3482 "Pushing uid " + uid + " swapping at " + i + ": "
3483 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3484 ProcessRecord tmp = mLruProcesses.get(i);
3485 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3486 mLruProcesses.set(i - 1, tmp);
3490 // A gap, we can stop here.
3495 // Process has activities, put it at the very tipsy-top.
3496 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3497 mLruProcesses.add(app);
3499 nextIndex = mLruProcessServiceStart;
3500 } else if (hasService) {
3501 // Process has services, put it at the top of the service list.
3502 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3503 mLruProcesses.add(mLruProcessActivityStart, app);
3504 nextIndex = mLruProcessServiceStart;
3505 mLruProcessActivityStart++;
3507 // Process not otherwise of interest, it goes to the top of the non-service area.
3508 int index = mLruProcessServiceStart;
3509 if (client != null) {
3510 // If there is a client, don't allow the process to be moved up higher
3511 // in the list than that client.
3512 int clientIndex = mLruProcesses.lastIndexOf(client);
3513 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3514 + " when updating " + app);
3515 if (clientIndex <= lrui) {
3516 // Don't allow the client index restriction to push it down farther in the
3517 // list than it already is.
3520 if (clientIndex >= 0 && index > clientIndex) {
3521 index = clientIndex;
3524 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3525 mLruProcesses.add(index, app);
3526 nextIndex = index-1;
3527 mLruProcessActivityStart++;
3528 mLruProcessServiceStart++;
3531 // If the app is currently using a content provider or service,
3532 // bump those processes as well.
3533 for (int j=app.connections.size()-1; j>=0; j--) {
3534 ConnectionRecord cr = app.connections.valueAt(j);
3535 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3536 && cr.binding.service.app != null
3537 && cr.binding.service.app.lruSeq != mLruSeq
3538 && !cr.binding.service.app.persistent) {
3539 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3540 "service connection", cr, app);
3543 for (int j=app.conProviders.size()-1; j>=0; j--) {
3544 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3545 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3546 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3547 "provider reference", cpr, app);
3552 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3553 if (uid == SYSTEM_UID) {
3554 // The system gets to run in any process. If there are multiple
3555 // processes with the same uid, just pick the first (this
3556 // should never happen).
3557 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3558 if (procs == null) return null;
3559 final int procCount = procs.size();
3560 for (int i = 0; i < procCount; i++) {
3561 final int procUid = procs.keyAt(i);
3562 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3563 // Don't use an app process or different user process for system component.
3566 return procs.valueAt(i);
3569 ProcessRecord proc = mProcessNames.get(processName, uid);
3570 if (false && proc != null && !keepIfLarge
3571 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3572 && proc.lastCachedPss >= 4000) {
3573 // Turn this condition on to cause killing to happen regularly, for testing.
3574 if (proc.baseProcessTracker != null) {
3575 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3577 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3578 } else if (proc != null && !keepIfLarge
3579 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3580 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3581 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3582 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3583 if (proc.baseProcessTracker != null) {
3584 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3586 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3592 void notifyPackageUse(String packageName, int reason) {
3593 synchronized(this) {
3594 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3598 boolean isNextTransitionForward() {
3599 int transit = mWindowManager.getPendingAppTransition();
3600 return transit == TRANSIT_ACTIVITY_OPEN
3601 || transit == TRANSIT_TASK_OPEN
3602 || transit == TRANSIT_TASK_TO_FRONT;
3605 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3606 String processName, String abiOverride, int uid, Runnable crashHandler) {
3607 synchronized(this) {
3608 ApplicationInfo info = new ApplicationInfo();
3609 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3610 // For isolated processes, the former contains the parent's uid and the latter the
3611 // actual uid of the isolated process.
3612 // In the special case introduced by this method (which is, starting an isolated
3613 // process directly from the SystemServer without an actual parent app process) the
3614 // closest thing to a parent's uid is SYSTEM_UID.
3615 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3616 // the |isolated| logic in the ProcessRecord constructor.
3617 info.uid = SYSTEM_UID;
3618 info.processName = processName;
3619 info.className = entryPoint;
3620 info.packageName = "android";
3621 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3622 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3623 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3624 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3625 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3627 return proc != null ? proc.pid : 0;
3631 final ProcessRecord startProcessLocked(String processName,
3632 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3633 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3634 boolean isolated, boolean keepIfLarge) {
3635 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3636 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3637 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3638 null /* crashHandler */);
3641 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3642 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3643 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3644 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3645 long startTime = SystemClock.elapsedRealtime();
3648 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3649 checkTime(startTime, "startProcess: after getProcessRecord");
3651 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3652 // If we are in the background, then check to see if this process
3653 // is bad. If so, we will just silently fail.
3654 if (mAppErrors.isBadProcessLocked(info)) {
3655 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3656 + "/" + info.processName);
3660 // When the user is explicitly starting a process, then clear its
3661 // crash count so that we won't make it bad until they see at
3662 // least one crash dialog again, and make the process good again
3663 // if it had been bad.
3664 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3665 + "/" + info.processName);
3666 mAppErrors.resetProcessCrashTimeLocked(info);
3667 if (mAppErrors.isBadProcessLocked(info)) {
3668 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3669 UserHandle.getUserId(info.uid), info.uid,
3671 mAppErrors.clearBadProcessLocked(info);
3678 // If this is an isolated process, it can't re-use an existing process.
3682 // We don't have to do anything more if:
3683 // (1) There is an existing application record; and
3684 // (2) The caller doesn't think it is dead, OR there is no thread
3685 // object attached to it so we know it couldn't have crashed; and
3686 // (3) There is a pid assigned to it, so it is either starting or
3688 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3689 + " app=" + app + " knownToBeDead=" + knownToBeDead
3690 + " thread=" + (app != null ? app.thread : null)
3691 + " pid=" + (app != null ? app.pid : -1));
3692 if (app != null && app.pid > 0) {
3693 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3694 // We already have the app running, or are waiting for it to
3695 // come up (we have a pid but not yet its thread), so keep it.
3696 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3697 // If this is a new package in the process, add the package to the list
3698 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3699 checkTime(startTime, "startProcess: done, added package to proc");
3703 // An application record is attached to a previous process,
3705 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3706 checkTime(startTime, "startProcess: bad proc running, killing");
3707 killProcessGroup(app.uid, app.pid);
3708 handleAppDiedLocked(app, true, true);
3709 checkTime(startTime, "startProcess: done killing old proc");
3712 String hostingNameStr = hostingName != null
3713 ? hostingName.flattenToShortString() : null;
3716 checkTime(startTime, "startProcess: creating new process record");
3717 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3719 Slog.w(TAG, "Failed making new process record for "
3720 + processName + "/" + info.uid + " isolated=" + isolated);
3723 app.crashHandler = crashHandler;
3724 checkTime(startTime, "startProcess: done creating new process record");
3726 // If this is a new package in the process, add the package to the list
3727 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3728 checkTime(startTime, "startProcess: added package to existing proc");
3731 // If the system is not ready yet, then hold off on starting this
3732 // process until it is.
3733 if (!mProcessesReady
3734 && !isAllowedWhileBooting(info)
3735 && !allowWhileBooting) {
3736 if (!mProcessesOnHold.contains(app)) {
3737 mProcessesOnHold.add(app);
3739 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3740 "System not ready, putting on hold: " + app);
3741 checkTime(startTime, "startProcess: returning with proc on hold");
3745 checkTime(startTime, "startProcess: stepping in to startProcess");
3747 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3748 checkTime(startTime, "startProcess: done starting proc!");
3749 return (app.pid != 0) ? app : null;
3752 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3753 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3756 private final void startProcessLocked(ProcessRecord app,
3757 String hostingType, String hostingNameStr) {
3758 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3759 null /* entryPoint */, null /* entryPointArgs */);
3762 private final void startProcessLocked(ProcessRecord app, String hostingType,
3763 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3764 long startTime = SystemClock.elapsedRealtime();
3765 if (app.pid > 0 && app.pid != MY_PID) {
3766 checkTime(startTime, "startProcess: removing from pids map");
3767 synchronized (mPidsSelfLocked) {
3768 mPidsSelfLocked.remove(app.pid);
3769 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3771 checkTime(startTime, "startProcess: done removing from pids map");
3775 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3776 "startProcessLocked removing on hold: " + app);
3777 mProcessesOnHold.remove(app);
3779 checkTime(startTime, "startProcess: starting to update cpu stats");
3781 checkTime(startTime, "startProcess: done updating cpu stats");
3785 final int userId = UserHandle.getUserId(app.uid);
3786 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3787 } catch (RemoteException e) {
3788 throw e.rethrowAsRuntimeException();
3793 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3794 if (!app.isolated) {
3795 int[] permGids = null;
3797 checkTime(startTime, "startProcess: getting gids from package manager");
3798 final IPackageManager pm = AppGlobals.getPackageManager();
3799 permGids = pm.getPackageGids(app.info.packageName,
3800 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3801 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3802 StorageManagerInternal.class);
3803 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3804 app.info.packageName);
3805 } catch (RemoteException e) {
3806 throw e.rethrowAsRuntimeException();
3810 * Add shared application and profile GIDs so applications can share some
3811 * resources like shared libraries and access user-wide resources
3813 if (ArrayUtils.isEmpty(permGids)) {
3816 gids = new int[permGids.length + 3];
3817 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3819 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3820 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3821 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3823 // Replace any invalid GIDs
3824 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
3825 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
3827 checkTime(startTime, "startProcess: building args");
3828 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3829 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3830 && mTopComponent != null
3831 && app.processName.equals(mTopComponent.getPackageName())) {
3834 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3835 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3839 int runtimeFlags = 0;
3840 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3841 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3842 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3843 // Also turn on CheckJNI for debuggable apps. It's quite
3844 // awkward to turn on otherwise.
3845 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3847 // Run the app in safe mode if its manifest requests so or the
3848 // system is booted in safe mode.
3849 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3850 mSafeMode == true) {
3851 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3853 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3854 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3856 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3857 if ("true".equals(genDebugInfoProperty)) {
3858 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3860 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3861 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3863 if ("1".equals(SystemProperties.get("debug.assert"))) {
3864 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3866 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3867 // Enable all debug flags required by the native debugger.
3868 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3869 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3870 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3871 mNativeDebuggingApp = null;
3874 if (app.info.isPrivilegedApp() &&
3875 !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
3876 runtimeFlags |= Zygote.DISABLE_VERIFIER;
3877 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
3880 String invokeWith = null;
3881 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3882 // Debuggable apps may include a wrapper script with their library directory.
3883 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3884 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3886 if (new File(wrapperFileName).exists()) {
3887 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3890 StrictMode.setThreadPolicy(oldPolicy);
3894 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3895 if (requiredAbi == null) {
3896 requiredAbi = Build.SUPPORTED_ABIS[0];
3899 String instructionSet = null;
3900 if (app.info.primaryCpuAbi != null) {
3901 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3905 app.requiredAbi = requiredAbi;
3906 app.instructionSet = instructionSet;
3908 // the per-user SELinux context must be set
3909 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3910 Slog.wtf(TAG, "SELinux tag not defined",
3911 new IllegalStateException("SELinux tag not defined for "
3912 + app.info.packageName + " (uid " + app.uid + ")"));
3914 final String seInfo = app.info.seInfo
3915 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3916 // Start the process. It will either succeed and return a result containing
3917 // the PID of the new process, or else throw a RuntimeException.
3918 boolean isActivityProcess = (entryPoint == null);
3919 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3920 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3922 checkTime(startTime, "startProcess: asking zygote to start proc");
3923 ProcessStartResult startResult;
3924 if (hostingType.equals("webview_service")) {
3925 startResult = startWebView(entryPoint,
3926 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3927 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3928 app.info.dataDir, null, entryPointArgs);
3930 startResult = Process.start(entryPoint,
3931 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3932 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3933 app.info.dataDir, invokeWith, entryPointArgs);
3935 checkTime(startTime, "startProcess: returned from zygote!");
3936 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3938 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3939 checkTime(startTime, "startProcess: done updating battery stats");
3941 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3942 UserHandle.getUserId(uid), startResult.pid, uid,
3943 app.processName, hostingType,
3944 hostingNameStr != null ? hostingNameStr : "");
3947 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3948 seInfo, app.info.sourceDir, startResult.pid);
3949 } catch (RemoteException ex) {
3953 if (app.persistent) {
3954 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3957 checkTime(startTime, "startProcess: building log message");
3958 StringBuilder buf = mStringBuilder;
3960 buf.append("Start proc ");
3961 buf.append(startResult.pid);
3963 buf.append(app.processName);
3965 UserHandle.formatUid(buf, uid);
3966 if (!isActivityProcess) {
3968 buf.append(entryPoint);
3971 buf.append(" for ");
3972 buf.append(hostingType);
3973 if (hostingNameStr != null) {
3975 buf.append(hostingNameStr);
3977 Slog.i(TAG, buf.toString());
3978 app.setPid(startResult.pid);
3979 app.usingWrapper = startResult.usingWrapper;
3980 app.removed = false;
3982 app.killedByAm = false;
3983 checkTime(startTime, "startProcess: starting to update pids map");
3984 ProcessRecord oldApp;
3985 synchronized (mPidsSelfLocked) {
3986 oldApp = mPidsSelfLocked.get(startResult.pid);
3988 // If there is already an app occupying that pid that hasn't been cleaned up
3989 if (oldApp != null && !app.isolated) {
3990 // Clean up anything relating to this pid first
3991 Slog.w(TAG, "Reusing pid " + startResult.pid
3992 + " while app is still mapped to it");
3993 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3994 true /*replacingPid*/);
3996 synchronized (mPidsSelfLocked) {
3997 this.mPidsSelfLocked.put(startResult.pid, app);
3998 if (isActivityProcess) {
3999 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4001 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4002 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4005 checkTime(startTime, "startProcess: done updating pids map");
4006 } catch (RuntimeException e) {
4007 Slog.e(TAG, "Failure starting process " + app.processName, e);
4009 // Something went very wrong while trying to start this process; one
4010 // common case is when the package is frozen due to an active
4011 // upgrade. To recover, clean up any active bookkeeping related to
4012 // starting this process. (We already invoked this method once when
4013 // the package was initially frozen through KILL_APPLICATION_MSG, so
4014 // it doesn't hurt to use it again.)
4015 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4016 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4020 void updateUsageStats(ActivityRecord component, boolean resumed) {
4021 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4022 "updateUsageStats: comp=" + component + "res=" + resumed);
4023 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4025 if (mUsageStatsService != null) {
4026 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4027 UsageEvents.Event.MOVE_TO_FOREGROUND);
4029 synchronized (stats) {
4030 stats.noteActivityResumedLocked(component.app.uid);
4033 if (mUsageStatsService != null) {
4034 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4035 UsageEvents.Event.MOVE_TO_BACKGROUND);
4037 synchronized (stats) {
4038 stats.noteActivityPausedLocked(component.app.uid);
4043 Intent getHomeIntent() {
4044 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4045 intent.setComponent(mTopComponent);
4046 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4047 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4048 intent.addCategory(Intent.CATEGORY_HOME);
4053 boolean startHomeActivityLocked(int userId, String reason) {
4054 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4055 && mTopAction == null) {
4056 // We are running in factory test mode, but unable to find
4057 // the factory test app, so just sit around displaying the
4058 // error message and don't try to start anything.
4061 Intent intent = getHomeIntent();
4062 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4063 if (aInfo != null) {
4064 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4065 // Don't do this if the home app is currently being
4067 aInfo = new ActivityInfo(aInfo);
4068 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4069 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4070 aInfo.applicationInfo.uid, true);
4071 if (app == null || app.instr == null) {
4072 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4073 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4074 // For ANR debugging to verify if the user activity is the one that actually
4076 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4077 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4080 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4086 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4087 ActivityInfo ai = null;
4088 ComponentName comp = intent.getComponent();
4092 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4094 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4096 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4100 ai = info.activityInfo;
4103 } catch (RemoteException e) {
4111 * Starts the "new version setup screen" if appropriate.
4113 void startSetupActivityLocked() {
4114 // Only do this once per boot.
4115 if (mCheckedForSetup) {
4119 // We will show this screen if the current one is a different
4120 // version than the last one shown, and we are not running in
4121 // low-level factory test mode.
4122 final ContentResolver resolver = mContext.getContentResolver();
4123 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4124 Settings.Global.getInt(resolver,
4125 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4126 mCheckedForSetup = true;
4128 // See if we should be showing the platform update setup UI.
4129 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4130 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4131 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4132 if (!ris.isEmpty()) {
4133 final ResolveInfo ri = ris.get(0);
4134 String vers = ri.activityInfo.metaData != null
4135 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4137 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4138 vers = ri.activityInfo.applicationInfo.metaData.getString(
4139 Intent.METADATA_SETUP_VERSION);
4141 String lastVers = Settings.Secure.getString(
4142 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4143 if (vers != null && !vers.equals(lastVers)) {
4144 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4145 intent.setComponent(new ComponentName(
4146 ri.activityInfo.packageName, ri.activityInfo.name));
4147 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4148 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4149 null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4155 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4156 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4159 void enforceNotIsolatedCaller(String caller) {
4160 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4161 throw new SecurityException("Isolated process not allowed to call " + caller);
4165 void enforceShellRestriction(String restriction, int userHandle) {
4166 if (Binder.getCallingUid() == SHELL_UID) {
4167 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4168 throw new SecurityException("Shell does not have permission to access user "
4175 public int getFrontActivityScreenCompatMode() {
4176 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4177 synchronized (this) {
4178 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4183 public void setFrontActivityScreenCompatMode(int mode) {
4184 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4185 "setFrontActivityScreenCompatMode");
4186 synchronized (this) {
4187 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4192 public int getPackageScreenCompatMode(String packageName) {
4193 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4194 synchronized (this) {
4195 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4200 public void setPackageScreenCompatMode(String packageName, int mode) {
4201 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4202 "setPackageScreenCompatMode");
4203 synchronized (this) {
4204 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4209 public boolean getPackageAskScreenCompat(String packageName) {
4210 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4211 synchronized (this) {
4212 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4217 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4218 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4219 "setPackageAskScreenCompat");
4220 synchronized (this) {
4221 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4225 private boolean hasUsageStatsPermission(String callingPackage) {
4226 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4227 Binder.getCallingUid(), callingPackage);
4228 if (mode == AppOpsManager.MODE_DEFAULT) {
4229 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4230 == PackageManager.PERMISSION_GRANTED;
4232 return mode == AppOpsManager.MODE_ALLOWED;
4236 public int getPackageProcessState(String packageName, String callingPackage) {
4237 if (!hasUsageStatsPermission(callingPackage)) {
4238 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4239 "getPackageProcessState");
4242 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4243 synchronized (this) {
4244 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4245 final ProcessRecord proc = mLruProcesses.get(i);
4246 if (procState > proc.setProcState) {
4247 if (proc.pkgList.containsKey(packageName) ||
4248 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4249 procState = proc.setProcState;
4258 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4259 throws RemoteException {
4260 synchronized (this) {
4261 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4263 throw new IllegalArgumentException("Unknown process: " + process);
4265 if (app.thread == null) {
4266 throw new IllegalArgumentException("Process has no app thread");
4268 if (app.trimMemoryLevel >= level) {
4269 throw new IllegalArgumentException(
4270 "Unable to set a higher trim level than current level");
4272 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4273 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4274 throw new IllegalArgumentException("Unable to set a background trim level "
4275 + "on a foreground process");
4277 app.thread.scheduleTrimMemory(level);
4278 app.trimMemoryLevel = level;
4283 private void dispatchProcessesChanged() {
4285 synchronized (this) {
4286 N = mPendingProcessChanges.size();
4287 if (mActiveProcessChanges.length < N) {
4288 mActiveProcessChanges = new ProcessChangeItem[N];
4290 mPendingProcessChanges.toArray(mActiveProcessChanges);
4291 mPendingProcessChanges.clear();
4292 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4293 "*** Delivering " + N + " process changes");
4296 int i = mProcessObservers.beginBroadcast();
4299 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4300 if (observer != null) {
4302 for (int j=0; j<N; j++) {
4303 ProcessChangeItem item = mActiveProcessChanges[j];
4304 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4305 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4306 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4307 + item.uid + ": " + item.foregroundActivities);
4308 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4309 item.foregroundActivities);
4312 } catch (RemoteException e) {
4316 mProcessObservers.finishBroadcast();
4318 synchronized (this) {
4319 for (int j=0; j<N; j++) {
4320 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4325 private void dispatchProcessDied(int pid, int uid) {
4326 int i = mProcessObservers.beginBroadcast();
4329 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4330 if (observer != null) {
4332 observer.onProcessDied(pid, uid);
4333 } catch (RemoteException e) {
4337 mProcessObservers.finishBroadcast();
4341 void dispatchUidsChanged() {
4343 synchronized (this) {
4344 N = mPendingUidChanges.size();
4345 if (mActiveUidChanges.length < N) {
4346 mActiveUidChanges = new UidRecord.ChangeItem[N];
4348 for (int i=0; i<N; i++) {
4349 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4350 mActiveUidChanges[i] = change;
4351 if (change.uidRecord != null) {
4352 change.uidRecord.pendingChange = null;
4353 change.uidRecord = null;
4356 mPendingUidChanges.clear();
4357 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4358 "*** Delivering " + N + " uid changes");
4361 int i = mUidObservers.beginBroadcast();
4364 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4365 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4367 mUidObservers.finishBroadcast();
4369 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4370 for (int j = 0; j < N; ++j) {
4371 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4372 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4373 mValidateUids.remove(item.uid);
4375 UidRecord validateUid = mValidateUids.get(item.uid);
4376 if (validateUid == null) {
4377 validateUid = new UidRecord(item.uid);
4378 mValidateUids.put(item.uid, validateUid);
4380 if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4381 validateUid.idle = true;
4382 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4383 validateUid.idle = false;
4385 validateUid.curProcState = validateUid.setProcState = item.processState;
4386 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4391 synchronized (this) {
4392 for (int j = 0; j < N; j++) {
4393 mAvailUidChanges.add(mActiveUidChanges[j]);
4398 private void dispatchUidsChangedForObserver(IUidObserver observer,
4399 UidObserverRegistration reg, int changesSize) {
4400 if (observer == null) {
4404 for (int j = 0; j < changesSize; j++) {
4405 UidRecord.ChangeItem item = mActiveUidChanges[j];
4406 final int change = item.change;
4407 if (change == UidRecord.CHANGE_PROCSTATE &&
4408 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4409 // No-op common case: no significant change, the observer is not
4410 // interested in all proc state changes.
4413 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4414 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4415 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4416 "UID idle uid=" + item.uid);
4417 observer.onUidIdle(item.uid, item.ephemeral);
4419 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4420 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4421 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422 "UID active uid=" + item.uid);
4423 observer.onUidActive(item.uid);
4426 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4427 if ((change & UidRecord.CHANGE_CACHED) != 0) {
4428 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4429 "UID cached uid=" + item.uid);
4430 observer.onUidCachedChanged(item.uid, true);
4431 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4432 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4433 "UID active uid=" + item.uid);
4434 observer.onUidCachedChanged(item.uid, false);
4437 if ((change & UidRecord.CHANGE_GONE) != 0) {
4438 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4439 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4440 "UID gone uid=" + item.uid);
4441 observer.onUidGone(item.uid, item.ephemeral);
4443 if (reg.lastProcStates != null) {
4444 reg.lastProcStates.delete(item.uid);
4447 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4448 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4449 "UID CHANGED uid=" + item.uid
4450 + ": " + item.processState);
4451 boolean doReport = true;
4452 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4453 final int lastState = reg.lastProcStates.get(item.uid,
4454 ActivityManager.PROCESS_STATE_UNKNOWN);
4455 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4456 final boolean lastAboveCut = lastState <= reg.cutpoint;
4457 final boolean newAboveCut = item.processState <= reg.cutpoint;
4458 doReport = lastAboveCut != newAboveCut;
4460 doReport = item.processState
4461 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4465 if (reg.lastProcStates != null) {
4466 reg.lastProcStates.put(item.uid, item.processState);
4468 observer.onUidStateChanged(item.uid, item.processState,
4474 } catch (RemoteException e) {
4478 void dispatchOomAdjObserver(String msg) {
4479 OomAdjObserver observer;
4480 synchronized (this) {
4481 observer = mCurOomAdjObserver;
4484 if (observer != null) {
4485 observer.onOomAdjMessage(msg);
4489 void setOomAdjObserver(int uid, OomAdjObserver observer) {
4490 synchronized (this) {
4491 mCurOomAdjUid = uid;
4492 mCurOomAdjObserver = observer;
4496 void clearOomAdjObserver() {
4497 synchronized (this) {
4499 mCurOomAdjObserver = null;
4503 void reportOomAdjMessageLocked(String tag, String msg) {
4505 if (mCurOomAdjObserver != null) {
4506 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4511 public final int startActivity(IApplicationThread caller, String callingPackage,
4512 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4513 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4514 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4515 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4516 UserHandle.getCallingUserId());
4520 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4521 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4522 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4523 enforceNotIsolatedCaller("startActivity");
4524 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4525 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4526 // TODO: Switch to user app stacks here.
4527 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4528 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4529 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4533 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4534 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4535 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4538 // This is very dangerous -- it allows you to perform a start activity (including
4539 // permission grants) as any app that may launch one of your own activities. So
4540 // we will only allow this to be done from activities that are part of the core framework,
4541 // and then only when they are running as the system.
4542 final ActivityRecord sourceRecord;
4543 final int targetUid;
4544 final String targetPackage;
4545 synchronized (this) {
4546 if (resultTo == null) {
4547 throw new SecurityException("Must be called from an activity");
4549 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4550 if (sourceRecord == null) {
4551 throw new SecurityException("Called with bad activity token: " + resultTo);
4553 if (!sourceRecord.info.packageName.equals("android")) {
4554 throw new SecurityException(
4555 "Must be called from an activity that is declared in the android package");
4557 if (sourceRecord.app == null) {
4558 throw new SecurityException("Called without a process attached to activity");
4560 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4561 // This is still okay, as long as this activity is running under the
4562 // uid of the original calling activity.
4563 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4564 throw new SecurityException(
4565 "Calling activity in uid " + sourceRecord.app.uid
4566 + " must be system uid or original calling uid "
4567 + sourceRecord.launchedFromUid);
4570 if (ignoreTargetSecurity) {
4571 if (intent.getComponent() == null) {
4572 throw new SecurityException(
4573 "Component must be specified with ignoreTargetSecurity");
4575 if (intent.getSelector() != null) {
4576 throw new SecurityException(
4577 "Selector not allowed with ignoreTargetSecurity");
4580 targetUid = sourceRecord.launchedFromUid;
4581 targetPackage = sourceRecord.launchedFromPackage;
4584 if (userId == UserHandle.USER_NULL) {
4585 userId = UserHandle.getUserId(sourceRecord.app.uid);
4588 // TODO: Switch to user app stacks here.
4590 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4591 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4592 null, null, bOptions, ignoreTargetSecurity, userId, null,
4593 "startActivityAsCaller");
4595 } catch (SecurityException e) {
4596 // XXX need to figure out how to propagate to original app.
4597 // A SecurityException here is generally actually a fault of the original
4598 // calling activity (such as a fairly granting permissions), so propagate it
4601 StringBuilder msg = new StringBuilder();
4602 msg.append("While launching");
4603 msg.append(intent.toString());
4605 msg.append(e.getMessage());
4612 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4613 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4614 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4615 enforceNotIsolatedCaller("startActivityAndWait");
4616 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4617 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4618 WaitResult res = new WaitResult();
4619 // TODO: Switch to user app stacks here.
4620 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4621 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4622 bOptions, false, userId, null, "startActivityAndWait");
4627 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4628 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4629 int startFlags, Configuration config, Bundle bOptions, int userId) {
4630 enforceNotIsolatedCaller("startActivityWithConfig");
4631 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4632 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4633 // TODO: Switch to user app stacks here.
4634 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4635 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4636 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4641 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4642 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4643 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4644 throws TransactionTooLargeException {
4645 enforceNotIsolatedCaller("startActivityIntentSender");
4646 // Refuse possible leaked file descriptors
4647 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4648 throw new IllegalArgumentException("File descriptors passed in Intent");
4651 if (!(target instanceof PendingIntentRecord)) {
4652 throw new IllegalArgumentException("Bad PendingIntent object");
4655 PendingIntentRecord pir = (PendingIntentRecord)target;
4657 synchronized (this) {
4658 // If this is coming from the currently resumed activity, it is
4659 // effectively saying that app switches are allowed at this point.
4660 final ActivityStack stack = getFocusedStack();
4661 if (stack.mResumedActivity != null &&
4662 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4663 mAppSwitchesAllowedTime = 0;
4666 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4667 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4672 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4673 Intent intent, String resolvedType, IVoiceInteractionSession session,
4674 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4675 Bundle bOptions, int userId) {
4676 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4677 != PackageManager.PERMISSION_GRANTED) {
4678 String msg = "Permission Denial: startVoiceActivity() from pid="
4679 + Binder.getCallingPid()
4680 + ", uid=" + Binder.getCallingUid()
4681 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4683 throw new SecurityException(msg);
4685 if (session == null || interactor == null) {
4686 throw new NullPointerException("null session or interactor");
4688 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4689 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4690 // TODO: Switch to user app stacks here.
4691 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4692 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4693 null, bOptions, false, userId, null, "startVoiceActivity");
4697 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4698 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4699 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4700 != PackageManager.PERMISSION_GRANTED) {
4701 final String msg = "Permission Denial: startAssistantActivity() from pid="
4702 + Binder.getCallingPid()
4703 + ", uid=" + Binder.getCallingUid()
4704 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4706 throw new SecurityException(msg);
4708 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4709 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4710 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4711 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4712 userId, null, "startAssistantActivity");
4716 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4717 throws RemoteException {
4718 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4719 synchronized (this) {
4720 ActivityRecord activity = getFocusedStack().topActivity();
4721 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4722 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4724 if (mRunningVoice != null || activity.getTask().voiceSession != null
4725 || activity.voiceSession != null) {
4726 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4729 if (activity.pendingVoiceInteractionStart) {
4730 Slog.w(TAG, "Pending start of voice interaction already.");
4733 activity.pendingVoiceInteractionStart = true;
4735 LocalServices.getService(VoiceInteractionManagerInternal.class)
4736 .startLocalVoiceInteraction(callingActivity, options);
4740 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4741 LocalServices.getService(VoiceInteractionManagerInternal.class)
4742 .stopLocalVoiceInteraction(callingActivity);
4746 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4747 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4748 .supportsLocalVoiceInteraction();
4751 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4752 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4753 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4754 if (activityToCallback == null) return;
4755 activityToCallback.setVoiceSessionLocked(voiceSession);
4757 // Inform the activity
4759 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4761 long token = Binder.clearCallingIdentity();
4763 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4765 Binder.restoreCallingIdentity(token);
4767 // TODO: VI Should we cache the activity so that it's easier to find later
4768 // rather than scan through all the stacks and activities?
4769 } catch (RemoteException re) {
4770 activityToCallback.clearVoiceSessionLocked();
4771 // TODO: VI Should this terminate the voice session?
4776 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4777 synchronized (this) {
4778 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4780 mVoiceWakeLock.acquire();
4782 mVoiceWakeLock.release();
4789 public boolean startNextMatchingActivity(IBinder callingActivity,
4790 Intent intent, Bundle bOptions) {
4791 // Refuse possible leaked file descriptors
4792 if (intent != null && intent.hasFileDescriptors() == true) {
4793 throw new IllegalArgumentException("File descriptors passed in Intent");
4795 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4797 synchronized (this) {
4798 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4800 ActivityOptions.abort(options);
4803 if (r.app == null || r.app.thread == null) {
4804 // The caller is not running... d'oh!
4805 ActivityOptions.abort(options);
4808 intent = new Intent(intent);
4809 // The caller is not allowed to change the data.
4810 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4811 // And we are resetting to find the next component...
4812 intent.setComponent(null);
4814 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4816 ActivityInfo aInfo = null;
4818 List<ResolveInfo> resolves =
4819 AppGlobals.getPackageManager().queryIntentActivities(
4820 intent, r.resolvedType,
4821 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4822 UserHandle.getCallingUserId()).getList();
4824 // Look for the original activity in the list...
4825 final int N = resolves != null ? resolves.size() : 0;
4826 for (int i=0; i<N; i++) {
4827 ResolveInfo rInfo = resolves.get(i);
4828 if (rInfo.activityInfo.packageName.equals(r.packageName)
4829 && rInfo.activityInfo.name.equals(r.info.name)) {
4830 // We found the current one... the next matching is
4834 aInfo = resolves.get(i).activityInfo;
4837 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4838 + "/" + r.info.name);
4839 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4840 ? "null" : aInfo.packageName + "/" + aInfo.name));
4845 } catch (RemoteException e) {
4848 if (aInfo == null) {
4849 // Nobody who is next!
4850 ActivityOptions.abort(options);
4851 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4855 intent.setComponent(new ComponentName(
4856 aInfo.applicationInfo.packageName, aInfo.name));
4857 intent.setFlags(intent.getFlags()&~(
4858 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4859 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4860 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4861 Intent.FLAG_ACTIVITY_NEW_TASK));
4863 // Okay now we need to start the new activity, replacing the
4864 // currently running activity. This is a little tricky because
4865 // we want to start the new one as if the current one is finished,
4866 // but not finish the current one first so that there is no flicker.
4868 final boolean wasFinishing = r.finishing;
4871 // Propagate reply information over to the new activity.
4872 final ActivityRecord resultTo = r.resultTo;
4873 final String resultWho = r.resultWho;
4874 final int requestCode = r.requestCode;
4876 if (resultTo != null) {
4877 resultTo.removeResultsLocked(r, resultWho, requestCode);
4880 final long origId = Binder.clearCallingIdentity();
4881 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4882 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4883 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4884 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4885 false, false, null, null, "startNextMatchingActivity");
4886 Binder.restoreCallingIdentity(origId);
4888 r.finishing = wasFinishing;
4889 if (res != ActivityManager.START_SUCCESS) {
4897 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4898 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4899 String msg = "Permission Denial: startActivityFromRecents called without " +
4900 START_TASKS_FROM_RECENTS;
4902 throw new SecurityException(msg);
4904 final long origId = Binder.clearCallingIdentity();
4906 synchronized (this) {
4907 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4910 Binder.restoreCallingIdentity(origId);
4914 final int startActivityInPackage(int uid, String callingPackage,
4915 Intent intent, String resolvedType, IBinder resultTo,
4916 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4917 TaskRecord inTask, String reason) {
4919 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4920 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4922 // TODO: Switch to user app stacks here.
4923 return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4924 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4925 null, null, null, bOptions, false, userId, inTask, reason);
4929 public final int startActivities(IApplicationThread caller, String callingPackage,
4930 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4932 final String reason = "startActivities";
4933 enforceNotIsolatedCaller(reason);
4934 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4935 userId, false, ALLOW_FULL_ONLY, reason, null);
4936 // TODO: Switch to user app stacks here.
4937 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4938 resolvedTypes, resultTo, bOptions, userId, reason);
4942 final int startActivitiesInPackage(int uid, String callingPackage,
4943 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4944 Bundle bOptions, int userId) {
4946 final String reason = "startActivityInPackage";
4947 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4948 userId, false, ALLOW_FULL_ONLY, reason, null);
4949 // TODO: Switch to user app stacks here.
4950 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4951 resultTo, bOptions, userId, reason);
4956 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4957 synchronized (this) {
4958 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4962 r.reportFullyDrawnLocked(restoredFromBundle);
4967 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4968 synchronized (this) {
4969 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4973 final long origId = Binder.clearCallingIdentity();
4975 r.setRequestedOrientation(requestedOrientation);
4977 Binder.restoreCallingIdentity(origId);
4983 public int getRequestedOrientation(IBinder token) {
4984 synchronized (this) {
4985 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4987 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4989 return r.getRequestedOrientation();
4994 public final void requestActivityRelaunch(IBinder token) {
4995 synchronized(this) {
4996 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5000 final long origId = Binder.clearCallingIdentity();
5002 r.forceNewConfig = true;
5003 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5004 true /* preserveWindow */);
5006 Binder.restoreCallingIdentity(origId);
5012 * This is the internal entry point for handling Activity.finish().
5014 * @param token The Binder token referencing the Activity we want to finish.
5015 * @param resultCode Result code, if any, from this Activity.
5016 * @param resultData Result data (Intent), if any, from this Activity.
5017 * @param finishTask Whether to finish the task associated with this Activity.
5019 * @return Returns true if the activity successfully finished, or false if it is still running.
5022 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5024 // Refuse possible leaked file descriptors
5025 if (resultData != null && resultData.hasFileDescriptors() == true) {
5026 throw new IllegalArgumentException("File descriptors passed in Intent");
5029 synchronized(this) {
5030 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5034 // Keep track of the root activity of the task before we finish it
5035 TaskRecord tr = r.getTask();
5036 ActivityRecord rootR = tr.getRootActivity();
5037 if (rootR == null) {
5038 Slog.w(TAG, "Finishing task with all activities already finished");
5040 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5042 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5043 mStackSupervisor.isLastLockedTask(tr)) {
5044 Slog.i(TAG, "Not finishing task in lock task mode");
5045 mStackSupervisor.showLockTaskToast();
5048 if (mController != null) {
5049 // Find the first activity that is not finishing.
5050 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5052 // ask watcher if this is allowed
5053 boolean resumeOK = true;
5055 resumeOK = mController.activityResuming(next.packageName);
5056 } catch (RemoteException e) {
5058 Watchdog.getInstance().setActivityController(null);
5062 Slog.i(TAG, "Not finishing activity because controller resumed");
5067 final long origId = Binder.clearCallingIdentity();
5070 final boolean finishWithRootActivity =
5071 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5072 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5073 || (finishWithRootActivity && r == rootR)) {
5074 // If requested, remove the task that is associated to this activity only if it
5075 // was the root activity in the task. The result code and data is ignored
5076 // because we don't support returning them across task boundaries. Also, to
5077 // keep backwards compatibility we remove the task from recents when finishing
5078 // task with root activity.
5079 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5081 Slog.i(TAG, "Removing task failed to finish activity");
5084 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5085 resultData, "app-request", true);
5087 Slog.i(TAG, "Failed to finish by app-request");
5092 Binder.restoreCallingIdentity(origId);
5098 public final void finishHeavyWeightApp() {
5099 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5100 != PackageManager.PERMISSION_GRANTED) {
5101 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5102 + Binder.getCallingPid()
5103 + ", uid=" + Binder.getCallingUid()
5104 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5106 throw new SecurityException(msg);
5109 synchronized(this) {
5110 if (mHeavyWeightProcess == null) {
5114 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5115 for (int i = 0; i < activities.size(); i++) {
5116 ActivityRecord r = activities.get(i);
5117 if (!r.finishing && r.isInStackLocked()) {
5118 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5119 null, "finish-heavy", true);
5123 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5124 mHeavyWeightProcess.userId, 0));
5125 mHeavyWeightProcess = null;
5130 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5132 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5133 != PackageManager.PERMISSION_GRANTED) {
5134 String msg = "Permission Denial: crashApplication() from pid="
5135 + Binder.getCallingPid()
5136 + ", uid=" + Binder.getCallingUid()
5137 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5139 throw new SecurityException(msg);
5142 synchronized(this) {
5143 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5148 public final void finishSubActivity(IBinder token, String resultWho,
5150 synchronized(this) {
5151 final long origId = Binder.clearCallingIdentity();
5152 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5154 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5156 Binder.restoreCallingIdentity(origId);
5161 public boolean finishActivityAffinity(IBinder token) {
5162 synchronized(this) {
5163 final long origId = Binder.clearCallingIdentity();
5165 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5170 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5172 final TaskRecord task = r.getTask();
5173 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5174 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5175 mStackSupervisor.showLockTaskToast();
5178 return task.getStack().finishActivityAffinityLocked(r);
5180 Binder.restoreCallingIdentity(origId);
5186 public void finishVoiceTask(IVoiceInteractionSession session) {
5187 synchronized (this) {
5188 final long origId = Binder.clearCallingIdentity();
5190 // TODO: VI Consider treating local voice interactions and voice tasks
5192 mStackSupervisor.finishVoiceTask(session);
5194 Binder.restoreCallingIdentity(origId);
5201 public boolean releaseActivityInstance(IBinder token) {
5202 synchronized(this) {
5203 final long origId = Binder.clearCallingIdentity();
5205 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5209 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5211 Binder.restoreCallingIdentity(origId);
5217 public void releaseSomeActivities(IApplicationThread appInt) {
5218 synchronized(this) {
5219 final long origId = Binder.clearCallingIdentity();
5221 ProcessRecord app = getRecordForAppLocked(appInt);
5222 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5224 Binder.restoreCallingIdentity(origId);
5230 public boolean willActivityBeVisible(IBinder token) {
5231 synchronized(this) {
5232 ActivityStack stack = ActivityRecord.getStackLocked(token);
5233 if (stack != null) {
5234 return stack.willActivityBeVisibleLocked(token);
5241 public void overridePendingTransition(IBinder token, String packageName,
5242 int enterAnim, int exitAnim) {
5243 synchronized(this) {
5244 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5249 final long origId = Binder.clearCallingIdentity();
5251 if (self.state == ActivityState.RESUMED
5252 || self.state == ActivityState.PAUSING) {
5253 mWindowManager.overridePendingAppTransition(packageName,
5254 enterAnim, exitAnim, null);
5257 Binder.restoreCallingIdentity(origId);
5262 * Main function for removing an existing process from the activity manager
5263 * as a result of that process going away. Clears out all connections
5266 private final void handleAppDiedLocked(ProcessRecord app,
5267 boolean restarting, boolean allowRestart) {
5269 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5270 false /*replacingPid*/);
5271 if (!kept && !restarting) {
5272 removeLruProcessLocked(app);
5274 ProcessList.remove(pid);
5278 if (mProfileProc == app) {
5279 clearProfilerLocked();
5282 // Remove this application's activities from active lists.
5283 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5285 app.activities.clear();
5287 if (app.instr != null) {
5288 Slog.w(TAG, "Crash of app " + app.processName
5289 + " running instrumentation " + app.instr.mClass);
5290 Bundle info = new Bundle();
5291 info.putString("shortMsg", "Process crashed.");
5292 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5295 mWindowManager.deferSurfaceLayout();
5297 if (!restarting && hasVisibleActivities
5298 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5299 // If there was nothing to resume, and we are not already restarting this process, but
5300 // there is a visible activity that is hosted by the process... then make sure all
5301 // visible activities are running, taking care of restarting this process.
5302 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5305 mWindowManager.continueSurfaceLayout();
5309 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5310 final IBinder threadBinder = thread.asBinder();
5311 // Find the application record.
5312 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5313 final ProcessRecord rec = mLruProcesses.get(i);
5314 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5321 final ProcessRecord getRecordForAppLocked(
5322 IApplicationThread thread) {
5323 if (thread == null) {
5327 int appIndex = getLRURecordIndexForAppLocked(thread);
5328 if (appIndex >= 0) {
5329 return mLruProcesses.get(appIndex);
5332 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5333 // double-check that.
5334 final IBinder threadBinder = thread.asBinder();
5335 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5336 for (int i = pmap.size()-1; i >= 0; i--) {
5337 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5338 for (int j = procs.size()-1; j >= 0; j--) {
5339 final ProcessRecord proc = procs.valueAt(j);
5340 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5341 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5351 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5352 // If there are no longer any background processes running,
5353 // and the app that died was not running instrumentation,
5354 // then tell everyone we are now low on memory.
5355 boolean haveBg = false;
5356 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5357 ProcessRecord rec = mLruProcesses.get(i);
5358 if (rec.thread != null
5359 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5366 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5368 long now = SystemClock.uptimeMillis();
5369 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5372 mLastMemUsageReportTime = now;
5375 final ArrayList<ProcessMemInfo> memInfos
5376 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5377 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5378 long now = SystemClock.uptimeMillis();
5379 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5380 ProcessRecord rec = mLruProcesses.get(i);
5381 if (rec == dyingProc || rec.thread == null) {
5385 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5386 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5388 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5389 // The low memory report is overriding any current
5390 // state for a GC request. Make sure to do
5391 // heavy/important/visible/foreground processes first.
5392 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5393 rec.lastRequestedGc = 0;
5395 rec.lastRequestedGc = rec.lastLowMemory;
5397 rec.reportLowMemory = true;
5398 rec.lastLowMemory = now;
5399 mProcessesToGc.remove(rec);
5400 addProcessToGcListLocked(rec);
5404 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5405 mHandler.sendMessage(msg);
5407 scheduleAppGcsLocked();
5411 final void appDiedLocked(ProcessRecord app) {
5412 appDiedLocked(app, app.pid, app.thread, false);
5415 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5416 boolean fromBinderDied) {
5417 // First check if this ProcessRecord is actually active for the pid.
5418 synchronized (mPidsSelfLocked) {
5419 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5420 if (curProc != app) {
5421 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5426 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5427 synchronized (stats) {
5428 stats.noteProcessDiedLocked(app.info.uid, pid);
5432 if (!fromBinderDied) {
5433 killProcessQuiet(pid);
5435 killProcessGroup(app.uid, pid);
5439 // Clean up already done if the process has been re-started.
5440 if (app.pid == pid && app.thread != null &&
5441 app.thread.asBinder() == thread.asBinder()) {
5442 boolean doLowMem = app.instr == null;
5443 boolean doOomAdj = doLowMem;
5444 if (!app.killedByAm) {
5445 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5446 + ProcessList.makeOomAdjString(app.setAdj)
5447 + ProcessList.makeProcStateString(app.setProcState));
5448 mAllowLowerMemLevel = true;
5450 // Note that we always want to do oom adj to update our state with the
5451 // new number of procs.
5452 mAllowLowerMemLevel = false;
5455 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5456 app.setAdj, app.setProcState);
5457 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5458 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5459 handleAppDiedLocked(app, false, true);
5462 updateOomAdjLocked();
5465 doLowMemReportIfNeededLocked(app);
5467 } else if (app.pid != pid) {
5468 // A new process has already been started.
5469 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5470 + ") has died and restarted (pid " + app.pid + ").");
5471 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5472 } else if (DEBUG_PROCESSES) {
5473 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5474 + thread.asBinder());
5479 * If a stack trace dump file is configured, dump process stack traces.
5480 * @param clearTraces causes the dump file to be erased prior to the new
5481 * traces being written, if true; when false, the new traces will be
5482 * appended to any existing file content.
5483 * @param firstPids of dalvik VM processes to dump stack traces for first
5484 * @param lastPids of dalvik VM processes to dump stack traces for last
5485 * @param nativePids optional list of native pids to dump stack crawls
5487 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5488 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5489 ArrayList<Integer> nativePids) {
5490 ArrayList<Integer> extraPids = null;
5492 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5493 // of the top users at the time of the request.
5494 if (processCpuTracker != null) {
5495 processCpuTracker.init();
5498 } catch (InterruptedException ignored) {
5501 processCpuTracker.update();
5503 // We'll take the stack crawls of just the top apps using CPU.
5504 final int N = processCpuTracker.countWorkingStats();
5505 extraPids = new ArrayList<>();
5506 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5507 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5508 if (lastPids.indexOfKey(stats.pid) >= 0) {
5509 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5511 extraPids.add(stats.pid);
5512 } else if (DEBUG_ANR) {
5513 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5519 boolean useTombstonedForJavaTraces = false;
5522 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5523 if (tracesDirProp.isEmpty()) {
5524 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5525 // dumping scheme. All traces are written to a global trace file (usually
5526 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5527 // the file if requested.
5529 // This mode of operation will be removed in the near future.
5532 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5533 if (globalTracesPath.isEmpty()) {
5534 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5538 tracesFile = new File(globalTracesPath);
5540 if (clearTraces && tracesFile.exists()) {
5541 tracesFile.delete();
5544 tracesFile.createNewFile();
5545 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5546 } catch (IOException e) {
5547 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5551 File tracesDir = new File(tracesDirProp);
5552 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5553 // Each set of ANR traces is written to a separate file and dumpstate will process
5554 // all such files and add them to a captured bug report if they're recent enough.
5555 maybePruneOldTraces(tracesDir);
5557 // NOTE: We should consider creating the file in native code atomically once we've
5558 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5560 tracesFile = createAnrDumpFile(tracesDir);
5561 if (tracesFile == null) {
5565 useTombstonedForJavaTraces = true;
5568 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5569 useTombstonedForJavaTraces);
5573 @GuardedBy("ActivityManagerService.class")
5574 private static SimpleDateFormat sAnrFileDateFormat;
5576 private static synchronized File createAnrDumpFile(File tracesDir) {
5577 if (sAnrFileDateFormat == null) {
5578 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5581 final String formattedDate = sAnrFileDateFormat.format(new Date());
5582 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5585 if (anrFile.createNewFile()) {
5586 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5589 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5591 } catch (IOException ioe) {
5592 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5599 * Prune all trace files that are more than a day old.
5601 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5602 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5603 * since it's the system_server that creates trace files for most ANRs.
5605 private static void maybePruneOldTraces(File tracesDir) {
5606 final long now = System.currentTimeMillis();
5607 final File[] traceFiles = tracesDir.listFiles();
5609 if (traceFiles != null) {
5610 for (File file : traceFiles) {
5611 if ((now - file.lastModified()) > DAY_IN_MILLIS) {
5612 if (!file.delete()) {
5613 Slog.w(TAG, "Unable to prune stale trace file: " + file);
5621 * Legacy code, do not use. Existing users will be deleted.
5626 public static class DumpStackFileObserver extends FileObserver {
5627 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5628 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5630 private final String mTracesPath;
5631 private boolean mClosed;
5633 public DumpStackFileObserver(String tracesPath) {
5634 super(tracesPath, FileObserver.CLOSE_WRITE);
5635 mTracesPath = tracesPath;
5639 public synchronized void onEvent(int event, String path) {
5644 public long dumpWithTimeout(int pid, long timeout) {
5645 sendSignal(pid, SIGNAL_QUIT);
5646 final long start = SystemClock.elapsedRealtime();
5648 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5649 synchronized (this) {
5651 wait(waitTime); // Wait for traces file to be closed.
5652 } catch (InterruptedException e) {
5657 // This avoids a corner case of passing a negative time to the native
5658 // trace in case we've already hit the overall timeout.
5659 final long timeWaited = SystemClock.elapsedRealtime() - start;
5660 if (timeWaited >= timeout) {
5665 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5666 ". Attempting native stack collection.");
5668 final long nativeDumpTimeoutMs = Math.min(
5669 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5671 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5672 (int) (nativeDumpTimeoutMs / 1000));
5675 final long end = SystemClock.elapsedRealtime();
5678 return (end - start);
5683 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5684 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5685 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5686 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5689 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5690 final long timeStart = SystemClock.elapsedRealtime();
5691 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5692 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5693 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5696 return SystemClock.elapsedRealtime() - timeStart;
5699 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5700 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5701 boolean useTombstonedForJavaTraces) {
5703 // We don't need any sort of inotify based monitoring when we're dumping traces via
5704 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5705 // control of all writes to the file in question.
5706 final DumpStackFileObserver observer;
5707 if (useTombstonedForJavaTraces) {
5710 // Use a FileObserver to detect when traces finish writing.
5711 // The order of traces is considered important to maintain for legibility.
5712 observer = new DumpStackFileObserver(tracesFile);
5715 // We must complete all stack dumps within 20 seconds.
5716 long remainingTime = 20 * 1000;
5718 if (observer != null) {
5719 observer.startWatching();
5722 // First collect all of the stacks of the most important pids.
5723 if (firstPids != null) {
5724 int num = firstPids.size();
5725 for (int i = 0; i < num; i++) {
5726 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5727 + firstPids.get(i));
5728 final long timeTaken;
5729 if (useTombstonedForJavaTraces) {
5730 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5732 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5735 remainingTime -= timeTaken;
5736 if (remainingTime <= 0) {
5737 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5738 "); deadline exceeded.");
5743 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5748 // Next collect the stacks of the native pids
5749 if (nativePids != null) {
5750 for (int pid : nativePids) {
5751 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5752 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5754 final long start = SystemClock.elapsedRealtime();
5755 Debug.dumpNativeBacktraceToFileTimeout(
5756 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5757 final long timeTaken = SystemClock.elapsedRealtime() - start;
5759 remainingTime -= timeTaken;
5760 if (remainingTime <= 0) {
5761 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5762 "); deadline exceeded.");
5767 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5772 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5773 if (extraPids != null) {
5774 for (int pid : extraPids) {
5775 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5777 final long timeTaken;
5778 if (useTombstonedForJavaTraces) {
5779 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5781 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5784 remainingTime -= timeTaken;
5785 if (remainingTime <= 0) {
5786 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5787 "); deadline exceeded.");
5792 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5797 if (observer != null) {
5798 observer.stopWatching();
5803 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5804 if (true || Build.IS_USER) {
5807 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5808 if (tracesPath == null || tracesPath.length() == 0) {
5812 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5813 StrictMode.allowThreadDiskWrites();
5815 final File tracesFile = new File(tracesPath);
5816 final File tracesDir = tracesFile.getParentFile();
5817 final File tracesTmp = new File(tracesDir, "__tmp__");
5819 if (tracesFile.exists()) {
5821 tracesFile.renameTo(tracesTmp);
5823 StringBuilder sb = new StringBuilder();
5824 Time tobj = new Time();
5825 tobj.set(System.currentTimeMillis());
5826 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5828 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5829 sb.append(" since ");
5831 FileOutputStream fos = new FileOutputStream(tracesFile);
5832 fos.write(sb.toString().getBytes());
5834 fos.write("\n*** No application process!".getBytes());
5837 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5838 } catch (IOException e) {
5839 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5844 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5845 firstPids.add(app.pid);
5846 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5849 File lastTracesFile = null;
5850 File curTracesFile = null;
5851 for (int i=9; i>=0; i--) {
5852 String name = String.format(Locale.US, "slow%02d.txt", i);
5853 curTracesFile = new File(tracesDir, name);
5854 if (curTracesFile.exists()) {
5855 if (lastTracesFile != null) {
5856 curTracesFile.renameTo(lastTracesFile);
5858 curTracesFile.delete();
5861 lastTracesFile = curTracesFile;
5863 tracesFile.renameTo(curTracesFile);
5864 if (tracesTmp.exists()) {
5865 tracesTmp.renameTo(tracesFile);
5868 StrictMode.setThreadPolicy(oldPolicy);
5872 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5873 if (!mLaunchWarningShown) {
5874 mLaunchWarningShown = true;
5875 mUiHandler.post(new Runnable() {
5878 synchronized (ActivityManagerService.this) {
5879 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5881 mUiHandler.postDelayed(new Runnable() {
5884 synchronized (ActivityManagerService.this) {
5886 mLaunchWarningShown = false;
5897 public boolean clearApplicationUserData(final String packageName,
5898 final IPackageDataObserver observer, int userId) {
5899 enforceNotIsolatedCaller("clearApplicationUserData");
5900 int uid = Binder.getCallingUid();
5901 int pid = Binder.getCallingPid();
5902 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5903 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5905 final ApplicationInfo appInfo;
5906 final boolean isInstantApp;
5908 long callingId = Binder.clearCallingIdentity();
5910 IPackageManager pm = AppGlobals.getPackageManager();
5911 synchronized(this) {
5912 // Instant packages are not protected
5913 if (getPackageManagerInternalLocked().isPackageDataProtected(
5914 resolvedUserId, packageName)) {
5915 throw new SecurityException(
5916 "Cannot clear data for a protected package: " + packageName);
5919 ApplicationInfo applicationInfo = null;
5921 applicationInfo = pm.getApplicationInfo(packageName,
5922 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5923 } catch (RemoteException e) {
5926 appInfo = applicationInfo;
5928 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5930 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5931 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5932 throw new SecurityException("PID " + pid + " does not have permission "
5933 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5934 + " of package " + packageName);
5937 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5938 .hasInstantApplicationMetadata(packageName, resolvedUserId);
5939 final boolean isUninstalledAppWithoutInstantMetadata =
5940 (appInfo == null && !hasInstantMetadata);
5941 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5942 || hasInstantMetadata;
5943 final boolean canAccessInstantApps = checkComponentPermission(
5944 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5945 == PackageManager.PERMISSION_GRANTED;
5947 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5948 && !canAccessInstantApps)) {
5949 Slog.w(TAG, "Invalid packageName: " + packageName);
5950 if (observer != null) {
5952 observer.onRemoveCompleted(packageName, false);
5953 } catch (RemoteException e) {
5954 Slog.i(TAG, "Observer no longer exists.");
5960 if (appInfo != null) {
5961 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5962 // Remove all tasks match the cleared application package and user
5963 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5964 final TaskRecord tr = mRecentTasks.get(i);
5965 final String taskPackageName =
5966 tr.getBaseIntent().getComponent().getPackageName();
5967 if (tr.userId != resolvedUserId) continue;
5968 if (!taskPackageName.equals(packageName)) continue;
5969 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5970 REMOVE_FROM_RECENTS);
5975 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5977 public void onRemoveCompleted(String packageName, boolean succeeded)
5978 throws RemoteException {
5979 if (appInfo != null) {
5980 synchronized (ActivityManagerService.this) {
5981 finishForceStopPackageLocked(packageName, appInfo.uid);
5984 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5985 Uri.fromParts("package", packageName, null));
5986 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5987 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5988 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5990 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5991 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5992 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5995 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5996 null, null, null, null, false, false, resolvedUserId);
5999 if (observer != null) {
6000 observer.onRemoveCompleted(packageName, succeeded);
6006 // Clear application user data
6007 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6009 if (appInfo != null) {
6010 synchronized (this) {
6011 // Remove all permissions granted from/to this package
6012 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6015 // Reset notification settings.
6016 INotificationManager inm = NotificationManager.getService();
6017 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6019 } catch (RemoteException e) {
6022 Binder.restoreCallingIdentity(callingId);
6028 public void killBackgroundProcesses(final String packageName, int userId) {
6029 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6030 != PackageManager.PERMISSION_GRANTED &&
6031 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6032 != PackageManager.PERMISSION_GRANTED) {
6033 String msg = "Permission Denial: killBackgroundProcesses() from pid="
6034 + Binder.getCallingPid()
6035 + ", uid=" + Binder.getCallingUid()
6036 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6038 throw new SecurityException(msg);
6041 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6042 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6043 long callingId = Binder.clearCallingIdentity();
6045 IPackageManager pm = AppGlobals.getPackageManager();
6046 synchronized(this) {
6049 appId = UserHandle.getAppId(
6050 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6051 } catch (RemoteException e) {
6054 Slog.w(TAG, "Invalid packageName: " + packageName);
6057 killPackageProcessesLocked(packageName, appId, userId,
6058 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6061 Binder.restoreCallingIdentity(callingId);
6066 public void killAllBackgroundProcesses() {
6067 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6068 != PackageManager.PERMISSION_GRANTED) {
6069 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6070 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6071 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6073 throw new SecurityException(msg);
6076 final long callingId = Binder.clearCallingIdentity();
6078 synchronized (this) {
6079 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6080 final int NP = mProcessNames.getMap().size();
6081 for (int ip = 0; ip < NP; ip++) {
6082 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6083 final int NA = apps.size();
6084 for (int ia = 0; ia < NA; ia++) {
6085 final ProcessRecord app = apps.valueAt(ia);
6086 if (app.persistent) {
6087 // We don't kill persistent processes.
6092 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6099 final int N = procs.size();
6100 for (int i = 0; i < N; i++) {
6101 removeProcessLocked(procs.get(i), false, true, "kill all background");
6104 mAllowLowerMemLevel = true;
6106 updateOomAdjLocked();
6107 doLowMemReportIfNeededLocked(null);
6110 Binder.restoreCallingIdentity(callingId);
6115 * Kills all background processes, except those matching any of the
6116 * specified properties.
6118 * @param minTargetSdk the target SDK version at or above which to preserve
6119 * processes, or {@code -1} to ignore the target SDK
6120 * @param maxProcState the process state at or below which to preserve
6121 * processes, or {@code -1} to ignore the process state
6123 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6124 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6125 != PackageManager.PERMISSION_GRANTED) {
6126 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6127 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6128 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6130 throw new SecurityException(msg);
6133 final long callingId = Binder.clearCallingIdentity();
6135 synchronized (this) {
6136 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6137 final int NP = mProcessNames.getMap().size();
6138 for (int ip = 0; ip < NP; ip++) {
6139 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6140 final int NA = apps.size();
6141 for (int ia = 0; ia < NA; ia++) {
6142 final ProcessRecord app = apps.valueAt(ia);
6145 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6146 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6153 final int N = procs.size();
6154 for (int i = 0; i < N; i++) {
6155 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6159 Binder.restoreCallingIdentity(callingId);
6164 public void forceStopPackage(final String packageName, int userId) {
6165 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6166 != PackageManager.PERMISSION_GRANTED) {
6167 String msg = "Permission Denial: forceStopPackage() from pid="
6168 + Binder.getCallingPid()
6169 + ", uid=" + Binder.getCallingUid()
6170 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6172 throw new SecurityException(msg);
6174 final int callingPid = Binder.getCallingPid();
6175 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6176 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6177 long callingId = Binder.clearCallingIdentity();
6179 IPackageManager pm = AppGlobals.getPackageManager();
6180 synchronized(this) {
6181 int[] users = userId == UserHandle.USER_ALL
6182 ? mUserController.getUsers() : new int[] { userId };
6183 for (int user : users) {
6186 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6188 } catch (RemoteException e) {
6191 Slog.w(TAG, "Invalid packageName: " + packageName);
6195 pm.setPackageStoppedState(packageName, true, user);
6196 } catch (RemoteException e) {
6197 } catch (IllegalArgumentException e) {
6198 Slog.w(TAG, "Failed trying to unstop package "
6199 + packageName + ": " + e);
6201 if (mUserController.isUserRunningLocked(user, 0)) {
6202 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6203 finishForceStopPackageLocked(packageName, pkgUid);
6208 Binder.restoreCallingIdentity(callingId);
6213 public void addPackageDependency(String packageName) {
6214 synchronized (this) {
6215 int callingPid = Binder.getCallingPid();
6216 if (callingPid == myPid()) {
6221 synchronized (mPidsSelfLocked) {
6222 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6225 if (proc.pkgDeps == null) {
6226 proc.pkgDeps = new ArraySet<String>(1);
6228 proc.pkgDeps.add(packageName);
6234 * The pkg name and app id have to be specified.
6237 public void killApplication(String pkg, int appId, int userId, String reason) {
6241 // Make sure the uid is valid.
6243 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6246 int callerUid = Binder.getCallingUid();
6247 // Only the system server can kill an application
6248 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6249 // Post an aysnc message to kill the application
6250 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6253 Bundle bundle = new Bundle();
6254 bundle.putString("pkg", pkg);
6255 bundle.putString("reason", reason);
6257 mHandler.sendMessage(msg);
6259 throw new SecurityException(callerUid + " cannot kill pkg: " +
6265 public void closeSystemDialogs(String reason) {
6266 enforceNotIsolatedCaller("closeSystemDialogs");
6268 final int pid = Binder.getCallingPid();
6269 final int uid = Binder.getCallingUid();
6270 final long origId = Binder.clearCallingIdentity();
6272 synchronized (this) {
6273 // Only allow this from foreground processes, so that background
6274 // applications can't abuse it to prevent system UI from being shown.
6275 if (uid >= FIRST_APPLICATION_UID) {
6277 synchronized (mPidsSelfLocked) {
6278 proc = mPidsSelfLocked.get(pid);
6280 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6281 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6282 + " from background process " + proc);
6286 closeSystemDialogsLocked(reason);
6289 Binder.restoreCallingIdentity(origId);
6293 void closeSystemDialogsLocked(String reason) {
6294 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6295 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6296 | Intent.FLAG_RECEIVER_FOREGROUND);
6297 if (reason != null) {
6298 intent.putExtra("reason", reason);
6300 mWindowManager.closeSystemDialogs(reason);
6302 mStackSupervisor.closeSystemDialogsLocked();
6304 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6305 AppOpsManager.OP_NONE, null, false, false,
6306 -1, SYSTEM_UID, UserHandle.USER_ALL);
6310 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6311 enforceNotIsolatedCaller("getProcessMemoryInfo");
6312 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6313 for (int i=pids.length-1; i>=0; i--) {
6316 synchronized (this) {
6317 synchronized (mPidsSelfLocked) {
6318 proc = mPidsSelfLocked.get(pids[i]);
6319 oomAdj = proc != null ? proc.setAdj : 0;
6322 infos[i] = new Debug.MemoryInfo();
6323 Debug.getMemoryInfo(pids[i], infos[i]);
6325 synchronized (this) {
6326 if (proc.thread != null && proc.setAdj == oomAdj) {
6327 // Record this for posterity if the process has been stable.
6328 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6329 infos[i].getTotalUss(), false, proc.pkgList);
6338 public long[] getProcessPss(int[] pids) {
6339 enforceNotIsolatedCaller("getProcessPss");
6340 long[] pss = new long[pids.length];
6341 for (int i=pids.length-1; i>=0; i--) {
6344 synchronized (this) {
6345 synchronized (mPidsSelfLocked) {
6346 proc = mPidsSelfLocked.get(pids[i]);
6347 oomAdj = proc != null ? proc.setAdj : 0;
6350 long[] tmpUss = new long[1];
6351 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6353 synchronized (this) {
6354 if (proc.thread != null && proc.setAdj == oomAdj) {
6355 // Record this for posterity if the process has been stable.
6356 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6365 public void killApplicationProcess(String processName, int uid) {
6366 if (processName == null) {
6370 int callerUid = Binder.getCallingUid();
6371 // Only the system server can kill an application
6372 if (callerUid == SYSTEM_UID) {
6373 synchronized (this) {
6374 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6375 if (app != null && app.thread != null) {
6377 app.thread.scheduleSuicide();
6378 } catch (RemoteException e) {
6379 // If the other end already died, then our work here is done.
6382 Slog.w(TAG, "Process/uid not found attempting kill of "
6383 + processName + " / " + uid);
6387 throw new SecurityException(callerUid + " cannot kill app process: " +
6392 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6393 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6394 false, true, false, false, UserHandle.getUserId(uid), reason);
6397 private void finishForceStopPackageLocked(final String packageName, int uid) {
6398 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6399 Uri.fromParts("package", packageName, null));
6400 if (!mProcessesReady) {
6401 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6402 | Intent.FLAG_RECEIVER_FOREGROUND);
6404 intent.putExtra(Intent.EXTRA_UID, uid);
6405 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6406 broadcastIntentLocked(null, null, intent,
6407 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6408 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6412 private final boolean killPackageProcessesLocked(String packageName, int appId,
6413 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6414 boolean doit, boolean evenPersistent, String reason) {
6415 ArrayList<ProcessRecord> procs = new ArrayList<>();
6417 // Remove all processes this package may have touched: all with the
6418 // same UID (except for the system or root user), and all whose name
6419 // matches the package name.
6420 final int NP = mProcessNames.getMap().size();
6421 for (int ip=0; ip<NP; ip++) {
6422 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6423 final int NA = apps.size();
6424 for (int ia=0; ia<NA; ia++) {
6425 ProcessRecord app = apps.valueAt(ia);
6426 if (app.persistent && !evenPersistent) {
6427 // we don't kill persistent processes
6437 // Skip process if it doesn't meet our oom adj requirement.
6438 if (app.setAdj < minOomAdj) {
6442 // If no package is specified, we call all processes under the
6444 if (packageName == null) {
6445 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6448 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6451 // Package has been specified, we want to hit all processes
6452 // that match it. We need to qualify this by the processes
6453 // that are running under the specified app and user ID.
6455 final boolean isDep = app.pkgDeps != null
6456 && app.pkgDeps.contains(packageName);
6457 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6460 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6463 if (!app.pkgList.containsKey(packageName) && !isDep) {
6468 // Process has passed all conditions, kill it!
6477 int N = procs.size();
6478 for (int i=0; i<N; i++) {
6479 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6481 updateOomAdjLocked();
6485 private void cleanupDisabledPackageComponentsLocked(
6486 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6488 Set<String> disabledClasses = null;
6489 boolean packageDisabled = false;
6490 IPackageManager pm = AppGlobals.getPackageManager();
6492 if (changedClasses == null) {
6493 // Nothing changed...
6497 // Determine enable/disable state of the package and its components.
6498 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6499 for (int i = changedClasses.length - 1; i >= 0; i--) {
6500 final String changedClass = changedClasses[i];
6502 if (changedClass.equals(packageName)) {
6504 // Entire package setting changed
6505 enabled = pm.getApplicationEnabledSetting(packageName,
6506 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6507 } catch (Exception e) {
6508 // No such package/component; probably racing with uninstall. In any
6509 // event it means we have nothing further to do here.
6512 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6513 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6514 if (packageDisabled) {
6515 // Entire package is disabled.
6516 // No need to continue to check component states.
6517 disabledClasses = null;
6522 enabled = pm.getComponentEnabledSetting(
6523 new ComponentName(packageName, changedClass),
6524 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6525 } catch (Exception e) {
6526 // As above, probably racing with uninstall.
6529 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6530 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6531 if (disabledClasses == null) {
6532 disabledClasses = new ArraySet<>(changedClasses.length);
6534 disabledClasses.add(changedClass);
6539 if (!packageDisabled && disabledClasses == null) {
6540 // Nothing to do here...
6544 // Clean-up disabled activities.
6545 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6546 packageName, disabledClasses, true, false, userId) && mBooted) {
6547 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6548 mStackSupervisor.scheduleIdleLocked();
6551 // Clean-up disabled tasks
6552 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6554 // Clean-up disabled services.
6555 mServices.bringDownDisabledPackageServicesLocked(
6556 packageName, disabledClasses, userId, false, killProcess, true);
6558 // Clean-up disabled providers.
6559 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6560 mProviderMap.collectPackageProvidersLocked(
6561 packageName, disabledClasses, true, false, userId, providers);
6562 for (int i = providers.size() - 1; i >= 0; i--) {
6563 removeDyingProviderLocked(null, providers.get(i), true);
6566 // Clean-up disabled broadcast receivers.
6567 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6568 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6569 packageName, disabledClasses, userId, true);
6574 final boolean clearBroadcastQueueForUserLocked(int userId) {
6575 boolean didSomething = false;
6576 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6577 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6578 null, null, userId, true);
6580 return didSomething;
6583 final boolean forceStopPackageLocked(String packageName, int appId,
6584 boolean callerWillRestart, boolean purgeCache, boolean doit,
6585 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6588 if (userId == UserHandle.USER_ALL && packageName == null) {
6589 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6592 if (appId < 0 && packageName != null) {
6594 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6595 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6596 } catch (RemoteException e) {
6601 if (packageName != null) {
6602 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6603 + " user=" + userId + ": " + reason);
6605 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6608 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6611 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6612 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6613 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6615 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6617 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6618 packageName, null, doit, evenPersistent, userId)) {
6622 didSomething = true;
6625 if (mServices.bringDownDisabledPackageServicesLocked(
6626 packageName, null, userId, evenPersistent, true, doit)) {
6630 didSomething = true;
6633 if (packageName == null) {
6634 // Remove all sticky broadcasts from this user.
6635 mStickyBroadcasts.remove(userId);
6638 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6639 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6640 userId, providers)) {
6644 didSomething = true;
6646 for (i = providers.size() - 1; i >= 0; i--) {
6647 removeDyingProviderLocked(null, providers.get(i), true);
6650 // Remove transient permissions granted from/to this package/user
6651 removeUriPermissionsForPackageLocked(packageName, userId, false);
6654 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6655 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6656 packageName, null, userId, doit);
6660 if (packageName == null || uninstalling) {
6661 // Remove pending intents. For now we only do this when force
6662 // stopping users, because we have some problems when doing this
6663 // for packages -- app widgets are not currently cleaned up for
6664 // such packages, so they can be left with bad pending intents.
6665 if (mIntentSenderRecords.size() > 0) {
6666 Iterator<WeakReference<PendingIntentRecord>> it
6667 = mIntentSenderRecords.values().iterator();
6668 while (it.hasNext()) {
6669 WeakReference<PendingIntentRecord> wpir = it.next();
6674 PendingIntentRecord pir = wpir.get();
6679 if (packageName == null) {
6680 // Stopping user, remove all objects for the user.
6681 if (pir.key.userId != userId) {
6682 // Not the same user, skip it.
6686 if (UserHandle.getAppId(pir.uid) != appId) {
6687 // Different app id, skip it.
6690 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6691 // Different user, skip it.
6694 if (!pir.key.packageName.equals(packageName)) {
6695 // Different package, skip it.
6702 didSomething = true;
6704 makeIntentSenderCanceledLocked(pir);
6705 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6706 pir.key.activity.pendingResults.remove(pir.ref);
6713 if (purgeCache && packageName != null) {
6714 AttributeCache ac = AttributeCache.instance();
6716 ac.removePackage(packageName);
6720 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6721 mStackSupervisor.scheduleIdleLocked();
6725 return didSomething;
6728 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6729 return removeProcessNameLocked(name, uid, null);
6732 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6733 final ProcessRecord expecting) {
6734 ProcessRecord old = mProcessNames.get(name, uid);
6735 // Only actually remove when the currently recorded value matches the
6736 // record that we expected; if it doesn't match then we raced with a
6737 // newly created process and we don't want to destroy the new one.
6738 if ((expecting == null) || (old == expecting)) {
6739 mProcessNames.remove(name, uid);
6741 if (old != null && old.uidRecord != null) {
6742 old.uidRecord.numProcs--;
6743 if (old.uidRecord.numProcs == 0) {
6744 // No more processes using this uid, tell clients it is gone.
6745 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6746 "No more processes in " + old.uidRecord);
6747 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6748 EventLogTags.writeAmUidStopped(uid);
6749 mActiveUids.remove(uid);
6750 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6752 old.uidRecord = null;
6754 mIsolatedProcesses.remove(uid);
6758 private final void addProcessNameLocked(ProcessRecord proc) {
6759 // We shouldn't already have a process under this name, but just in case we
6760 // need to clean up whatever may be there now.
6761 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6762 if (old == proc && proc.persistent) {
6763 // We are re-adding a persistent process. Whatevs! Just leave it there.
6764 Slog.w(TAG, "Re-adding persistent process " + proc);
6765 } else if (old != null) {
6766 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6768 UidRecord uidRec = mActiveUids.get(proc.uid);
6769 if (uidRec == null) {
6770 uidRec = new UidRecord(proc.uid);
6771 // This is the first appearance of the uid, report it now!
6772 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6773 "Creating new process uid: " + uidRec);
6774 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6775 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6776 uidRec.setWhitelist = uidRec.curWhitelist = true;
6778 uidRec.updateHasInternetPermission();
6779 mActiveUids.put(proc.uid, uidRec);
6780 EventLogTags.writeAmUidRunning(uidRec.uid);
6781 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6783 proc.uidRecord = uidRec;
6785 // Reset render thread tid if it was already set, so new process can set it again.
6786 proc.renderThreadTid = 0;
6788 mProcessNames.put(proc.processName, proc.uid, proc);
6789 if (proc.isolated) {
6790 mIsolatedProcesses.put(proc.uid, proc);
6794 boolean removeProcessLocked(ProcessRecord app,
6795 boolean callerWillRestart, boolean allowRestart, String reason) {
6796 final String name = app.processName;
6797 final int uid = app.uid;
6798 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6799 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6801 ProcessRecord old = mProcessNames.get(name, uid);
6803 // This process is no longer active, so nothing to do.
6804 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6807 removeProcessNameLocked(name, uid);
6808 if (mHeavyWeightProcess == app) {
6809 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6810 mHeavyWeightProcess.userId, 0));
6811 mHeavyWeightProcess = null;
6813 boolean needRestart = false;
6814 if (app.pid > 0 && app.pid != MY_PID) {
6816 synchronized (mPidsSelfLocked) {
6817 mPidsSelfLocked.remove(pid);
6818 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6820 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6821 boolean willRestart = false;
6822 if (app.persistent && !app.isolated) {
6823 if (!callerWillRestart) {
6829 app.kill(reason, true);
6831 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6832 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6834 handleAppDiedLocked(app, willRestart, allowRestart);
6836 removeLruProcessLocked(app);
6837 addAppLocked(app.info, null, false, null /* ABI override */);
6840 mRemovedProcesses.add(app);
6846 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6847 cleanupAppInLaunchingProvidersLocked(app, true);
6848 removeProcessLocked(app, false, true, "timeout publishing content providers");
6851 private final void processStartTimedOutLocked(ProcessRecord app) {
6852 final int pid = app.pid;
6853 boolean gone = false;
6854 synchronized (mPidsSelfLocked) {
6855 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6856 if (knownApp != null && knownApp.thread == null) {
6857 mPidsSelfLocked.remove(pid);
6863 Slog.w(TAG, "Process " + app + " failed to attach");
6864 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6865 pid, app.uid, app.processName);
6866 removeProcessNameLocked(app.processName, app.uid);
6867 if (mHeavyWeightProcess == app) {
6868 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6869 mHeavyWeightProcess.userId, 0));
6870 mHeavyWeightProcess = null;
6872 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6873 // Take care of any launching providers waiting for this process.
6874 cleanupAppInLaunchingProvidersLocked(app, true);
6875 // Take care of any services that are waiting for the process.
6876 mServices.processStartTimedOutLocked(app);
6877 app.kill("start timeout", true);
6879 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6881 removeLruProcessLocked(app);
6882 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6883 Slog.w(TAG, "Unattached app died before backup, skipping");
6884 mHandler.post(new Runnable() {
6888 IBackupManager bm = IBackupManager.Stub.asInterface(
6889 ServiceManager.getService(Context.BACKUP_SERVICE));
6890 bm.agentDisconnected(app.info.packageName);
6891 } catch (RemoteException e) {
6892 // Can't happen; the backup manager is local
6897 if (isPendingBroadcastProcessLocked(pid)) {
6898 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6899 skipPendingBroadcastLocked(pid);
6902 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6906 private final boolean attachApplicationLocked(IApplicationThread thread,
6909 // Find the application record that is being attached... either via
6910 // the pid if we are running in multiple processes, or just pull the
6911 // next app record if we are emulating process with anonymous threads.
6913 long startTime = SystemClock.uptimeMillis();
6914 if (pid != MY_PID && pid >= 0) {
6915 synchronized (mPidsSelfLocked) {
6916 app = mPidsSelfLocked.get(pid);
6923 Slog.w(TAG, "No pending application record for pid " + pid
6924 + " (IApplicationThread " + thread + "); dropping process");
6925 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6926 if (pid > 0 && pid != MY_PID) {
6927 killProcessQuiet(pid);
6928 //TODO: killProcessGroup(app.info.uid, pid);
6931 thread.scheduleExit();
6932 } catch (Exception e) {
6933 // Ignore exceptions.
6939 // If this application record is still attached to a previous
6940 // process, clean it up now.
6941 if (app.thread != null) {
6942 handleAppDiedLocked(app, true, true);
6945 // Tell the process all about itself.
6947 if (DEBUG_ALL) Slog.v(
6948 TAG, "Binding process pid " + pid + " to record " + app);
6950 final String processName = app.processName;
6952 AppDeathRecipient adr = new AppDeathRecipient(
6954 thread.asBinder().linkToDeath(adr, 0);
6955 app.deathRecipient = adr;
6956 } catch (RemoteException e) {
6957 app.resetPackageList(mProcessStats);
6958 startProcessLocked(app, "link fail", processName);
6962 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6964 app.makeActive(thread, mProcessStats);
6965 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6966 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6967 app.forcingToImportant = null;
6968 updateProcessForegroundLocked(app, false, false);
6969 app.hasShownUi = false;
6970 app.debugging = false;
6972 app.killedByAm = false;
6976 // We carefully use the same state that PackageManager uses for
6977 // filtering, since we use this flag to decide if we need to install
6978 // providers when user is unlocked later
6979 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6981 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6983 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6984 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6986 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6987 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6989 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6992 checkTime(startTime, "attachApplicationLocked: before bindApplication");
6995 Slog.i(TAG, "Launching preboot mode app: " + app);
6998 if (DEBUG_ALL) Slog.v(
6999 TAG, "New app record " + app
7000 + " thread=" + thread.asBinder() + " pid=" + pid);
7002 int testMode = ApplicationThreadConstants.DEBUG_OFF;
7003 if (mDebugApp != null && mDebugApp.equals(processName)) {
7004 testMode = mWaitForDebugger
7005 ? ApplicationThreadConstants.DEBUG_WAIT
7006 : ApplicationThreadConstants.DEBUG_ON;
7007 app.debugging = true;
7008 if (mDebugTransient) {
7009 mDebugApp = mOrigDebugApp;
7010 mWaitForDebugger = mOrigWaitForDebugger;
7014 ProfilerInfo profilerInfo = null;
7015 String preBindAgent = null;
7016 if (mProfileApp != null && mProfileApp.equals(processName)) {
7018 if (mProfilerInfo != null) {
7019 // Send a profiler info object to the app if either a file is given, or
7020 // an agent should be loaded at bind-time.
7021 boolean needsInfo = mProfilerInfo.profileFile != null
7022 || mProfilerInfo.attachAgentDuringBind;
7023 profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7024 if (!mProfilerInfo.attachAgentDuringBind) {
7025 preBindAgent = mProfilerInfo.agent;
7028 } else if (app.instr != null && app.instr.mProfileFile != null) {
7029 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7033 boolean enableTrackAllocation = false;
7034 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7035 enableTrackAllocation = true;
7036 mTrackAllocationApp = null;
7039 // If the app is being launched for restore or full backup, set it up specially
7040 boolean isRestrictedBackupMode = false;
7041 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7042 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7043 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7044 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7045 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7048 if (app.instr != null) {
7049 notifyPackageUse(app.instr.mClass.getPackageName(),
7050 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7052 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7053 + processName + " with config " + getGlobalConfiguration());
7054 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7055 app.compat = compatibilityInfoForPackageLocked(appInfo);
7057 if (profilerInfo != null && profilerInfo.profileFd != null) {
7058 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7061 // We deprecated Build.SERIAL and it is not accessible to
7062 // apps that target the v2 security sandbox. Since access to
7063 // the serial is now behind a permission we push down the value.
7064 String buildSerial = appInfo.targetSandboxVersion < 2
7065 ? sTheRealBuildSerial : Build.UNKNOWN;
7067 // Check if this is a secondary process that should be incorporated into some
7068 // currently active instrumentation. (Note we do this AFTER all of the profiling
7069 // stuff above because profiling can currently happen only in the primary
7070 // instrumentation process.)
7071 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7072 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7073 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7074 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7075 if (aInstr.mTargetProcesses.length == 0) {
7076 // This is the wildcard mode, where every process brought up for
7077 // the target instrumentation should be included.
7078 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7080 aInstr.mRunningProcesses.add(app);
7083 for (String proc : aInstr.mTargetProcesses) {
7084 if (proc.equals(app.processName)) {
7086 aInstr.mRunningProcesses.add(app);
7095 // If we were asked to attach an agent on startup, do so now, before we're binding
7096 // application code.
7097 if (preBindAgent != null) {
7098 thread.attachAgent(preBindAgent);
7101 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7102 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7103 if (app.instr != null) {
7104 thread.bindApplication(processName, appInfo, providers,
7106 profilerInfo, app.instr.mArguments,
7108 app.instr.mUiAutomationConnection, testMode,
7109 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7110 isRestrictedBackupMode || !normalMode, app.persistent,
7111 new Configuration(getGlobalConfiguration()), app.compat,
7112 getCommonServicesLocked(app.isolated),
7113 mCoreSettingsObserver.getCoreSettingsLocked(),
7116 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7117 null, null, null, testMode,
7118 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7119 isRestrictedBackupMode || !normalMode, app.persistent,
7120 new Configuration(getGlobalConfiguration()), app.compat,
7121 getCommonServicesLocked(app.isolated),
7122 mCoreSettingsObserver.getCoreSettingsLocked(),
7126 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7127 updateLruProcessLocked(app, false, null);
7128 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7129 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7130 } catch (Exception e) {
7131 // todo: Yikes! What should we do? For now we will try to
7132 // start another process, but that could easily get us in
7133 // an infinite loop of restarting processes...
7134 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7136 app.resetPackageList(mProcessStats);
7137 app.unlinkDeathRecipient();
7138 startProcessLocked(app, "bind fail", processName);
7142 // Remove this record from the list of starting applications.
7143 mPersistentStartingProcesses.remove(app);
7144 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7145 "Attach application locked removing on hold: " + app);
7146 mProcessesOnHold.remove(app);
7148 boolean badApp = false;
7149 boolean didSomething = false;
7151 // See if the top visible activity is waiting to run in this process...
7154 if (mStackSupervisor.attachApplicationLocked(app)) {
7155 didSomething = true;
7157 } catch (Exception e) {
7158 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7163 // Find any services that should be running in this process...
7166 didSomething |= mServices.attachApplicationLocked(app, processName);
7167 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7168 } catch (Exception e) {
7169 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7174 // Check if a next-broadcast receiver is in this process...
7175 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7177 didSomething |= sendPendingBroadcastsLocked(app);
7178 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7179 } catch (Exception e) {
7180 // If the app died trying to launch the receiver we declare it 'bad'
7181 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7186 // Check whether the next backup agent is in this process...
7187 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7188 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7189 "New app is backup target, launching agent for " + app);
7190 notifyPackageUse(mBackupTarget.appInfo.packageName,
7191 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7193 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7194 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7195 mBackupTarget.backupMode);
7196 } catch (Exception e) {
7197 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7203 app.kill("error during init", true);
7204 handleAppDiedLocked(app, false, true);
7208 if (!didSomething) {
7209 updateOomAdjLocked();
7210 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7217 public final void attachApplication(IApplicationThread thread) {
7218 synchronized (this) {
7219 int callingPid = Binder.getCallingPid();
7220 final long origId = Binder.clearCallingIdentity();
7221 attachApplicationLocked(thread, callingPid);
7222 Binder.restoreCallingIdentity(origId);
7227 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7228 final long origId = Binder.clearCallingIdentity();
7229 synchronized (this) {
7230 ActivityStack stack = ActivityRecord.getStackLocked(token);
7231 if (stack != null) {
7233 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7234 false /* processPausingActivities */, config);
7235 if (stopProfiling) {
7236 if ((mProfileProc == r.app) && mProfilerInfo != null) {
7237 clearProfilerLocked();
7242 Binder.restoreCallingIdentity(origId);
7245 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7246 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7247 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7250 void enableScreenAfterBoot() {
7251 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7252 SystemClock.uptimeMillis());
7253 mWindowManager.enableScreenAfterBoot();
7255 synchronized (this) {
7256 updateEventDispatchingLocked();
7261 public void showBootMessage(final CharSequence msg, final boolean always) {
7262 if (Binder.getCallingUid() != myUid()) {
7263 throw new SecurityException();
7265 mWindowManager.showBootMessage(msg, always);
7269 public void keyguardGoingAway(int flags) {
7270 enforceNotIsolatedCaller("keyguardGoingAway");
7271 final long token = Binder.clearCallingIdentity();
7273 synchronized (this) {
7274 mKeyguardController.keyguardGoingAway(flags);
7277 Binder.restoreCallingIdentity(token);
7282 * @return whther the keyguard is currently locked.
7284 boolean isKeyguardLocked() {
7285 return mKeyguardController.isKeyguardLocked();
7288 final void finishBooting() {
7289 synchronized (this) {
7290 if (!mBootAnimationComplete) {
7291 mCallFinishBooting = true;
7294 mCallFinishBooting = false;
7297 ArraySet<String> completedIsas = new ArraySet<String>();
7298 for (String abi : Build.SUPPORTED_ABIS) {
7299 zygoteProcess.establishZygoteConnectionForAbi(abi);
7300 final String instructionSet = VMRuntime.getInstructionSet(abi);
7301 if (!completedIsas.contains(instructionSet)) {
7303 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7304 } catch (InstallerException e) {
7305 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7306 e.getMessage() +")");
7308 completedIsas.add(instructionSet);
7312 IntentFilter pkgFilter = new IntentFilter();
7313 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7314 pkgFilter.addDataScheme("package");
7315 mContext.registerReceiver(new BroadcastReceiver() {
7317 public void onReceive(Context context, Intent intent) {
7318 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7320 for (String pkg : pkgs) {
7321 synchronized (ActivityManagerService.this) {
7322 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7323 0, "query restart")) {
7324 setResultCode(Activity.RESULT_OK);
7333 IntentFilter dumpheapFilter = new IntentFilter();
7334 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7335 mContext.registerReceiver(new BroadcastReceiver() {
7337 public void onReceive(Context context, Intent intent) {
7338 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7339 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7341 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7346 // Let system services know.
7347 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7349 synchronized (this) {
7350 // Ensure that any processes we had put on hold are now started
7352 final int NP = mProcessesOnHold.size();
7354 ArrayList<ProcessRecord> procs =
7355 new ArrayList<ProcessRecord>(mProcessesOnHold);
7356 for (int ip=0; ip<NP; ip++) {
7357 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7359 startProcessLocked(procs.get(ip), "on-hold", null);
7363 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7364 // Start looking for apps that are abusing wake locks.
7365 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7366 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7367 // Tell anyone interested that we are done booting!
7368 SystemProperties.set("sys.boot_completed", "1");
7370 // And trigger dev.bootcomplete if we are not showing encryption progress
7371 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7372 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7373 SystemProperties.set("dev.bootcomplete", "1");
7375 mUserController.sendBootCompletedLocked(
7376 new IIntentReceiver.Stub() {
7378 public void performReceive(Intent intent, int resultCode,
7379 String data, Bundle extras, boolean ordered,
7380 boolean sticky, int sendingUser) {
7381 synchronized (ActivityManagerService.this) {
7382 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7387 scheduleStartProfilesLocked();
7393 public void bootAnimationComplete() {
7394 final boolean callFinishBooting;
7395 synchronized (this) {
7396 callFinishBooting = mCallFinishBooting;
7397 mBootAnimationComplete = true;
7399 if (callFinishBooting) {
7400 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7402 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7406 final void ensureBootCompleted() {
7408 boolean enableScreen;
7409 synchronized (this) {
7412 enableScreen = !mBooted;
7417 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7419 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7423 enableScreenAfterBoot();
7428 public final void activityResumed(IBinder token) {
7429 final long origId = Binder.clearCallingIdentity();
7430 synchronized(this) {
7431 ActivityRecord.activityResumedLocked(token);
7432 mWindowManager.notifyAppResumedFinished(token);
7434 Binder.restoreCallingIdentity(origId);
7438 public final void activityPaused(IBinder token) {
7439 final long origId = Binder.clearCallingIdentity();
7440 synchronized(this) {
7441 ActivityStack stack = ActivityRecord.getStackLocked(token);
7442 if (stack != null) {
7443 stack.activityPausedLocked(token, false);
7446 Binder.restoreCallingIdentity(origId);
7450 public final void activityStopped(IBinder token, Bundle icicle,
7451 PersistableBundle persistentState, CharSequence description) {
7452 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7454 // Refuse possible leaked file descriptors
7455 if (icicle != null && icicle.hasFileDescriptors()) {
7456 throw new IllegalArgumentException("File descriptors passed in Bundle");
7459 final long origId = Binder.clearCallingIdentity();
7461 synchronized (this) {
7462 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7464 r.activityStoppedLocked(icicle, persistentState, description);
7470 Binder.restoreCallingIdentity(origId);
7474 public final void activityDestroyed(IBinder token) {
7475 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7476 synchronized (this) {
7477 ActivityStack stack = ActivityRecord.getStackLocked(token);
7478 if (stack != null) {
7479 stack.activityDestroyedLocked(token, "activityDestroyed");
7485 public final void activityRelaunched(IBinder token) {
7486 final long origId = Binder.clearCallingIdentity();
7487 synchronized (this) {
7488 mStackSupervisor.activityRelaunchedLocked(token);
7490 Binder.restoreCallingIdentity(origId);
7494 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7495 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7496 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7497 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7498 synchronized (this) {
7499 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7500 if (record == null) {
7501 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7502 + "found for: " + token);
7504 record.setSizeConfigurations(horizontalSizeConfiguration,
7505 verticalSizeConfigurations, smallestSizeConfigurations);
7510 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7511 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7515 public final void notifyEnterAnimationComplete(IBinder token) {
7516 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7520 public String getCallingPackage(IBinder token) {
7521 synchronized (this) {
7522 ActivityRecord r = getCallingRecordLocked(token);
7523 return r != null ? r.info.packageName : null;
7528 public ComponentName getCallingActivity(IBinder token) {
7529 synchronized (this) {
7530 ActivityRecord r = getCallingRecordLocked(token);
7531 return r != null ? r.intent.getComponent() : null;
7535 private ActivityRecord getCallingRecordLocked(IBinder token) {
7536 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7544 public ComponentName getActivityClassForToken(IBinder token) {
7545 synchronized(this) {
7546 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7550 return r.intent.getComponent();
7555 public String getPackageForToken(IBinder token) {
7556 synchronized(this) {
7557 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7561 return r.packageName;
7566 public boolean isRootVoiceInteraction(IBinder token) {
7567 synchronized(this) {
7568 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7572 return r.rootVoiceInteraction;
7577 public IIntentSender getIntentSender(int type,
7578 String packageName, IBinder token, String resultWho,
7579 int requestCode, Intent[] intents, String[] resolvedTypes,
7580 int flags, Bundle bOptions, int userId) {
7581 enforceNotIsolatedCaller("getIntentSender");
7582 // Refuse possible leaked file descriptors
7583 if (intents != null) {
7584 if (intents.length < 1) {
7585 throw new IllegalArgumentException("Intents array length must be >= 1");
7587 for (int i=0; i<intents.length; i++) {
7588 Intent intent = intents[i];
7589 if (intent != null) {
7590 if (intent.hasFileDescriptors()) {
7591 throw new IllegalArgumentException("File descriptors passed in Intent");
7593 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7594 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7595 throw new IllegalArgumentException(
7596 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7598 intents[i] = new Intent(intent);
7601 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7602 throw new IllegalArgumentException(
7603 "Intent array length does not match resolvedTypes length");
7606 if (bOptions != null) {
7607 if (bOptions.hasFileDescriptors()) {
7608 throw new IllegalArgumentException("File descriptors passed in options");
7612 synchronized(this) {
7613 int callingUid = Binder.getCallingUid();
7614 int origUserId = userId;
7615 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7616 type == ActivityManager.INTENT_SENDER_BROADCAST,
7617 ALLOW_NON_FULL, "getIntentSender", null);
7618 if (origUserId == UserHandle.USER_CURRENT) {
7619 // We don't want to evaluate this until the pending intent is
7620 // actually executed. However, we do want to always do the
7621 // security checking for it above.
7622 userId = UserHandle.USER_CURRENT;
7625 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7626 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7627 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7628 if (!UserHandle.isSameApp(callingUid, uid)) {
7629 String msg = "Permission Denial: getIntentSender() from pid="
7630 + Binder.getCallingPid()
7631 + ", uid=" + Binder.getCallingUid()
7632 + ", (need uid=" + uid + ")"
7633 + " is not allowed to send as package " + packageName;
7635 throw new SecurityException(msg);
7639 return getIntentSenderLocked(type, packageName, callingUid, userId,
7640 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7642 } catch (RemoteException e) {
7643 throw new SecurityException(e);
7648 IIntentSender getIntentSenderLocked(int type, String packageName,
7649 int callingUid, int userId, IBinder token, String resultWho,
7650 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7652 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7653 ActivityRecord activity = null;
7654 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7655 activity = ActivityRecord.isInStackLocked(token);
7656 if (activity == null) {
7657 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7660 if (activity.finishing) {
7661 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7666 // We're going to be splicing together extras before sending, so we're
7667 // okay poking into any contained extras.
7668 if (intents != null) {
7669 for (int i = 0; i < intents.length; i++) {
7670 intents[i].setDefusable(true);
7673 Bundle.setDefusable(bOptions, true);
7675 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7676 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7677 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7678 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7679 |PendingIntent.FLAG_UPDATE_CURRENT);
7681 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7682 type, packageName, activity, resultWho,
7683 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7684 WeakReference<PendingIntentRecord> ref;
7685 ref = mIntentSenderRecords.get(key);
7686 PendingIntentRecord rec = ref != null ? ref.get() : null;
7688 if (!cancelCurrent) {
7689 if (updateCurrent) {
7690 if (rec.key.requestIntent != null) {
7691 rec.key.requestIntent.replaceExtras(intents != null ?
7692 intents[intents.length - 1] : null);
7694 if (intents != null) {
7695 intents[intents.length-1] = rec.key.requestIntent;
7696 rec.key.allIntents = intents;
7697 rec.key.allResolvedTypes = resolvedTypes;
7699 rec.key.allIntents = null;
7700 rec.key.allResolvedTypes = null;
7705 makeIntentSenderCanceledLocked(rec);
7706 mIntentSenderRecords.remove(key);
7711 rec = new PendingIntentRecord(this, key, callingUid);
7712 mIntentSenderRecords.put(key, rec.ref);
7713 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7714 if (activity.pendingResults == null) {
7715 activity.pendingResults
7716 = new HashSet<WeakReference<PendingIntentRecord>>();
7718 activity.pendingResults.add(rec.ref);
7724 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7725 Intent intent, String resolvedType,
7726 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7727 if (target instanceof PendingIntentRecord) {
7728 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7729 whitelistToken, finishedReceiver, requiredPermission, options);
7731 if (intent == null) {
7732 // Weird case: someone has given us their own custom IIntentSender, and now
7733 // they have someone else trying to send to it but of course this isn't
7734 // really a PendingIntent, so there is no base Intent, and the caller isn't
7735 // supplying an Intent... but we never want to dispatch a null Intent to
7736 // a receiver, so um... let's make something up.
7737 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7738 intent = new Intent(Intent.ACTION_MAIN);
7741 target.send(code, intent, resolvedType, whitelistToken, null,
7742 requiredPermission, options);
7743 } catch (RemoteException e) {
7745 // Platform code can rely on getting a result back when the send is done, but if
7746 // this intent sender is from outside of the system we can't rely on it doing that.
7747 // So instead we don't give it the result receiver, and instead just directly
7748 // report the finish immediately.
7749 if (finishedReceiver != null) {
7751 finishedReceiver.performReceive(intent, 0,
7752 null, null, false, false, UserHandle.getCallingUserId());
7753 } catch (RemoteException e) {
7761 public void cancelIntentSender(IIntentSender sender) {
7762 if (!(sender instanceof PendingIntentRecord)) {
7765 synchronized(this) {
7766 PendingIntentRecord rec = (PendingIntentRecord)sender;
7768 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7769 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7770 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7771 String msg = "Permission Denial: cancelIntentSender() from pid="
7772 + Binder.getCallingPid()
7773 + ", uid=" + Binder.getCallingUid()
7774 + " is not allowed to cancel package "
7775 + rec.key.packageName;
7777 throw new SecurityException(msg);
7779 } catch (RemoteException e) {
7780 throw new SecurityException(e);
7782 cancelIntentSenderLocked(rec, true);
7786 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7787 makeIntentSenderCanceledLocked(rec);
7788 mIntentSenderRecords.remove(rec.key);
7789 if (cleanActivity && rec.key.activity != null) {
7790 rec.key.activity.pendingResults.remove(rec.ref);
7794 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7795 rec.canceled = true;
7796 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7797 if (callbacks != null) {
7798 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7803 public String getPackageForIntentSender(IIntentSender pendingResult) {
7804 if (!(pendingResult instanceof PendingIntentRecord)) {
7808 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7809 return res.key.packageName;
7810 } catch (ClassCastException e) {
7816 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7817 if (!(sender instanceof PendingIntentRecord)) {
7820 synchronized(this) {
7821 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7826 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7827 IResultReceiver receiver) {
7828 if (!(sender instanceof PendingIntentRecord)) {
7831 synchronized(this) {
7832 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7837 public int getUidForIntentSender(IIntentSender sender) {
7838 if (sender instanceof PendingIntentRecord) {
7840 PendingIntentRecord res = (PendingIntentRecord)sender;
7842 } catch (ClassCastException e) {
7849 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7850 if (!(pendingResult instanceof PendingIntentRecord)) {
7854 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7855 if (res.key.allIntents == null) {
7858 for (int i=0; i<res.key.allIntents.length; i++) {
7859 Intent intent = res.key.allIntents[i];
7860 if (intent.getPackage() != null && intent.getComponent() != null) {
7865 } catch (ClassCastException e) {
7871 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7872 if (!(pendingResult instanceof PendingIntentRecord)) {
7876 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7877 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7881 } catch (ClassCastException e) {
7887 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7888 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7889 "getIntentForIntentSender()");
7890 if (!(pendingResult instanceof PendingIntentRecord)) {
7894 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7895 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7896 } catch (ClassCastException e) {
7902 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7903 if (!(pendingResult instanceof PendingIntentRecord)) {
7907 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7908 synchronized (this) {
7909 return getTagForIntentSenderLocked(res, prefix);
7911 } catch (ClassCastException e) {
7916 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7917 final Intent intent = res.key.requestIntent;
7918 if (intent != null) {
7919 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7920 || res.lastTagPrefix.equals(prefix))) {
7923 res.lastTagPrefix = prefix;
7924 final StringBuilder sb = new StringBuilder(128);
7925 if (prefix != null) {
7928 if (intent.getAction() != null) {
7929 sb.append(intent.getAction());
7930 } else if (intent.getComponent() != null) {
7931 intent.getComponent().appendShortString(sb);
7935 return res.lastTag = sb.toString();
7941 public void setProcessLimit(int max) {
7942 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7943 "setProcessLimit()");
7944 synchronized (this) {
7945 mConstants.setOverrideMaxCachedProcesses(max);
7951 public int getProcessLimit() {
7952 synchronized (this) {
7953 return mConstants.getOverrideMaxCachedProcesses();
7957 void importanceTokenDied(ImportanceToken token) {
7958 synchronized (ActivityManagerService.this) {
7959 synchronized (mPidsSelfLocked) {
7961 = mImportantProcesses.get(token.pid);
7965 mImportantProcesses.remove(token.pid);
7966 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7970 pr.forcingToImportant = null;
7971 updateProcessForegroundLocked(pr, false, false);
7973 updateOomAdjLocked();
7978 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7979 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7980 "setProcessImportant()");
7981 synchronized(this) {
7982 boolean changed = false;
7984 synchronized (mPidsSelfLocked) {
7985 ProcessRecord pr = mPidsSelfLocked.get(pid);
7986 if (pr == null && isForeground) {
7987 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7990 ImportanceToken oldToken = mImportantProcesses.get(pid);
7991 if (oldToken != null) {
7992 oldToken.token.unlinkToDeath(oldToken, 0);
7993 mImportantProcesses.remove(pid);
7995 pr.forcingToImportant = null;
7999 if (isForeground && token != null) {
8000 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8002 public void binderDied() {
8003 importanceTokenDied(this);
8007 token.linkToDeath(newToken, 0);
8008 mImportantProcesses.put(pid, newToken);
8009 pr.forcingToImportant = newToken;
8011 } catch (RemoteException e) {
8012 // If the process died while doing this, we will later
8013 // do the cleanup with the process death link.
8019 updateOomAdjLocked();
8025 public boolean isAppForeground(int uid) throws RemoteException {
8026 synchronized (this) {
8027 UidRecord uidRec = mActiveUids.get(uid);
8028 if (uidRec == null || uidRec.idle) {
8031 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8035 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8036 // be guarded by permission checking.
8037 int getUidState(int uid) {
8038 synchronized (this) {
8039 return getUidStateLocked(uid);
8043 int getUidStateLocked(int uid) {
8044 UidRecord uidRec = mActiveUids.get(uid);
8045 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8049 public boolean isInMultiWindowMode(IBinder token) {
8050 final long origId = Binder.clearCallingIdentity();
8052 synchronized(this) {
8053 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8057 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8058 return !r.getTask().mFullscreen;
8061 Binder.restoreCallingIdentity(origId);
8066 public boolean isInPictureInPictureMode(IBinder token) {
8067 final long origId = Binder.clearCallingIdentity();
8069 synchronized(this) {
8070 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8073 Binder.restoreCallingIdentity(origId);
8077 private boolean isInPictureInPictureMode(ActivityRecord r) {
8078 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8079 r.getStack().isInStackLocked(r) == null) {
8083 // If we are animating to fullscreen then we have already dispatched the PIP mode
8084 // changed, so we should reflect that check here as well.
8085 final PinnedActivityStack stack = r.getStack();
8086 final PinnedStackWindowController windowController = stack.getWindowContainerController();
8087 return !windowController.isAnimatingBoundsToFullscreen();
8091 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8092 final long origId = Binder.clearCallingIdentity();
8094 synchronized(this) {
8095 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8096 "enterPictureInPictureMode", token, params);
8098 // If the activity is already in picture in picture mode, then just return early
8099 if (isInPictureInPictureMode(r)) {
8103 // Activity supports picture-in-picture, now check that we can enter PiP at this
8105 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8106 false /* beforeStopping */)) {
8110 final Runnable enterPipRunnable = () -> {
8111 // Only update the saved args from the args that are set
8112 r.pictureInPictureArgs.copyOnlySet(params);
8113 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8114 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8115 // Adjust the source bounds by the insets for the transition down
8116 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8117 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8118 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8119 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8120 stack.setPictureInPictureAspectRatio(aspectRatio);
8121 stack.setPictureInPictureActions(actions);
8123 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8124 r.supportsEnterPipOnTaskSwitch);
8125 logPictureInPictureArgs(params);
8128 if (isKeyguardLocked()) {
8129 // If the keyguard is showing or occluded, then try and dismiss it before
8130 // entering picture-in-picture (this will prompt the user to authenticate if the
8131 // device is currently locked).
8133 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8135 public void onDismissError() throws RemoteException {
8140 public void onDismissSucceeded() throws RemoteException {
8141 mHandler.post(enterPipRunnable);
8145 public void onDismissCancelled() throws RemoteException {
8149 } catch (RemoteException e) {
8153 // Enter picture in picture immediately otherwise
8154 enterPipRunnable.run();
8159 Binder.restoreCallingIdentity(origId);
8164 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8165 final long origId = Binder.clearCallingIdentity();
8167 synchronized(this) {
8168 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8169 "setPictureInPictureParams", token, params);
8171 // Only update the saved args from the args that are set
8172 r.pictureInPictureArgs.copyOnlySet(params);
8173 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8174 // If the activity is already in picture-in-picture, update the pinned stack now
8175 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8176 // be used the next time the activity enters PiP
8177 final PinnedActivityStack stack = r.getStack();
8178 if (!stack.isAnimatingBoundsToFullscreen()) {
8179 stack.setPictureInPictureAspectRatio(
8180 r.pictureInPictureArgs.getAspectRatio());
8181 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8184 logPictureInPictureArgs(params);
8187 Binder.restoreCallingIdentity(origId);
8192 public int getMaxNumPictureInPictureActions(IBinder token) {
8193 // Currently, this is a static constant, but later, we may change this to be dependent on
8194 // the context of the activity
8198 private void logPictureInPictureArgs(PictureInPictureParams params) {
8199 if (params.hasSetActions()) {
8200 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8201 params.getActions().size());
8203 if (params.hasSetAspectRatio()) {
8204 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8205 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8206 MetricsLogger.action(lm);
8211 * Checks the state of the system and the activity associated with the given {@param token} to
8212 * verify that picture-in-picture is supported for that activity.
8214 * @return the activity record for the given {@param token} if all the checks pass.
8216 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8217 IBinder token, PictureInPictureParams params) {
8218 if (!mSupportsPictureInPicture) {
8219 throw new IllegalStateException(caller
8220 + ": Device doesn't support picture-in-picture mode.");
8223 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8225 throw new IllegalStateException(caller
8226 + ": Can't find activity for token=" + token);
8229 if (!r.supportsPictureInPicture()) {
8230 throw new IllegalStateException(caller
8231 + ": Current activity does not support picture-in-picture.");
8234 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8235 throw new IllegalStateException(caller
8236 + ": Activities on the home, assistant, or recents stack not supported");
8239 if (params.hasSetAspectRatio()
8240 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8241 params.getAspectRatio())) {
8242 final float minAspectRatio = mContext.getResources().getFloat(
8243 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8244 final float maxAspectRatio = mContext.getResources().getFloat(
8245 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8246 throw new IllegalArgumentException(String.format(caller
8247 + ": Aspect ratio is too extreme (must be between %f and %f).",
8248 minAspectRatio, maxAspectRatio));
8251 // Truncate the number of actions if necessary
8252 params.truncateActions(getMaxNumPictureInPictureActions(token));
8257 // =========================================================
8259 // =========================================================
8261 static class ProcessInfoService extends IProcessInfoService.Stub {
8262 final ActivityManagerService mActivityManagerService;
8263 ProcessInfoService(ActivityManagerService activityManagerService) {
8264 mActivityManagerService = activityManagerService;
8268 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8269 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8270 /*in*/ pids, /*out*/ states, null);
8274 public void getProcessStatesAndOomScoresFromPids(
8275 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8276 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8277 /*in*/ pids, /*out*/ states, /*out*/ scores);
8282 * For each PID in the given input array, write the current process state
8283 * for that process into the states array, or -1 to indicate that no
8284 * process with the given PID exists. If scores array is provided, write
8285 * the oom score for the process into the scores array, with INVALID_ADJ
8286 * indicating the PID doesn't exist.
8288 public void getProcessStatesAndOomScoresForPIDs(
8289 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8290 if (scores != null) {
8291 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8292 "getProcessStatesAndOomScoresForPIDs()");
8296 throw new NullPointerException("pids");
8297 } else if (states == null) {
8298 throw new NullPointerException("states");
8299 } else if (pids.length != states.length) {
8300 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8301 } else if (scores != null && pids.length != scores.length) {
8302 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8305 synchronized (mPidsSelfLocked) {
8306 for (int i = 0; i < pids.length; i++) {
8307 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8308 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8310 if (scores != null) {
8311 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8317 // =========================================================
8319 // =========================================================
8321 static class PermissionController extends IPermissionController.Stub {
8322 ActivityManagerService mActivityManagerService;
8323 PermissionController(ActivityManagerService activityManagerService) {
8324 mActivityManagerService = activityManagerService;
8328 public boolean checkPermission(String permission, int pid, int uid) {
8329 return mActivityManagerService.checkPermission(permission, pid,
8330 uid) == PackageManager.PERMISSION_GRANTED;
8334 public String[] getPackagesForUid(int uid) {
8335 return mActivityManagerService.mContext.getPackageManager()
8336 .getPackagesForUid(uid);
8340 public boolean isRuntimePermission(String permission) {
8342 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8343 .getPermissionInfo(permission, 0);
8344 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8345 == PermissionInfo.PROTECTION_DANGEROUS;
8346 } catch (NameNotFoundException nnfe) {
8347 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8353 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8355 public int checkComponentPermission(String permission, int pid, int uid,
8356 int owningUid, boolean exported) {
8357 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8358 owningUid, exported);
8362 public Object getAMSLock() {
8363 return ActivityManagerService.this;
8368 * This can be called with or without the global lock held.
8370 int checkComponentPermission(String permission, int pid, int uid,
8371 int owningUid, boolean exported) {
8372 if (pid == MY_PID) {
8373 return PackageManager.PERMISSION_GRANTED;
8375 return ActivityManager.checkComponentPermission(permission, uid,
8376 owningUid, exported);
8380 * As the only public entry point for permissions checking, this method
8381 * can enforce the semantic that requesting a check on a null global
8382 * permission is automatically denied. (Internally a null permission
8383 * string is used when calling {@link #checkComponentPermission} in cases
8384 * when only uid-based security is needed.)
8386 * This can be called with or without the global lock held.
8389 public int checkPermission(String permission, int pid, int uid) {
8390 if (permission == null) {
8391 return PackageManager.PERMISSION_DENIED;
8393 return checkComponentPermission(permission, pid, uid, -1, true);
8397 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8398 if (permission == null) {
8399 return PackageManager.PERMISSION_DENIED;
8402 // We might be performing an operation on behalf of an indirect binder
8403 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8404 // client identity accordingly before proceeding.
8405 Identity tlsIdentity = sCallerIdentity.get();
8406 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8407 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8408 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8409 uid = tlsIdentity.uid;
8410 pid = tlsIdentity.pid;
8413 return checkComponentPermission(permission, pid, uid, -1, true);
8417 * Binder IPC calls go through the public entry point.
8418 * This can be called with or without the global lock held.
8420 int checkCallingPermission(String permission) {
8421 return checkPermission(permission,
8422 Binder.getCallingPid(),
8423 UserHandle.getAppId(Binder.getCallingUid()));
8427 * This can be called with or without the global lock held.
8429 void enforceCallingPermission(String permission, String func) {
8430 if (checkCallingPermission(permission)
8431 == PackageManager.PERMISSION_GRANTED) {
8435 String msg = "Permission Denial: " + func + " from pid="
8436 + Binder.getCallingPid()
8437 + ", uid=" + Binder.getCallingUid()
8438 + " requires " + permission;
8440 throw new SecurityException(msg);
8444 * Determine if UID is holding permissions required to access {@link Uri} in
8445 * the given {@link ProviderInfo}. Final permission checking is always done
8446 * in {@link ContentProvider}.
8448 private final boolean checkHoldingPermissionsLocked(
8449 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8450 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8451 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8452 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8453 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8454 != PERMISSION_GRANTED) {
8458 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8461 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8462 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8463 if (pi.applicationInfo.uid == uid) {
8465 } else if (!pi.exported) {
8469 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8470 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8472 // check if target holds top-level <provider> permissions
8473 if (!readMet && pi.readPermission != null && considerUidPermissions
8474 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8477 if (!writeMet && pi.writePermission != null && considerUidPermissions
8478 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8482 // track if unprotected read/write is allowed; any denied
8483 // <path-permission> below removes this ability
8484 boolean allowDefaultRead = pi.readPermission == null;
8485 boolean allowDefaultWrite = pi.writePermission == null;
8487 // check if target holds any <path-permission> that match uri
8488 final PathPermission[] pps = pi.pathPermissions;
8490 final String path = grantUri.uri.getPath();
8492 while (i > 0 && (!readMet || !writeMet)) {
8494 PathPermission pp = pps[i];
8495 if (pp.match(path)) {
8497 final String pprperm = pp.getReadPermission();
8498 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8499 "Checking read perm for " + pprperm + " for " + pp.getPath()
8500 + ": match=" + pp.match(path)
8501 + " check=" + pm.checkUidPermission(pprperm, uid));
8502 if (pprperm != null) {
8503 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8504 == PERMISSION_GRANTED) {
8507 allowDefaultRead = false;
8512 final String ppwperm = pp.getWritePermission();
8513 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8514 "Checking write perm " + ppwperm + " for " + pp.getPath()
8515 + ": match=" + pp.match(path)
8516 + " check=" + pm.checkUidPermission(ppwperm, uid));
8517 if (ppwperm != null) {
8518 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8519 == PERMISSION_GRANTED) {
8522 allowDefaultWrite = false;
8530 // grant unprotected <provider> read/write, if not blocked by
8531 // <path-permission> above
8532 if (allowDefaultRead) readMet = true;
8533 if (allowDefaultWrite) writeMet = true;
8535 } catch (RemoteException e) {
8539 return readMet && writeMet;
8542 public boolean isAppStartModeDisabled(int uid, String packageName) {
8543 synchronized (this) {
8544 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8545 == ActivityManager.APP_START_MODE_DISABLED;
8549 // Unified app-op and target sdk check
8550 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8551 // Apps that target O+ are always subject to background check
8552 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8553 if (DEBUG_BACKGROUND_CHECK) {
8554 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8556 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8558 // ...and legacy apps get an AppOp check
8559 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8561 if (DEBUG_BACKGROUND_CHECK) {
8562 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8565 case AppOpsManager.MODE_ALLOWED:
8566 return ActivityManager.APP_START_MODE_NORMAL;
8567 case AppOpsManager.MODE_IGNORED:
8568 return ActivityManager.APP_START_MODE_DELAYED;
8570 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8574 // Service launch is available to apps with run-in-background exemptions but
8575 // some other background operations are not. If we're doing a check
8576 // of service-launch policy, allow those callers to proceed unrestricted.
8577 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8579 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8580 if (DEBUG_BACKGROUND_CHECK) {
8581 Slog.i(TAG, "App " + uid + "/" + packageName
8582 + " is persistent; not restricted in background");
8584 return ActivityManager.APP_START_MODE_NORMAL;
8587 // Non-persistent but background whitelisted?
8588 if (uidOnBackgroundWhitelist(uid)) {
8589 if (DEBUG_BACKGROUND_CHECK) {
8590 Slog.i(TAG, "App " + uid + "/" + packageName
8591 + " on background whitelist; not restricted in background");
8593 return ActivityManager.APP_START_MODE_NORMAL;
8596 // Is this app on the battery whitelist?
8597 if (isOnDeviceIdleWhitelistLocked(uid)) {
8598 if (DEBUG_BACKGROUND_CHECK) {
8599 Slog.i(TAG, "App " + uid + "/" + packageName
8600 + " on idle whitelist; not restricted in background");
8602 return ActivityManager.APP_START_MODE_NORMAL;
8605 // None of the service-policy criteria apply, so we apply the common criteria
8606 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8609 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8610 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8611 UidRecord uidRec = mActiveUids.get(uid);
8612 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8613 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8614 + (uidRec != null ? uidRec.idle : false));
8615 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8617 if (uidRec == null) {
8618 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8619 UserHandle.getUserId(uid), packageName);
8621 ephemeral = uidRec.ephemeral;
8625 // We are hard-core about ephemeral apps not running in the background.
8626 return ActivityManager.APP_START_MODE_DISABLED;
8629 // The caller is only interested in whether app starts are completely
8630 // disabled for the given package (that is, it is an instant app). So
8631 // we don't need to go further, which is all just seeing if we should
8632 // apply a "delayed" mode for a regular app.
8633 return ActivityManager.APP_START_MODE_NORMAL;
8635 final int startMode = (alwaysRestrict)
8636 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8637 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8639 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8640 + " pkg=" + packageName + " startMode=" + startMode
8641 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8642 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8643 // This is an old app that has been forced into a "compatible as possible"
8644 // mode of background check. To increase compatibility, we will allow other
8645 // foreground apps to cause its services to start.
8646 if (callingPid >= 0) {
8648 synchronized (mPidsSelfLocked) {
8649 proc = mPidsSelfLocked.get(callingPid);
8652 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8653 // Whoever is instigating this is in the foreground, so we will allow it
8655 return ActivityManager.APP_START_MODE_NORMAL;
8662 return ActivityManager.APP_START_MODE_NORMAL;
8665 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8666 final int appId = UserHandle.getAppId(uid);
8667 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8668 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8669 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8672 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8673 ProviderInfo pi = null;
8674 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8679 pi = AppGlobals.getPackageManager().resolveContentProvider(
8680 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8682 } catch (RemoteException ex) {
8688 void grantEphemeralAccessLocked(int userId, Intent intent,
8689 int targetAppId, int ephemeralAppId) {
8690 getPackageManagerInternalLocked().
8691 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8694 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8695 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8696 if (targetUris != null) {
8697 return targetUris.get(grantUri);
8702 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8703 String targetPkg, int targetUid, GrantUri grantUri) {
8704 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8705 if (targetUris == null) {
8706 targetUris = Maps.newArrayMap();
8707 mGrantedUriPermissions.put(targetUid, targetUris);
8710 UriPermission perm = targetUris.get(grantUri);
8712 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8713 targetUris.put(grantUri, perm);
8719 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8720 final int modeFlags) {
8721 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8722 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8723 : UriPermission.STRENGTH_OWNED;
8725 // Root gets to do everything.
8730 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8731 if (perms == null) return false;
8733 // First look for exact match
8734 final UriPermission exactPerm = perms.get(grantUri);
8735 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8739 // No exact match, look for prefixes
8740 final int N = perms.size();
8741 for (int i = 0; i < N; i++) {
8742 final UriPermission perm = perms.valueAt(i);
8743 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8744 && perm.getStrength(modeFlags) >= minStrength) {
8753 * @param uri This uri must NOT contain an embedded userId.
8754 * @param userId The userId in which the uri is to be resolved.
8757 public int checkUriPermission(Uri uri, int pid, int uid,
8758 final int modeFlags, int userId, IBinder callerToken) {
8759 enforceNotIsolatedCaller("checkUriPermission");
8761 // Another redirected-binder-call permissions check as in
8762 // {@link checkPermissionWithToken}.
8763 Identity tlsIdentity = sCallerIdentity.get();
8764 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8765 uid = tlsIdentity.uid;
8766 pid = tlsIdentity.pid;
8769 // Our own process gets to do everything.
8770 if (pid == MY_PID) {
8771 return PackageManager.PERMISSION_GRANTED;
8773 synchronized (this) {
8774 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8775 ? PackageManager.PERMISSION_GRANTED
8776 : PackageManager.PERMISSION_DENIED;
8781 * Check if the targetPkg can be granted permission to access uri by
8782 * the callingUid using the given modeFlags. Throws a security exception
8783 * if callingUid is not allowed to do this. Returns the uid of the target
8784 * if the URI permission grant should be performed; returns -1 if it is not
8785 * needed (for example targetPkg already has permission to access the URI).
8786 * If you already know the uid of the target, you can supply it in
8787 * lastTargetUid else set that to -1.
8789 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8790 final int modeFlags, int lastTargetUid) {
8791 if (!Intent.isAccessUriMode(modeFlags)) {
8795 if (targetPkg != null) {
8796 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8797 "Checking grant " + targetPkg + " permission to " + grantUri);
8800 final IPackageManager pm = AppGlobals.getPackageManager();
8802 // If this is not a content: uri, we can't do anything with it.
8803 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8804 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8805 "Can't grant URI permission for non-content URI: " + grantUri);
8809 // Bail early if system is trying to hand out permissions directly; it
8810 // must always grant permissions on behalf of someone explicit.
8811 final int callingAppId = UserHandle.getAppId(callingUid);
8812 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8813 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8814 // Exempted authority for cropping user photos in Settings app
8816 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8817 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8822 final String authority = grantUri.uri.getAuthority();
8823 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8824 MATCH_DEBUG_TRIAGED_MISSING);
8826 Slog.w(TAG, "No content provider found for permission check: " +
8827 grantUri.uri.toSafeString());
8831 int targetUid = lastTargetUid;
8832 if (targetUid < 0 && targetPkg != null) {
8834 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8835 UserHandle.getUserId(callingUid));
8836 if (targetUid < 0) {
8837 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8838 "Can't grant URI permission no uid for: " + targetPkg);
8841 } catch (RemoteException ex) {
8846 // If we're extending a persistable grant, then we always need to create
8847 // the grant data structure so that take/release APIs work
8848 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8852 if (targetUid >= 0) {
8853 // First... does the target actually need this permission?
8854 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8855 // No need to grant the target this permission.
8856 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8857 "Target " + targetPkg + " already has full permission to " + grantUri);
8861 // First... there is no target package, so can anyone access it?
8862 boolean allowed = pi.exported;
8863 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8864 if (pi.readPermission != null) {
8868 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8869 if (pi.writePermission != null) {
8878 /* There is a special cross user grant if:
8879 * - The target is on another user.
8880 * - Apps on the current user can access the uri without any uid permissions.
8881 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8882 * grant uri permissions.
8884 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8885 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8886 modeFlags, false /*without considering the uid permissions*/);
8888 // Second... is the provider allowing granting of URI permissions?
8889 if (!specialCrossUserGrant) {
8890 if (!pi.grantUriPermissions) {
8891 throw new SecurityException("Provider " + pi.packageName
8893 + " does not allow granting of Uri permissions (uri "
8896 if (pi.uriPermissionPatterns != null) {
8897 final int N = pi.uriPermissionPatterns.length;
8898 boolean allowed = false;
8899 for (int i=0; i<N; i++) {
8900 if (pi.uriPermissionPatterns[i] != null
8901 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8907 throw new SecurityException("Provider " + pi.packageName
8909 + " does not allow granting of permission to path of Uri "
8915 // Third... does the caller itself have permission to access
8917 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8918 // Require they hold a strong enough Uri permission
8919 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8920 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8921 throw new SecurityException(
8922 "UID " + callingUid + " does not have permission to " + grantUri
8923 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8924 + "or related APIs");
8926 throw new SecurityException(
8927 "UID " + callingUid + " does not have permission to " + grantUri);
8935 * @param uri This uri must NOT contain an embedded userId.
8936 * @param userId The userId in which the uri is to be resolved.
8939 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8940 final int modeFlags, int userId) {
8941 enforceNotIsolatedCaller("checkGrantUriPermission");
8942 synchronized(this) {
8943 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8944 new GrantUri(userId, uri, false), modeFlags, -1);
8948 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8949 final int modeFlags, UriPermissionOwner owner) {
8950 if (!Intent.isAccessUriMode(modeFlags)) {
8954 // So here we are: the caller has the assumed permission
8955 // to the uri, and the target doesn't. Let's now give this to
8958 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8959 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8961 final String authority = grantUri.uri.getAuthority();
8962 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8963 MATCH_DEBUG_TRIAGED_MISSING);
8965 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8969 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8970 grantUri.prefix = true;
8972 final UriPermission perm = findOrCreateUriPermissionLocked(
8973 pi.packageName, targetPkg, targetUid, grantUri);
8974 perm.grantModes(modeFlags, owner);
8977 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8978 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8979 if (targetPkg == null) {
8980 throw new NullPointerException("targetPkg");
8983 final IPackageManager pm = AppGlobals.getPackageManager();
8985 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8986 } catch (RemoteException ex) {
8990 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8992 if (targetUid < 0) {
8996 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9000 static class NeededUriGrants extends ArrayList<GrantUri> {
9001 final String targetPkg;
9002 final int targetUid;
9005 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9006 this.targetPkg = targetPkg;
9007 this.targetUid = targetUid;
9013 * Like checkGrantUriPermissionLocked, but takes an Intent.
9015 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9016 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9017 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9018 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9019 + " clip=" + (intent != null ? intent.getClipData() : null)
9020 + " from " + intent + "; flags=0x"
9021 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9023 if (targetPkg == null) {
9024 throw new NullPointerException("targetPkg");
9027 if (intent == null) {
9030 Uri data = intent.getData();
9031 ClipData clip = intent.getClipData();
9032 if (data == null && clip == null) {
9035 // Default userId for uris in the intent (if they don't specify it themselves)
9036 int contentUserHint = intent.getContentUserHint();
9037 if (contentUserHint == UserHandle.USER_CURRENT) {
9038 contentUserHint = UserHandle.getUserId(callingUid);
9040 final IPackageManager pm = AppGlobals.getPackageManager();
9042 if (needed != null) {
9043 targetUid = needed.targetUid;
9046 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9048 } catch (RemoteException ex) {
9051 if (targetUid < 0) {
9052 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9053 "Can't grant URI permission no uid for: " + targetPkg
9054 + " on user " + targetUserId);
9059 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9060 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9062 if (targetUid > 0) {
9063 if (needed == null) {
9064 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9066 needed.add(grantUri);
9070 for (int i=0; i<clip.getItemCount(); i++) {
9071 Uri uri = clip.getItemAt(i).getUri();
9073 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9074 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9076 if (targetUid > 0) {
9077 if (needed == null) {
9078 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9080 needed.add(grantUri);
9083 Intent clipIntent = clip.getItemAt(i).getIntent();
9084 if (clipIntent != null) {
9085 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9086 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9087 if (newNeeded != null) {
9099 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9101 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9102 UriPermissionOwner owner) {
9103 if (needed != null) {
9104 for (int i=0; i<needed.size(); i++) {
9105 GrantUri grantUri = needed.get(i);
9106 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9107 grantUri, needed.flags, owner);
9112 void grantUriPermissionFromIntentLocked(int callingUid,
9113 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9114 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9115 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9116 if (needed == null) {
9120 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9124 * @param uri This uri must NOT contain an embedded userId.
9125 * @param userId The userId in which the uri is to be resolved.
9128 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9129 final int modeFlags, int userId) {
9130 enforceNotIsolatedCaller("grantUriPermission");
9131 GrantUri grantUri = new GrantUri(userId, uri, false);
9132 synchronized(this) {
9133 final ProcessRecord r = getRecordForAppLocked(caller);
9135 throw new SecurityException("Unable to find app for caller "
9137 + " when granting permission to uri " + grantUri);
9139 if (targetPkg == null) {
9140 throw new IllegalArgumentException("null target");
9142 if (grantUri == null) {
9143 throw new IllegalArgumentException("null uri");
9146 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9147 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9148 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9149 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9151 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9152 UserHandle.getUserId(r.uid));
9156 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9157 if (perm.modeFlags == 0) {
9158 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9160 if (perms != null) {
9161 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9162 "Removing " + perm.targetUid + " permission to " + perm.uri);
9164 perms.remove(perm.uri);
9165 if (perms.isEmpty()) {
9166 mGrantedUriPermissions.remove(perm.targetUid);
9172 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9173 final int modeFlags) {
9174 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9175 "Revoking all granted permissions to " + grantUri);
9177 final IPackageManager pm = AppGlobals.getPackageManager();
9178 final String authority = grantUri.uri.getAuthority();
9179 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9180 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9182 Slog.w(TAG, "No content provider found for permission revoke: "
9183 + grantUri.toSafeString());
9187 // Does the caller have this permission on the URI?
9188 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9189 // If they don't have direct access to the URI, then revoke any
9190 // ownerless URI permissions that have been granted to them.
9191 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9192 if (perms != null) {
9193 boolean persistChanged = false;
9194 for (int i = perms.size()-1; i >= 0; i--) {
9195 final UriPermission perm = perms.valueAt(i);
9196 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9199 if (perm.uri.sourceUserId == grantUri.sourceUserId
9200 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9201 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9202 "Revoking non-owned " + perm.targetUid
9203 + " permission to " + perm.uri);
9204 persistChanged |= perm.revokeModes(
9205 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9206 if (perm.modeFlags == 0) {
9211 if (perms.isEmpty()) {
9212 mGrantedUriPermissions.remove(callingUid);
9214 if (persistChanged) {
9215 schedulePersistUriGrants();
9221 boolean persistChanged = false;
9223 // Go through all of the permissions and remove any that match.
9224 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9225 final int targetUid = mGrantedUriPermissions.keyAt(i);
9226 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9228 for (int j = perms.size()-1; j >= 0; j--) {
9229 final UriPermission perm = perms.valueAt(j);
9230 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9233 if (perm.uri.sourceUserId == grantUri.sourceUserId
9234 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9235 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9236 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9237 persistChanged |= perm.revokeModes(
9238 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9239 targetPackage == null);
9240 if (perm.modeFlags == 0) {
9246 if (perms.isEmpty()) {
9247 mGrantedUriPermissions.removeAt(i);
9251 if (persistChanged) {
9252 schedulePersistUriGrants();
9257 * @param uri This uri must NOT contain an embedded userId.
9258 * @param userId The userId in which the uri is to be resolved.
9261 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9262 final int modeFlags, int userId) {
9263 enforceNotIsolatedCaller("revokeUriPermission");
9264 synchronized(this) {
9265 final ProcessRecord r = getRecordForAppLocked(caller);
9267 throw new SecurityException("Unable to find app for caller "
9269 + " when revoking permission to uri " + uri);
9272 Slog.w(TAG, "revokeUriPermission: null uri");
9276 if (!Intent.isAccessUriMode(modeFlags)) {
9280 final String authority = uri.getAuthority();
9281 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9282 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9284 Slog.w(TAG, "No content provider found for permission revoke: "
9285 + uri.toSafeString());
9289 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9295 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9298 * @param packageName Package name to match, or {@code null} to apply to all
9300 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9302 * @param persistable If persistable grants should be removed.
9304 private void removeUriPermissionsForPackageLocked(
9305 String packageName, int userHandle, boolean persistable) {
9306 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9307 throw new IllegalArgumentException("Must narrow by either package or user");
9310 boolean persistChanged = false;
9312 int N = mGrantedUriPermissions.size();
9313 for (int i = 0; i < N; i++) {
9314 final int targetUid = mGrantedUriPermissions.keyAt(i);
9315 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9317 // Only inspect grants matching user
9318 if (userHandle == UserHandle.USER_ALL
9319 || userHandle == UserHandle.getUserId(targetUid)) {
9320 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9321 final UriPermission perm = it.next();
9323 // Only inspect grants matching package
9324 if (packageName == null || perm.sourcePkg.equals(packageName)
9325 || perm.targetPkg.equals(packageName)) {
9326 // Hacky solution as part of fixing a security bug; ignore
9327 // grants associated with DownloadManager so we don't have
9328 // to immediately launch it to regrant the permissions
9329 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9330 && !persistable) continue;
9332 persistChanged |= perm.revokeModes(persistable
9333 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9335 // Only remove when no modes remain; any persisted grants
9336 // will keep this alive.
9337 if (perm.modeFlags == 0) {
9343 if (perms.isEmpty()) {
9344 mGrantedUriPermissions.remove(targetUid);
9351 if (persistChanged) {
9352 schedulePersistUriGrants();
9357 public IBinder newUriPermissionOwner(String name) {
9358 enforceNotIsolatedCaller("newUriPermissionOwner");
9359 synchronized(this) {
9360 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9361 return owner.getExternalTokenLocked();
9366 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9367 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9368 synchronized(this) {
9369 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9371 throw new IllegalArgumentException("Activity does not exist; token="
9374 return r.getUriPermissionsLocked().getExternalTokenLocked();
9378 * @param uri This uri must NOT contain an embedded userId.
9379 * @param sourceUserId The userId in which the uri is to be resolved.
9380 * @param targetUserId The userId of the app that receives the grant.
9383 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9384 final int modeFlags, int sourceUserId, int targetUserId) {
9385 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9386 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9387 "grantUriPermissionFromOwner", null);
9388 synchronized(this) {
9389 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9390 if (owner == null) {
9391 throw new IllegalArgumentException("Unknown owner: " + token);
9393 if (fromUid != Binder.getCallingUid()) {
9394 if (Binder.getCallingUid() != myUid()) {
9395 // Only system code can grant URI permissions on behalf
9397 throw new SecurityException("nice try");
9400 if (targetPkg == null) {
9401 throw new IllegalArgumentException("null target");
9404 throw new IllegalArgumentException("null uri");
9407 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9408 modeFlags, owner, targetUserId);
9413 * @param uri This uri must NOT contain an embedded userId.
9414 * @param userId The userId in which the uri is to be resolved.
9417 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9418 synchronized(this) {
9419 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9420 if (owner == null) {
9421 throw new IllegalArgumentException("Unknown owner: " + token);
9425 owner.removeUriPermissionsLocked(mode);
9427 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9428 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9433 private void schedulePersistUriGrants() {
9434 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9435 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9436 10 * DateUtils.SECOND_IN_MILLIS);
9440 private void writeGrantedUriPermissions() {
9441 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9443 // Snapshot permissions so we can persist without lock
9444 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9445 synchronized (this) {
9446 final int size = mGrantedUriPermissions.size();
9447 for (int i = 0; i < size; i++) {
9448 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9449 for (UriPermission perm : perms.values()) {
9450 if (perm.persistedModeFlags != 0) {
9451 persist.add(perm.snapshot());
9457 FileOutputStream fos = null;
9459 fos = mGrantFile.startWrite();
9461 XmlSerializer out = new FastXmlSerializer();
9462 out.setOutput(fos, StandardCharsets.UTF_8.name());
9463 out.startDocument(null, true);
9464 out.startTag(null, TAG_URI_GRANTS);
9465 for (UriPermission.Snapshot perm : persist) {
9466 out.startTag(null, TAG_URI_GRANT);
9467 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9468 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9469 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9470 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9471 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9472 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9473 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9474 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9475 out.endTag(null, TAG_URI_GRANT);
9477 out.endTag(null, TAG_URI_GRANTS);
9480 mGrantFile.finishWrite(fos);
9481 } catch (IOException e) {
9483 mGrantFile.failWrite(fos);
9488 private void readGrantedUriPermissionsLocked() {
9489 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9491 final long now = System.currentTimeMillis();
9493 FileInputStream fis = null;
9495 fis = mGrantFile.openRead();
9496 final XmlPullParser in = Xml.newPullParser();
9497 in.setInput(fis, StandardCharsets.UTF_8.name());
9500 while ((type = in.next()) != END_DOCUMENT) {
9501 final String tag = in.getName();
9502 if (type == START_TAG) {
9503 if (TAG_URI_GRANT.equals(tag)) {
9504 final int sourceUserId;
9505 final int targetUserId;
9506 final int userHandle = readIntAttribute(in,
9507 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9508 if (userHandle != UserHandle.USER_NULL) {
9509 // For backwards compatibility.
9510 sourceUserId = userHandle;
9511 targetUserId = userHandle;
9513 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9514 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9516 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9517 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9518 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9519 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9520 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9521 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9523 // Sanity check that provider still belongs to source package
9524 // Both direct boot aware and unaware packages are fine as we
9525 // will do filtering at query time to avoid multiple parsing.
9526 final ProviderInfo pi = getProviderInfoLocked(
9527 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9528 | MATCH_DIRECT_BOOT_UNAWARE);
9529 if (pi != null && sourcePkg.equals(pi.packageName)) {
9532 targetUid = AppGlobals.getPackageManager().getPackageUid(
9533 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9534 } catch (RemoteException e) {
9536 if (targetUid != -1) {
9537 final UriPermission perm = findOrCreateUriPermissionLocked(
9538 sourcePkg, targetPkg, targetUid,
9539 new GrantUri(sourceUserId, uri, prefix));
9540 perm.initPersistedModes(modeFlags, createdTime);
9543 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9544 + " but instead found " + pi);
9549 } catch (FileNotFoundException e) {
9550 // Missing grants is okay
9551 } catch (IOException e) {
9552 Slog.wtf(TAG, "Failed reading Uri grants", e);
9553 } catch (XmlPullParserException e) {
9554 Slog.wtf(TAG, "Failed reading Uri grants", e);
9556 IoUtils.closeQuietly(fis);
9561 * @param uri This uri must NOT contain an embedded userId.
9562 * @param userId The userId in which the uri is to be resolved.
9565 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9566 enforceNotIsolatedCaller("takePersistableUriPermission");
9568 Preconditions.checkFlagsArgument(modeFlags,
9569 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9571 synchronized (this) {
9572 final int callingUid = Binder.getCallingUid();
9573 boolean persistChanged = false;
9574 GrantUri grantUri = new GrantUri(userId, uri, false);
9576 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9577 new GrantUri(userId, uri, false));
9578 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9579 new GrantUri(userId, uri, true));
9581 final boolean exactValid = (exactPerm != null)
9582 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9583 final boolean prefixValid = (prefixPerm != null)
9584 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9586 if (!(exactValid || prefixValid)) {
9587 throw new SecurityException("No persistable permission grants found for UID "
9588 + callingUid + " and Uri " + grantUri.toSafeString());
9592 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9595 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9598 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9600 if (persistChanged) {
9601 schedulePersistUriGrants();
9607 * @param uri This uri must NOT contain an embedded userId.
9608 * @param userId The userId in which the uri is to be resolved.
9611 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9612 enforceNotIsolatedCaller("releasePersistableUriPermission");
9614 Preconditions.checkFlagsArgument(modeFlags,
9615 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9617 synchronized (this) {
9618 final int callingUid = Binder.getCallingUid();
9619 boolean persistChanged = false;
9621 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9622 new GrantUri(userId, uri, false));
9623 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9624 new GrantUri(userId, uri, true));
9625 if (exactPerm == null && prefixPerm == null) {
9626 throw new SecurityException("No permission grants found for UID " + callingUid
9627 + " and Uri " + uri.toSafeString());
9630 if (exactPerm != null) {
9631 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9632 removeUriPermissionIfNeededLocked(exactPerm);
9634 if (prefixPerm != null) {
9635 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9636 removeUriPermissionIfNeededLocked(prefixPerm);
9639 if (persistChanged) {
9640 schedulePersistUriGrants();
9646 * Prune any older {@link UriPermission} for the given UID until outstanding
9647 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9649 * @return if any mutations occured that require persisting.
9651 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9652 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9653 if (perms == null) return false;
9654 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9656 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9657 for (UriPermission perm : perms.values()) {
9658 if (perm.persistedModeFlags != 0) {
9659 persisted.add(perm);
9663 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9664 if (trimCount <= 0) return false;
9666 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9667 for (int i = 0; i < trimCount; i++) {
9668 final UriPermission perm = persisted.get(i);
9670 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9671 "Trimming grant created at " + perm.persistedCreateTime);
9673 perm.releasePersistableModes(~0);
9674 removeUriPermissionIfNeededLocked(perm);
9681 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9682 String packageName, boolean incoming) {
9683 enforceNotIsolatedCaller("getPersistedUriPermissions");
9684 Preconditions.checkNotNull(packageName, "packageName");
9686 final int callingUid = Binder.getCallingUid();
9687 final int callingUserId = UserHandle.getUserId(callingUid);
9688 final IPackageManager pm = AppGlobals.getPackageManager();
9690 final int packageUid = pm.getPackageUid(packageName,
9691 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9692 if (packageUid != callingUid) {
9693 throw new SecurityException(
9694 "Package " + packageName + " does not belong to calling UID " + callingUid);
9696 } catch (RemoteException e) {
9697 throw new SecurityException("Failed to verify package name ownership");
9700 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9701 synchronized (this) {
9703 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9705 if (perms == null) {
9706 Slog.w(TAG, "No permission grants found for " + packageName);
9708 for (UriPermission perm : perms.values()) {
9709 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9710 result.add(perm.buildPersistedPublicApiObject());
9715 final int size = mGrantedUriPermissions.size();
9716 for (int i = 0; i < size; i++) {
9717 final ArrayMap<GrantUri, UriPermission> perms =
9718 mGrantedUriPermissions.valueAt(i);
9719 for (UriPermission perm : perms.values()) {
9720 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9721 result.add(perm.buildPersistedPublicApiObject());
9727 return new ParceledListSlice<android.content.UriPermission>(result);
9731 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9732 String packageName, int userId) {
9733 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9734 "getGrantedUriPermissions");
9736 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9737 synchronized (this) {
9738 final int size = mGrantedUriPermissions.size();
9739 for (int i = 0; i < size; i++) {
9740 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9741 for (UriPermission perm : perms.values()) {
9742 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9743 && perm.persistedModeFlags != 0) {
9744 result.add(perm.buildPersistedPublicApiObject());
9749 return new ParceledListSlice<android.content.UriPermission>(result);
9753 public void clearGrantedUriPermissions(String packageName, int userId) {
9754 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9755 "clearGrantedUriPermissions");
9756 removeUriPermissionsForPackageLocked(packageName, userId, true);
9760 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9761 synchronized (this) {
9763 who != null ? getRecordForAppLocked(who) : null;
9764 if (app == null) return;
9766 Message msg = Message.obtain();
9767 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9769 msg.arg1 = waiting ? 1 : 0;
9770 mUiHandler.sendMessage(msg);
9775 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9776 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9777 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9778 outInfo.availMem = getFreeMemory();
9779 outInfo.totalMem = getTotalMemory();
9780 outInfo.threshold = homeAppMem;
9781 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9782 outInfo.hiddenAppThreshold = cachedAppMem;
9783 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9784 ProcessList.SERVICE_ADJ);
9785 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9786 ProcessList.VISIBLE_APP_ADJ);
9787 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9788 ProcessList.FOREGROUND_APP_ADJ);
9791 // =========================================================
9793 // =========================================================
9796 public List<IBinder> getAppTasks(String callingPackage) {
9797 int callingUid = Binder.getCallingUid();
9798 long ident = Binder.clearCallingIdentity();
9800 synchronized(this) {
9801 ArrayList<IBinder> list = new ArrayList<IBinder>();
9803 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9805 final int N = mRecentTasks.size();
9806 for (int i = 0; i < N; i++) {
9807 TaskRecord tr = mRecentTasks.get(i);
9808 // Skip tasks that do not match the caller. We don't need to verify
9809 // callingPackage, because we are also limiting to callingUid and know
9810 // that will limit to the correct security sandbox.
9811 if (tr.effectiveUid != callingUid) {
9814 Intent intent = tr.getBaseIntent();
9815 if (intent == null ||
9816 !callingPackage.equals(intent.getComponent().getPackageName())) {
9819 ActivityManager.RecentTaskInfo taskInfo =
9820 createRecentTaskInfoFromTaskRecord(tr);
9821 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9822 list.add(taskImpl.asBinder());
9825 Binder.restoreCallingIdentity(ident);
9832 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9833 final int callingUid = Binder.getCallingUid();
9834 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9836 synchronized(this) {
9837 if (DEBUG_ALL) Slog.v(
9838 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9840 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9843 // TODO: Improve with MRU list from all ActivityStacks.
9844 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9851 * Creates a new RecentTaskInfo from a TaskRecord.
9853 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9854 // Update the task description to reflect any changes in the task stack
9855 tr.updateTaskDescription();
9857 // Compose the recent task info
9858 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9859 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9860 rti.persistentId = tr.taskId;
9861 rti.baseIntent = new Intent(tr.getBaseIntent());
9862 rti.origActivity = tr.origActivity;
9863 rti.realActivity = tr.realActivity;
9864 rti.description = tr.lastDescription;
9865 rti.stackId = tr.getStackId();
9866 rti.userId = tr.userId;
9867 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9868 rti.firstActiveTime = tr.firstActiveTime;
9869 rti.lastActiveTime = tr.lastActiveTime;
9870 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9871 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9872 rti.numActivities = 0;
9873 if (tr.mBounds != null) {
9874 rti.bounds = new Rect(tr.mBounds);
9876 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9877 rti.resizeMode = tr.mResizeMode;
9879 ActivityRecord base = null;
9880 ActivityRecord top = null;
9883 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9884 tmp = tr.mActivities.get(i);
9885 if (tmp.finishing) {
9889 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9892 rti.numActivities++;
9895 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9896 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9901 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9902 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9903 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9905 if (checkPermission(android.Manifest.permission.GET_TASKS,
9906 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9907 // Temporary compatibility: some existing apps on the system image may
9908 // still be requesting the old permission and not switched to the new
9909 // one; if so, we'll still allow them full access. This means we need
9910 // to see if they are holding the old permission and are a system app.
9912 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9914 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9915 + " is using old GET_TASKS but privileged; allowing");
9917 } catch (RemoteException e) {
9922 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9923 + " does not hold REAL_GET_TASKS; limiting output");
9929 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9931 final int callingUid = Binder.getCallingUid();
9932 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9933 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9935 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9936 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9937 synchronized (this) {
9938 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9940 final boolean detailed = checkCallingPermission(
9941 android.Manifest.permission.GET_DETAILED_TASKS)
9942 == PackageManager.PERMISSION_GRANTED;
9944 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9945 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9946 return ParceledListSlice.emptyList();
9948 mRecentTasks.loadUserRecentsLocked(userId);
9950 final int recentsCount = mRecentTasks.size();
9951 ArrayList<ActivityManager.RecentTaskInfo> res =
9952 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9954 final Set<Integer> includedUsers;
9955 if (includeProfiles) {
9956 includedUsers = mUserController.getProfileIds(userId);
9958 includedUsers = new HashSet<>();
9960 includedUsers.add(Integer.valueOf(userId));
9962 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9963 TaskRecord tr = mRecentTasks.get(i);
9964 // Only add calling user or related users recent tasks
9965 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9966 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9970 if (tr.realActivitySuspended) {
9971 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9975 // Return the entry if desired by the caller. We always return
9976 // the first entry, because callers always expect this to be the
9977 // foreground app. We may filter others if the caller has
9978 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9979 // we should exclude the entry.
9983 || (tr.intent == null)
9984 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9987 // If the caller doesn't have the GET_TASKS permission, then only
9988 // allow them to see a small subset of tasks -- their own and home.
9989 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9990 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9994 final ActivityStack stack = tr.getStack();
9995 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9996 if (stack != null && stack.isHomeOrRecentsStack()) {
9997 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9998 "Skipping, home or recents stack task: " + tr);
10002 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10003 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10004 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10005 "Skipping, top task in docked stack: " + tr);
10009 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10010 if (stack != null && stack.isPinnedStack()) {
10011 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10012 "Skipping, pinned stack task: " + tr);
10016 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10017 // Don't include auto remove tasks that are finished or finishing.
10018 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10019 "Skipping, auto-remove without activity: " + tr);
10022 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10023 && !tr.isAvailable) {
10024 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10025 "Skipping, unavail real act: " + tr);
10029 if (!tr.mUserSetupComplete) {
10030 // Don't include task launched while user is not done setting-up.
10031 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10032 "Skipping, user setup not complete: " + tr);
10036 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10038 rti.baseIntent.replaceExtras((Bundle)null);
10045 return new ParceledListSlice<>(res);
10050 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10051 synchronized (this) {
10052 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10053 "getTaskThumbnail()");
10054 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10055 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10057 return tr.getTaskThumbnailLocked();
10064 public ActivityManager.TaskDescription getTaskDescription(int id) {
10065 synchronized (this) {
10066 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10067 "getTaskDescription()");
10068 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10069 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10071 return tr.lastTaskDescription;
10078 public int addAppTask(IBinder activityToken, Intent intent,
10079 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10080 final int callingUid = Binder.getCallingUid();
10081 final long callingIdent = Binder.clearCallingIdentity();
10084 synchronized (this) {
10085 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10087 throw new IllegalArgumentException("Activity does not exist; token="
10090 ComponentName comp = intent.getComponent();
10091 if (comp == null) {
10092 throw new IllegalArgumentException("Intent " + intent
10093 + " must specify explicit component");
10095 if (thumbnail.getWidth() != mThumbnailWidth
10096 || thumbnail.getHeight() != mThumbnailHeight) {
10097 throw new IllegalArgumentException("Bad thumbnail size: got "
10098 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10099 + mThumbnailWidth + "x" + mThumbnailHeight);
10101 if (intent.getSelector() != null) {
10102 intent.setSelector(null);
10104 if (intent.getSourceBounds() != null) {
10105 intent.setSourceBounds(null);
10107 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10108 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10109 // The caller has added this as an auto-remove task... that makes no
10110 // sense, so turn off auto-remove.
10111 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10114 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10115 mLastAddedTaskActivity = null;
10117 ActivityInfo ainfo = mLastAddedTaskActivity;
10118 if (ainfo == null) {
10119 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10120 comp, 0, UserHandle.getUserId(callingUid));
10121 if (ainfo.applicationInfo.uid != callingUid) {
10122 throw new SecurityException(
10123 "Can't add task for another application: target uid="
10124 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10128 TaskRecord task = new TaskRecord(this,
10129 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10130 ainfo, intent, description, new TaskThumbnailInfo());
10132 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10133 if (trimIdx >= 0) {
10134 // If this would have caused a trim, then we'll abort because that
10135 // means it would be added at the end of the list but then just removed.
10136 return INVALID_TASK_ID;
10139 final int N = mRecentTasks.size();
10140 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10141 final TaskRecord tr = mRecentTasks.remove(N - 1);
10142 tr.removedFromRecents();
10145 task.inRecents = true;
10146 mRecentTasks.add(task);
10147 r.getStack().addTask(task, false, "addAppTask");
10149 task.setLastThumbnailLocked(thumbnail);
10150 task.freeLastThumbnail();
10151 return task.taskId;
10154 Binder.restoreCallingIdentity(callingIdent);
10159 public Point getAppTaskThumbnailSize() {
10160 synchronized (this) {
10161 return new Point(mThumbnailWidth, mThumbnailHeight);
10166 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10167 synchronized (this) {
10168 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10170 r.setTaskDescription(td);
10171 final TaskRecord task = r.getTask();
10172 task.updateTaskDescription();
10173 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10179 public void setTaskResizeable(int taskId, int resizeableMode) {
10180 synchronized (this) {
10181 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10182 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10183 if (task == null) {
10184 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10187 task.setResizeMode(resizeableMode);
10192 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10193 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10194 long ident = Binder.clearCallingIdentity();
10196 synchronized (this) {
10197 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10198 if (task == null) {
10199 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10202 // Place the task in the right stack if it isn't there already based on
10203 // the requested bounds.
10204 // The stack transition logic is:
10205 // - a null bounds on a freeform task moves that task to fullscreen
10206 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10207 // that task to freeform
10208 // - otherwise the task is not moved
10209 int stackId = task.getStackId();
10210 if (!StackId.isTaskResizeAllowed(stackId)) {
10211 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10213 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10214 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10215 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10216 stackId = FREEFORM_WORKSPACE_STACK_ID;
10219 // Reparent the task to the right stack if necessary
10220 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10221 if (stackId != task.getStackId()) {
10222 // Defer resume until the task is resized below
10223 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10224 DEFER_RESUME, "resizeTask");
10225 preserveWindow = false;
10228 // After reparenting (which only resizes the task to the stack bounds), resize the
10229 // task to the actual bounds provided
10230 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10233 Binder.restoreCallingIdentity(ident);
10238 public Rect getTaskBounds(int taskId) {
10239 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10240 long ident = Binder.clearCallingIdentity();
10241 Rect rect = new Rect();
10243 synchronized (this) {
10244 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10245 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10246 if (task == null) {
10247 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10250 if (task.getStack() != null) {
10251 // Return the bounds from window manager since it will be adjusted for various
10252 // things like the presense of a docked stack for tasks that aren't resizeable.
10253 task.getWindowContainerBounds(rect);
10255 // Task isn't in window manager yet since it isn't associated with a stack.
10256 // Return the persist value from activity manager
10257 if (task.mBounds != null) {
10258 rect.set(task.mBounds);
10259 } else if (task.mLastNonFullscreenBounds != null) {
10260 rect.set(task.mLastNonFullscreenBounds);
10265 Binder.restoreCallingIdentity(ident);
10271 public void cancelTaskWindowTransition(int taskId) {
10272 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10273 final long ident = Binder.clearCallingIdentity();
10275 synchronized (this) {
10276 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10277 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10278 if (task == null) {
10279 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10282 task.cancelWindowTransition();
10285 Binder.restoreCallingIdentity(ident);
10290 public void cancelTaskThumbnailTransition(int taskId) {
10291 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10292 final long ident = Binder.clearCallingIdentity();
10294 synchronized (this) {
10295 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10296 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10297 if (task == null) {
10298 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10301 task.cancelThumbnailTransition();
10304 Binder.restoreCallingIdentity(ident);
10309 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10310 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10311 final long ident = Binder.clearCallingIdentity();
10313 final TaskRecord task;
10314 synchronized (this) {
10315 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10316 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10317 if (task == null) {
10318 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10322 // Don't call this while holding the lock as this operation might hit the disk.
10323 return task.getSnapshot(reducedResolution);
10325 Binder.restoreCallingIdentity(ident);
10330 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10331 if (userId != UserHandle.getCallingUserId()) {
10332 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10333 "getTaskDescriptionIcon");
10335 final File passedIconFile = new File(filePath);
10336 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10337 passedIconFile.getName());
10338 if (!legitIconFile.getPath().equals(filePath)
10339 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10340 throw new IllegalArgumentException("Bad file path: " + filePath
10341 + " passed for userId " + userId);
10343 return mRecentTasks.getTaskDescriptionIcon(filePath);
10347 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10348 throws RemoteException {
10349 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10350 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10351 activityOptions.getCustomInPlaceResId() == 0) {
10352 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10353 "with valid animation");
10355 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10356 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10357 activityOptions.getCustomInPlaceResId());
10358 mWindowManager.executeAppTransition();
10361 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10362 // Remove all tasks with activities in the specified package from the list of recent tasks
10363 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10364 TaskRecord tr = mRecentTasks.get(i);
10365 if (tr.userId != userId) continue;
10367 ComponentName cn = tr.intent.getComponent();
10368 if (cn != null && cn.getPackageName().equals(packageName)) {
10369 // If the package name matches, remove the task.
10370 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10375 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10378 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10379 TaskRecord tr = mRecentTasks.get(i);
10380 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10384 ComponentName cn = tr.intent.getComponent();
10385 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10386 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10387 if (sameComponent) {
10388 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10394 public void removeStack(int stackId) {
10395 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10396 if (StackId.isHomeOrRecentsStack(stackId)) {
10397 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10400 synchronized (this) {
10401 final long ident = Binder.clearCallingIdentity();
10403 mStackSupervisor.removeStackLocked(stackId);
10405 Binder.restoreCallingIdentity(ident);
10411 public void moveStackToDisplay(int stackId, int displayId) {
10412 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10414 synchronized (this) {
10415 final long ident = Binder.clearCallingIdentity();
10417 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10418 + " to displayId=" + displayId);
10419 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10421 Binder.restoreCallingIdentity(ident);
10427 public boolean removeTask(int taskId) {
10428 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10429 synchronized (this) {
10430 final long ident = Binder.clearCallingIdentity();
10432 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10434 Binder.restoreCallingIdentity(ident);
10440 * TODO: Add mController hook
10443 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10444 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10446 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10447 synchronized(this) {
10448 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10452 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10453 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10455 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10456 Binder.getCallingUid(), -1, -1, "Task to front")) {
10457 ActivityOptions.abort(options);
10460 final long origId = Binder.clearCallingIdentity();
10462 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10463 if (task == null) {
10464 Slog.d(TAG, "Could not find task for id: "+ taskId);
10467 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10468 mStackSupervisor.showLockTaskToast();
10469 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10472 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10473 if (prev != null) {
10474 task.setTaskToReturnTo(prev);
10476 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10477 false /* forceNonResizable */);
10479 final ActivityRecord topActivity = task.getTopActivity();
10480 if (topActivity != null) {
10482 // We are reshowing a task, use a starting window to hide the initial draw delay
10483 // so the transition can start earlier.
10484 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10485 true /* taskSwitch */, fromRecents);
10488 Binder.restoreCallingIdentity(origId);
10490 ActivityOptions.abort(options);
10494 * Attempts to move a task backwards in z-order (the order of activities within the task is
10497 * There are several possible results of this call:
10498 * - if the task is locked, then we will show the lock toast
10499 * - if there is a task behind the provided task, then that task is made visible and resumed as
10500 * this task is moved to the back
10501 * - otherwise, if there are no other tasks in the stack:
10502 * - if this task is in the pinned stack, then we remove the stack completely, which will
10503 * have the effect of moving the task to the top or bottom of the fullscreen stack
10504 * (depending on whether it is visible)
10505 * - otherwise, we simply return home and hide this task
10507 * @param token A reference to the activity we wish to move
10508 * @param nonRoot If false then this only works if the activity is the root
10509 * of a task; if true it will work for any activity in a task.
10510 * @return Returns true if the move completed, false if not.
10513 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10514 enforceNotIsolatedCaller("moveActivityTaskToBack");
10515 synchronized(this) {
10516 final long origId = Binder.clearCallingIdentity();
10518 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10519 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10520 if (task != null) {
10521 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10524 Binder.restoreCallingIdentity(origId);
10531 public void moveTaskBackwards(int task) {
10532 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10533 "moveTaskBackwards()");
10535 synchronized(this) {
10536 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10537 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10540 final long origId = Binder.clearCallingIdentity();
10541 moveTaskBackwardsLocked(task);
10542 Binder.restoreCallingIdentity(origId);
10546 private final void moveTaskBackwardsLocked(int task) {
10547 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10551 public int createStackOnDisplay(int displayId) throws RemoteException {
10552 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10553 synchronized (this) {
10554 final int stackId = mStackSupervisor.getNextStackId();
10555 final ActivityStack stack =
10556 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10557 if (stack == null) {
10558 return INVALID_STACK_ID;
10560 return stack.mStackId;
10565 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10566 synchronized (this) {
10567 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10568 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10569 return stack.mDisplayId;
10571 return DEFAULT_DISPLAY;
10576 public int getActivityStackId(IBinder token) throws RemoteException {
10577 synchronized (this) {
10578 ActivityStack stack = ActivityRecord.getStackLocked(token);
10579 if (stack == null) {
10580 return INVALID_STACK_ID;
10582 return stack.mStackId;
10587 public void exitFreeformMode(IBinder token) throws RemoteException {
10588 synchronized (this) {
10589 long ident = Binder.clearCallingIdentity();
10591 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10593 throw new IllegalArgumentException(
10594 "exitFreeformMode: No activity record matching token=" + token);
10597 final ActivityStack stack = r.getStack();
10598 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10599 throw new IllegalStateException(
10600 "exitFreeformMode: You can only go fullscreen from freeform.");
10603 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10604 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10605 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10607 Binder.restoreCallingIdentity(ident);
10613 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10614 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10615 if (StackId.isHomeOrRecentsStack(stackId)) {
10616 throw new IllegalArgumentException(
10617 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10619 synchronized (this) {
10620 long ident = Binder.clearCallingIdentity();
10622 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10623 if (task == null) {
10624 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10628 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10629 + " to stackId=" + stackId + " toTop=" + toTop);
10630 if (stackId == DOCKED_STACK_ID) {
10631 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10632 null /* initialBounds */);
10634 task.reparent(stackId, toTop,
10635 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10637 Binder.restoreCallingIdentity(ident);
10643 public void swapDockedAndFullscreenStack() throws RemoteException {
10644 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10645 synchronized (this) {
10646 long ident = Binder.clearCallingIdentity();
10648 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10649 FULLSCREEN_WORKSPACE_STACK_ID);
10650 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10652 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10653 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10655 if (topTask == null || tasks == null || tasks.size() == 0) {
10657 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10661 // TODO: App transition
10662 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10664 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10665 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10666 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10667 final int size = tasks.size();
10668 for (int i = 0; i < size; i++) {
10669 final int id = tasks.get(i).taskId;
10670 if (id == topTask.taskId) {
10674 // Defer the resume until after all the tasks have been moved
10675 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10676 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10677 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10680 // Because we deferred the resume to avoid conflicts with stack switches while
10681 // resuming, we need to do it after all the tasks are moved.
10682 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10683 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10685 mWindowManager.executeAppTransition();
10687 Binder.restoreCallingIdentity(ident);
10693 * Moves the input task to the docked stack.
10695 * @param taskId Id of task to move.
10696 * @param createMode The mode the docked stack should be created in if it doesn't exist
10698 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10700 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10701 * @param toTop If the task and stack should be moved to the top.
10702 * @param animate Whether we should play an animation for the moving the task
10703 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10704 * docked stack. Pass {@code null} to use default bounds.
10707 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10708 Rect initialBounds) {
10709 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10710 synchronized (this) {
10711 long ident = Binder.clearCallingIdentity();
10713 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10714 if (task == null) {
10715 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10719 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10720 + " to createMode=" + createMode + " toTop=" + toTop);
10721 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10723 // Defer resuming until we move the home stack to the front below
10724 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10725 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10726 "moveTaskToDockedStack");
10728 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10732 Binder.restoreCallingIdentity(ident);
10738 * Moves the top activity in the input stackId to the pinned stack.
10740 * @param stackId Id of stack to move the top activity to pinned stack.
10741 * @param bounds Bounds to use for pinned stack.
10743 * @return True if the top activity of the input stack was successfully moved to the pinned
10747 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10748 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10749 synchronized (this) {
10750 if (!mSupportsPictureInPicture) {
10751 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10752 + "Device doesn't support picture-in-picture mode");
10755 long ident = Binder.clearCallingIdentity();
10757 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10759 Binder.restoreCallingIdentity(ident);
10765 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10766 boolean preserveWindows, boolean animate, int animationDuration) {
10767 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10768 long ident = Binder.clearCallingIdentity();
10770 synchronized (this) {
10772 if (stackId == PINNED_STACK_ID) {
10773 final PinnedActivityStack pinnedStack =
10774 mStackSupervisor.getStack(PINNED_STACK_ID);
10775 if (pinnedStack != null) {
10776 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10777 destBounds, animationDuration, false /* fromFullscreen */);
10780 throw new IllegalArgumentException("Stack: " + stackId
10781 + " doesn't support animated resize.");
10784 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10785 null /* tempTaskInsetBounds */, preserveWindows,
10786 allowResizeInDockedMode, !DEFER_RESUME);
10790 Binder.restoreCallingIdentity(ident);
10795 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10796 Rect tempDockedTaskInsetBounds,
10797 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10798 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10799 "resizeDockedStack()");
10800 long ident = Binder.clearCallingIdentity();
10802 synchronized (this) {
10803 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10804 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10808 Binder.restoreCallingIdentity(ident);
10813 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10814 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10815 "resizePinnedStack()");
10816 final long ident = Binder.clearCallingIdentity();
10818 synchronized (this) {
10819 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10822 Binder.restoreCallingIdentity(ident);
10827 * Try to place task to provided position. The final position might be different depending on
10828 * current user and stacks state. The task will be moved to target stack if it's currently in
10832 public void positionTaskInStack(int taskId, int stackId, int position) {
10833 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10834 if (StackId.isHomeOrRecentsStack(stackId)) {
10835 throw new IllegalArgumentException(
10836 "positionTaskInStack: Attempt to change the position of task "
10837 + taskId + " in/to home/recents stack");
10839 synchronized (this) {
10840 long ident = Binder.clearCallingIdentity();
10842 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10843 + taskId + " in stackId=" + stackId + " at position=" + position);
10844 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10845 if (task == null) {
10846 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10850 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10853 // TODO: Have the callers of this API call a separate reparent method if that is
10854 // what they intended to do vs. having this method also do reparenting.
10855 if (task.getStack() == stack) {
10856 // Change position in current stack.
10857 stack.positionChildAt(task, position);
10859 // Reparent to new stack.
10860 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10861 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10864 Binder.restoreCallingIdentity(ident);
10870 public List<StackInfo> getAllStackInfos() {
10871 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10872 long ident = Binder.clearCallingIdentity();
10874 synchronized (this) {
10875 return mStackSupervisor.getAllStackInfosLocked();
10878 Binder.restoreCallingIdentity(ident);
10883 public StackInfo getStackInfo(int stackId) {
10884 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10885 long ident = Binder.clearCallingIdentity();
10887 synchronized (this) {
10888 return mStackSupervisor.getStackInfoLocked(stackId);
10891 Binder.restoreCallingIdentity(ident);
10896 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10897 synchronized(this) {
10898 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10903 public void updateDeviceOwner(String packageName) {
10904 final int callingUid = Binder.getCallingUid();
10905 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10906 throw new SecurityException("updateDeviceOwner called from non-system process");
10908 synchronized (this) {
10909 mDeviceOwnerName = packageName;
10914 public void updateLockTaskPackages(int userId, String[] packages) {
10915 final int callingUid = Binder.getCallingUid();
10916 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10917 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10918 "updateLockTaskPackages()");
10920 synchronized (this) {
10921 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10922 Arrays.toString(packages));
10923 mLockTaskPackages.put(userId, packages);
10924 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10929 void startLockTaskModeLocked(TaskRecord task) {
10930 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10931 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10935 // When a task is locked, dismiss the pinned stack if it exists
10936 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10938 if (pinnedStack != null) {
10939 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10942 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10943 // is initiated by system after the pinning request was shown and locked mode is initiated
10944 // by an authorized app directly
10945 final int callingUid = Binder.getCallingUid();
10946 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10947 long ident = Binder.clearCallingIdentity();
10949 if (!isSystemInitiated) {
10950 task.mLockTaskUid = callingUid;
10951 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10952 // startLockTask() called by app and task mode is lockTaskModeDefault.
10953 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10954 StatusBarManagerInternal statusBarManager =
10955 LocalServices.getService(StatusBarManagerInternal.class);
10956 if (statusBarManager != null) {
10957 statusBarManager.showScreenPinningRequest(task.taskId);
10962 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10963 if (stack == null || task != stack.topTask()) {
10964 throw new IllegalArgumentException("Invalid task, not in foreground");
10967 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10969 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10970 ActivityManager.LOCK_TASK_MODE_PINNED :
10971 ActivityManager.LOCK_TASK_MODE_LOCKED,
10972 "startLockTask", true);
10974 Binder.restoreCallingIdentity(ident);
10979 public void startLockTaskModeById(int taskId) {
10980 synchronized (this) {
10981 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10982 if (task != null) {
10983 startLockTaskModeLocked(task);
10989 public void startLockTaskModeByToken(IBinder token) {
10990 synchronized (this) {
10991 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10995 final TaskRecord task = r.getTask();
10996 if (task != null) {
10997 startLockTaskModeLocked(task);
11003 public void startSystemLockTaskMode(int taskId) throws RemoteException {
11004 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11005 // This makes inner call to look as if it was initiated by system.
11006 long ident = Binder.clearCallingIdentity();
11008 synchronized (this) {
11009 startLockTaskModeById(taskId);
11012 Binder.restoreCallingIdentity(ident);
11017 public void stopLockTaskMode() {
11018 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11019 if (lockTask == null) {
11020 // Our work here is done.
11024 final int callingUid = Binder.getCallingUid();
11025 final int lockTaskUid = lockTask.mLockTaskUid;
11026 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11027 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11031 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11032 // It is possible lockTaskMode was started by the system process because
11033 // android:lockTaskMode is set to a locking value in the application manifest
11034 // instead of the app calling startLockTaskMode. In this case
11035 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11036 // {@link TaskRecord.effectiveUid} instead. Also caller with
11037 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11038 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11039 && callingUid != lockTaskUid
11040 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11041 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11042 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11045 long ident = Binder.clearCallingIdentity();
11047 Log.d(TAG, "stopLockTaskMode");
11049 synchronized (this) {
11050 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11051 "stopLockTask", true);
11053 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11055 tm.showInCallScreen(false);
11058 Binder.restoreCallingIdentity(ident);
11063 * This API should be called by SystemUI only when user perform certain action to dismiss
11064 * lock task mode. We should only dismiss pinned lock task mode in this case.
11067 public void stopSystemLockTaskMode() throws RemoteException {
11068 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11069 stopLockTaskMode();
11071 mStackSupervisor.showLockTaskToast();
11076 public boolean isInLockTaskMode() {
11077 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11081 public int getLockTaskModeState() {
11082 synchronized (this) {
11083 return mStackSupervisor.getLockTaskModeState();
11088 public void showLockTaskEscapeMessage(IBinder token) {
11089 synchronized (this) {
11090 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11094 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11099 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11100 throws RemoteException {
11101 synchronized (this) {
11102 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11104 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11108 final long origId = Binder.clearCallingIdentity();
11110 r.setDisablePreviewScreenshots(disable);
11112 Binder.restoreCallingIdentity(origId);
11117 // =========================================================
11118 // CONTENT PROVIDERS
11119 // =========================================================
11121 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11122 List<ProviderInfo> providers = null;
11124 providers = AppGlobals.getPackageManager()
11125 .queryContentProviders(app.processName, app.uid,
11126 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11127 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11129 } catch (RemoteException ex) {
11131 if (DEBUG_MU) Slog.v(TAG_MU,
11132 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11133 int userId = app.userId;
11134 if (providers != null) {
11135 int N = providers.size();
11136 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11137 for (int i=0; i<N; i++) {
11138 // TODO: keep logic in sync with installEncryptionUnawareProviders
11140 (ProviderInfo)providers.get(i);
11141 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11142 cpi.name, cpi.flags);
11143 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11144 // This is a singleton provider, but a user besides the
11145 // default user is asking to initialize a process it runs
11146 // in... well, no, it doesn't actually run in this process,
11147 // it runs in the process of the default user. Get rid of it.
11148 providers.remove(i);
11154 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11155 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11157 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11158 mProviderMap.putProviderByClass(comp, cpr);
11160 if (DEBUG_MU) Slog.v(TAG_MU,
11161 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11162 app.pubProviders.put(cpi.name, cpr);
11163 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11164 // Don't add this if it is a platform component that is marked
11165 // to run in multiple processes, because this is actually
11166 // part of the framework so doesn't make sense to track as a
11167 // separate apk in the process.
11168 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11171 notifyPackageUse(cpi.applicationInfo.packageName,
11172 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11179 * Check if the calling UID has a possible chance at accessing the provider
11180 * at the given authority and user.
11182 public String checkContentProviderAccess(String authority, int userId) {
11183 if (userId == UserHandle.USER_ALL) {
11184 mContext.enforceCallingOrSelfPermission(
11185 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11186 userId = UserHandle.getCallingUserId();
11189 ProviderInfo cpi = null;
11191 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11192 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11193 | PackageManager.MATCH_DISABLED_COMPONENTS
11194 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11195 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11197 } catch (RemoteException ignored) {
11200 return "Failed to find provider " + authority + " for user " + userId
11201 + "; expected to find a valid ContentProvider for this authority";
11204 ProcessRecord r = null;
11205 synchronized (mPidsSelfLocked) {
11206 r = mPidsSelfLocked.get(Binder.getCallingPid());
11209 return "Failed to find PID " + Binder.getCallingPid();
11212 synchronized (this) {
11213 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11218 * Check if {@link ProcessRecord} has a possible chance at accessing the
11219 * given {@link ProviderInfo}. Final permission checking is always done
11220 * in {@link ContentProvider}.
11222 private final String checkContentProviderPermissionLocked(
11223 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11224 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11225 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11226 boolean checkedGrants = false;
11228 // Looking for cross-user grants before enforcing the typical cross-users permissions
11229 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11230 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11231 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11234 checkedGrants = true;
11236 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11237 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11238 if (userId != tmpTargetUserId) {
11239 // When we actually went to determine the final targer user ID, this ended
11240 // up different than our initial check for the authority. This is because
11241 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11242 // SELF. So we need to re-check the grants again.
11243 checkedGrants = false;
11246 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11247 cpi.applicationInfo.uid, cpi.exported)
11248 == PackageManager.PERMISSION_GRANTED) {
11251 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11252 cpi.applicationInfo.uid, cpi.exported)
11253 == PackageManager.PERMISSION_GRANTED) {
11257 PathPermission[] pps = cpi.pathPermissions;
11259 int i = pps.length;
11262 PathPermission pp = pps[i];
11263 String pprperm = pp.getReadPermission();
11264 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11265 cpi.applicationInfo.uid, cpi.exported)
11266 == PackageManager.PERMISSION_GRANTED) {
11269 String ppwperm = pp.getWritePermission();
11270 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11271 cpi.applicationInfo.uid, cpi.exported)
11272 == PackageManager.PERMISSION_GRANTED) {
11277 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11281 final String suffix;
11282 if (!cpi.exported) {
11283 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11284 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11285 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11287 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11289 final String msg = "Permission Denial: opening provider " + cpi.name
11290 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11291 + ", uid=" + callingUid + ")" + suffix;
11297 * Returns if the ContentProvider has granted a uri to callingUid
11299 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11300 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11301 if (perms != null) {
11302 for (int i=perms.size()-1; i>=0; i--) {
11303 GrantUri grantUri = perms.keyAt(i);
11304 if (grantUri.sourceUserId == userId || !checkUser) {
11305 if (matchesProvider(grantUri.uri, cpi)) {
11315 * Returns true if the uri authority is one of the authorities specified in the provider.
11317 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11318 String uriAuth = uri.getAuthority();
11319 String cpiAuth = cpi.authority;
11320 if (cpiAuth.indexOf(';') == -1) {
11321 return cpiAuth.equals(uriAuth);
11323 String[] cpiAuths = cpiAuth.split(";");
11324 int length = cpiAuths.length;
11325 for (int i = 0; i < length; i++) {
11326 if (cpiAuths[i].equals(uriAuth)) return true;
11331 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11332 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11334 for (int i=0; i<r.conProviders.size(); i++) {
11335 ContentProviderConnection conn = r.conProviders.get(i);
11336 if (conn.provider == cpr) {
11337 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11338 "Adding provider requested by "
11339 + r.processName + " from process "
11340 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11341 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11343 conn.stableCount++;
11344 conn.numStableIncs++;
11346 conn.unstableCount++;
11347 conn.numUnstableIncs++;
11352 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11354 conn.stableCount = 1;
11355 conn.numStableIncs = 1;
11357 conn.unstableCount = 1;
11358 conn.numUnstableIncs = 1;
11360 cpr.connections.add(conn);
11361 r.conProviders.add(conn);
11362 startAssociationLocked(r.uid, r.processName, r.curProcState,
11363 cpr.uid, cpr.name, cpr.info.processName);
11366 cpr.addExternalProcessHandleLocked(externalProcessToken);
11370 boolean decProviderCountLocked(ContentProviderConnection conn,
11371 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11372 if (conn != null) {
11373 cpr = conn.provider;
11374 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11375 "Removing provider requested by "
11376 + conn.client.processName + " from process "
11377 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11378 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11380 conn.stableCount--;
11382 conn.unstableCount--;
11384 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11385 cpr.connections.remove(conn);
11386 conn.client.conProviders.remove(conn);
11387 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11388 // The client is more important than last activity -- note the time this
11389 // is happening, so we keep the old provider process around a bit as last
11390 // activity to avoid thrashing it.
11391 if (cpr.proc != null) {
11392 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11395 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11400 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11404 private void checkTime(long startTime, String where) {
11405 long now = SystemClock.uptimeMillis();
11406 if ((now-startTime) > 50) {
11407 // If we are taking more than 50ms, log about it.
11408 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11412 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11414 PROC_SPACE_TERM|PROC_PARENS,
11415 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11418 private final long[] mProcessStateStatsLongs = new long[1];
11420 boolean isProcessAliveLocked(ProcessRecord proc) {
11421 if (proc.procStatFile == null) {
11422 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11424 mProcessStateStatsLongs[0] = 0;
11425 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11426 mProcessStateStatsLongs, null)) {
11427 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11430 final long state = mProcessStateStatsLongs[0];
11431 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11433 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11436 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11437 String name, IBinder token, boolean stable, int userId) {
11438 ContentProviderRecord cpr;
11439 ContentProviderConnection conn = null;
11440 ProviderInfo cpi = null;
11442 synchronized(this) {
11443 long startTime = SystemClock.uptimeMillis();
11445 ProcessRecord r = null;
11446 if (caller != null) {
11447 r = getRecordForAppLocked(caller);
11449 throw new SecurityException(
11450 "Unable to find app for caller " + caller
11451 + " (pid=" + Binder.getCallingPid()
11452 + ") when getting content provider " + name);
11456 boolean checkCrossUser = true;
11458 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11460 // First check if this content provider has been published...
11461 cpr = mProviderMap.getProviderByName(name, userId);
11462 // If that didn't work, check if it exists for user 0 and then
11463 // verify that it's a singleton provider before using it.
11464 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11465 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11468 if (isSingleton(cpi.processName, cpi.applicationInfo,
11469 cpi.name, cpi.flags)
11470 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11471 userId = UserHandle.USER_SYSTEM;
11472 checkCrossUser = false;
11480 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11481 if (providerRunning) {
11484 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11485 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11487 throw new SecurityException(msg);
11489 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11491 if (r != null && cpr.canRunHere(r)) {
11492 // This provider has been published or is in the process
11493 // of being published... but it is also allowed to run
11494 // in the caller's process, so don't make a connection
11495 // and just let the caller instantiate its own instance.
11496 ContentProviderHolder holder = cpr.newHolder(null);
11497 // don't give caller the provider object, it needs
11498 // to make its own.
11499 holder.provider = null;
11502 // Don't expose providers between normal apps and instant apps
11504 if (AppGlobals.getPackageManager()
11505 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11508 } catch (RemoteException e) {
11511 final long origId = Binder.clearCallingIdentity();
11513 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11515 // In this case the provider instance already exists, so we can
11516 // return it right away.
11517 conn = incProviderCountLocked(r, cpr, token, stable);
11518 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11519 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11520 // If this is a perceptible app accessing the provider,
11521 // make sure to count it as being accessed and thus
11522 // back up on the LRU list. This is good because
11523 // content providers are often expensive to start.
11524 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11525 updateLruProcessLocked(cpr.proc, false, null);
11526 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11530 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11531 final int verifiedAdj = cpr.proc.verifiedAdj;
11532 boolean success = updateOomAdjLocked(cpr.proc, true);
11533 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11534 // if the process has been successfully adjusted. So to reduce races with
11535 // it, we will check whether the process still exists. Note that this doesn't
11536 // completely get rid of races with LMK killing the process, but should make
11537 // them much smaller.
11538 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11541 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11542 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11543 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11544 // NOTE: there is still a race here where a signal could be
11545 // pending on the process even though we managed to update its
11546 // adj level. Not sure what to do about this, but at least
11547 // the race is now smaller.
11549 // Uh oh... it looks like the provider's process
11550 // has been killed on us. We need to wait for a new
11551 // process to be started, and make sure its death
11552 // doesn't kill our process.
11553 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11554 + " is crashing; detaching " + r);
11555 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11556 checkTime(startTime, "getContentProviderImpl: before appDied");
11557 appDiedLocked(cpr.proc);
11558 checkTime(startTime, "getContentProviderImpl: after appDied");
11560 // This wasn't the last ref our process had on
11561 // the provider... we have now been killed, bail.
11564 providerRunning = false;
11567 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11570 Binder.restoreCallingIdentity(origId);
11573 if (!providerRunning) {
11575 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11576 cpi = AppGlobals.getPackageManager().
11577 resolveContentProvider(name,
11578 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11579 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11580 } catch (RemoteException ex) {
11585 // If the provider is a singleton AND
11586 // (it's a call within the same user || the provider is a
11588 // Then allow connecting to the singleton provider
11589 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11590 cpi.name, cpi.flags)
11591 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11593 userId = UserHandle.USER_SYSTEM;
11595 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11596 checkTime(startTime, "getContentProviderImpl: got app info for user");
11599 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11600 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11602 throw new SecurityException(msg);
11604 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11606 if (!mProcessesReady
11607 && !cpi.processName.equals("system")) {
11608 // If this content provider does not run in the system
11609 // process, and the system is not yet ready to run other
11610 // processes, then fail fast instead of hanging.
11611 throw new IllegalArgumentException(
11612 "Attempt to launch content provider before system ready");
11615 // Make sure that the user who owns this provider is running. If not,
11616 // we don't want to allow it to run.
11617 if (!mUserController.isUserRunningLocked(userId, 0)) {
11618 Slog.w(TAG, "Unable to launch app "
11619 + cpi.applicationInfo.packageName + "/"
11620 + cpi.applicationInfo.uid + " for provider "
11621 + name + ": user " + userId + " is stopped");
11625 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11626 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11627 cpr = mProviderMap.getProviderByClass(comp, userId);
11628 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11629 final boolean firstClass = cpr == null;
11631 final long ident = Binder.clearCallingIdentity();
11633 // If permissions need a review before any of the app components can run,
11634 // we return no provider and launch a review activity if the calling app
11635 // is in the foreground.
11636 if (mPermissionReviewRequired) {
11637 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11643 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11644 ApplicationInfo ai =
11645 AppGlobals.getPackageManager().
11646 getApplicationInfo(
11647 cpi.applicationInfo.packageName,
11648 STOCK_PM_FLAGS, userId);
11649 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11651 Slog.w(TAG, "No package info for content provider "
11655 ai = getAppInfoForUser(ai, userId);
11656 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11657 } catch (RemoteException ex) {
11658 // pm is in same process, this will never happen.
11660 Binder.restoreCallingIdentity(ident);
11664 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11666 if (r != null && cpr.canRunHere(r)) {
11667 // If this is a multiprocess provider, then just return its
11668 // info and allow the caller to instantiate it. Only do
11669 // this if the provider is the same user as the caller's
11670 // process, or can run as root (so can be in any process).
11671 return cpr.newHolder(null);
11674 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11675 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11676 + cpr.info.name + " callers=" + Debug.getCallers(6));
11678 // This is single process, and our app is now connecting to it.
11679 // See if we are already in the process of launching this
11681 final int N = mLaunchingProviders.size();
11683 for (i = 0; i < N; i++) {
11684 if (mLaunchingProviders.get(i) == cpr) {
11689 // If the provider is not already being launched, then get it
11692 final long origId = Binder.clearCallingIdentity();
11695 // Content provider is now in use, its package can't be stopped.
11697 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11698 AppGlobals.getPackageManager().setPackageStoppedState(
11699 cpr.appInfo.packageName, false, userId);
11700 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11701 } catch (RemoteException e) {
11702 } catch (IllegalArgumentException e) {
11703 Slog.w(TAG, "Failed trying to unstop package "
11704 + cpr.appInfo.packageName + ": " + e);
11707 // Use existing process if already started
11708 checkTime(startTime, "getContentProviderImpl: looking for process record");
11709 ProcessRecord proc = getProcessRecordLocked(
11710 cpi.processName, cpr.appInfo.uid, false);
11711 if (proc != null && proc.thread != null && !proc.killed) {
11712 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11713 "Installing in existing process " + proc);
11714 if (!proc.pubProviders.containsKey(cpi.name)) {
11715 checkTime(startTime, "getContentProviderImpl: scheduling install");
11716 proc.pubProviders.put(cpi.name, cpr);
11718 proc.thread.scheduleInstallProvider(cpi);
11719 } catch (RemoteException e) {
11723 checkTime(startTime, "getContentProviderImpl: before start process");
11724 proc = startProcessLocked(cpi.processName,
11725 cpr.appInfo, false, 0, "content provider",
11726 new ComponentName(cpi.applicationInfo.packageName,
11727 cpi.name), false, false, false);
11728 checkTime(startTime, "getContentProviderImpl: after start process");
11729 if (proc == null) {
11730 Slog.w(TAG, "Unable to launch app "
11731 + cpi.applicationInfo.packageName + "/"
11732 + cpi.applicationInfo.uid + " for provider "
11733 + name + ": process is bad");
11737 cpr.launchingApp = proc;
11738 mLaunchingProviders.add(cpr);
11740 Binder.restoreCallingIdentity(origId);
11744 checkTime(startTime, "getContentProviderImpl: updating data structures");
11746 // Make sure the provider is published (the same provider class
11747 // may be published under multiple names).
11749 mProviderMap.putProviderByClass(comp, cpr);
11752 mProviderMap.putProviderByName(name, cpr);
11753 conn = incProviderCountLocked(r, cpr, token, stable);
11754 if (conn != null) {
11755 conn.waiting = true;
11758 checkTime(startTime, "getContentProviderImpl: done!");
11760 grantEphemeralAccessLocked(userId, null /*intent*/,
11761 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11764 // Wait for the provider to be published...
11765 synchronized (cpr) {
11766 while (cpr.provider == null) {
11767 if (cpr.launchingApp == null) {
11768 Slog.w(TAG, "Unable to launch app "
11769 + cpi.applicationInfo.packageName + "/"
11770 + cpi.applicationInfo.uid + " for provider "
11771 + name + ": launching app became null");
11772 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11773 UserHandle.getUserId(cpi.applicationInfo.uid),
11774 cpi.applicationInfo.packageName,
11775 cpi.applicationInfo.uid, name);
11779 if (DEBUG_MU) Slog.v(TAG_MU,
11780 "Waiting to start provider " + cpr
11781 + " launchingApp=" + cpr.launchingApp);
11782 if (conn != null) {
11783 conn.waiting = true;
11786 } catch (InterruptedException ex) {
11788 if (conn != null) {
11789 conn.waiting = false;
11794 return cpr != null ? cpr.newHolder(conn) : null;
11797 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11798 ProcessRecord r, final int userId) {
11799 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11800 cpi.packageName, userId)) {
11802 final boolean callerForeground = r == null || r.setSchedGroup
11803 != ProcessList.SCHED_GROUP_BACKGROUND;
11805 // Show a permission review UI only for starting from a foreground app
11806 if (!callerForeground) {
11807 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11808 + cpi.packageName + " requires a permissions review");
11812 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11813 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11814 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11815 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11817 if (DEBUG_PERMISSIONS_REVIEW) {
11818 Slog.i(TAG, "u" + userId + " Launching permission review "
11819 + "for package " + cpi.packageName);
11822 final UserHandle userHandle = new UserHandle(userId);
11823 mHandler.post(new Runnable() {
11825 public void run() {
11826 mContext.startActivityAsUser(intent, userHandle);
11836 PackageManagerInternal getPackageManagerInternalLocked() {
11837 if (mPackageManagerInt == null) {
11838 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11840 return mPackageManagerInt;
11844 public final ContentProviderHolder getContentProvider(
11845 IApplicationThread caller, String name, int userId, boolean stable) {
11846 enforceNotIsolatedCaller("getContentProvider");
11847 if (caller == null) {
11848 String msg = "null IApplicationThread when getting content provider "
11851 throw new SecurityException(msg);
11853 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11854 // with cross-user grant.
11855 return getContentProviderImpl(caller, name, null, stable, userId);
11858 public ContentProviderHolder getContentProviderExternal(
11859 String name, int userId, IBinder token) {
11860 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11861 "Do not have permission in call getContentProviderExternal()");
11862 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11863 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11864 return getContentProviderExternalUnchecked(name, token, userId);
11867 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11868 IBinder token, int userId) {
11869 return getContentProviderImpl(null, name, token, true, userId);
11873 * Drop a content provider from a ProcessRecord's bookkeeping
11875 public void removeContentProvider(IBinder connection, boolean stable) {
11876 enforceNotIsolatedCaller("removeContentProvider");
11877 long ident = Binder.clearCallingIdentity();
11879 synchronized (this) {
11880 ContentProviderConnection conn;
11882 conn = (ContentProviderConnection)connection;
11883 } catch (ClassCastException e) {
11884 String msg ="removeContentProvider: " + connection
11885 + " not a ContentProviderConnection";
11887 throw new IllegalArgumentException(msg);
11889 if (conn == null) {
11890 throw new NullPointerException("connection is null");
11892 if (decProviderCountLocked(conn, null, null, stable)) {
11893 updateOomAdjLocked();
11897 Binder.restoreCallingIdentity(ident);
11901 public void removeContentProviderExternal(String name, IBinder token) {
11902 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11903 "Do not have permission in call removeContentProviderExternal()");
11904 int userId = UserHandle.getCallingUserId();
11905 long ident = Binder.clearCallingIdentity();
11907 removeContentProviderExternalUnchecked(name, token, userId);
11909 Binder.restoreCallingIdentity(ident);
11913 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11914 synchronized (this) {
11915 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11917 //remove from mProvidersByClass
11918 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11922 //update content provider record entry info
11923 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11924 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11925 if (localCpr.hasExternalProcessHandles()) {
11926 if (localCpr.removeExternalProcessHandleLocked(token)) {
11927 updateOomAdjLocked();
11929 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11930 + " with no external reference for token: "
11934 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11935 + " with no external references.");
11940 public final void publishContentProviders(IApplicationThread caller,
11941 List<ContentProviderHolder> providers) {
11942 if (providers == null) {
11946 enforceNotIsolatedCaller("publishContentProviders");
11947 synchronized (this) {
11948 final ProcessRecord r = getRecordForAppLocked(caller);
11949 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11951 throw new SecurityException(
11952 "Unable to find app for caller " + caller
11953 + " (pid=" + Binder.getCallingPid()
11954 + ") when publishing content providers");
11957 final long origId = Binder.clearCallingIdentity();
11959 final int N = providers.size();
11960 for (int i = 0; i < N; i++) {
11961 ContentProviderHolder src = providers.get(i);
11962 if (src == null || src.info == null || src.provider == null) {
11965 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11966 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11968 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11969 mProviderMap.putProviderByClass(comp, dst);
11970 String names[] = dst.info.authority.split(";");
11971 for (int j = 0; j < names.length; j++) {
11972 mProviderMap.putProviderByName(names[j], dst);
11975 int launchingCount = mLaunchingProviders.size();
11977 boolean wasInLaunchingProviders = false;
11978 for (j = 0; j < launchingCount; j++) {
11979 if (mLaunchingProviders.get(j) == dst) {
11980 mLaunchingProviders.remove(j);
11981 wasInLaunchingProviders = true;
11986 if (wasInLaunchingProviders) {
11987 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11989 synchronized (dst) {
11990 dst.provider = src.provider;
11994 updateOomAdjLocked(r, true);
11995 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11996 src.info.authority);
12000 Binder.restoreCallingIdentity(origId);
12004 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12005 ContentProviderConnection conn;
12007 conn = (ContentProviderConnection)connection;
12008 } catch (ClassCastException e) {
12009 String msg ="refContentProvider: " + connection
12010 + " not a ContentProviderConnection";
12012 throw new IllegalArgumentException(msg);
12014 if (conn == null) {
12015 throw new NullPointerException("connection is null");
12018 synchronized (this) {
12020 conn.numStableIncs += stable;
12022 stable = conn.stableCount + stable;
12024 throw new IllegalStateException("stableCount < 0: " + stable);
12027 if (unstable > 0) {
12028 conn.numUnstableIncs += unstable;
12030 unstable = conn.unstableCount + unstable;
12031 if (unstable < 0) {
12032 throw new IllegalStateException("unstableCount < 0: " + unstable);
12035 if ((stable+unstable) <= 0) {
12036 throw new IllegalStateException("ref counts can't go to zero here: stable="
12037 + stable + " unstable=" + unstable);
12039 conn.stableCount = stable;
12040 conn.unstableCount = unstable;
12045 public void unstableProviderDied(IBinder connection) {
12046 ContentProviderConnection conn;
12048 conn = (ContentProviderConnection)connection;
12049 } catch (ClassCastException e) {
12050 String msg ="refContentProvider: " + connection
12051 + " not a ContentProviderConnection";
12053 throw new IllegalArgumentException(msg);
12055 if (conn == null) {
12056 throw new NullPointerException("connection is null");
12059 // Safely retrieve the content provider associated with the connection.
12060 IContentProvider provider;
12061 synchronized (this) {
12062 provider = conn.provider.provider;
12065 if (provider == null) {
12066 // Um, yeah, we're way ahead of you.
12070 // Make sure the caller is being honest with us.
12071 if (provider.asBinder().pingBinder()) {
12072 // Er, no, still looks good to us.
12073 synchronized (this) {
12074 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12075 + " says " + conn + " died, but we don't agree");
12080 // Well look at that! It's dead!
12081 synchronized (this) {
12082 if (conn.provider.provider != provider) {
12083 // But something changed... good enough.
12087 ProcessRecord proc = conn.provider.proc;
12088 if (proc == null || proc.thread == null) {
12089 // Seems like the process is already cleaned up.
12093 // As far as we're concerned, this is just like receiving a
12094 // death notification... just a bit prematurely.
12095 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12096 + ") early provider death");
12097 final long ident = Binder.clearCallingIdentity();
12099 appDiedLocked(proc);
12101 Binder.restoreCallingIdentity(ident);
12107 public void appNotRespondingViaProvider(IBinder connection) {
12108 enforceCallingPermission(
12109 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12111 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12112 if (conn == null) {
12113 Slog.w(TAG, "ContentProviderConnection is null");
12117 final ProcessRecord host = conn.provider.proc;
12118 if (host == null) {
12119 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12123 mHandler.post(new Runnable() {
12125 public void run() {
12126 mAppErrors.appNotResponding(host, null, null, false,
12127 "ContentProvider not responding");
12132 public final void installSystemProviders() {
12133 List<ProviderInfo> providers;
12134 synchronized (this) {
12135 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12136 providers = generateApplicationProvidersLocked(app);
12137 if (providers != null) {
12138 for (int i=providers.size()-1; i>=0; i--) {
12139 ProviderInfo pi = (ProviderInfo)providers.get(i);
12140 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12141 Slog.w(TAG, "Not installing system proc provider " + pi.name
12142 + ": not system .apk");
12143 providers.remove(i);
12148 if (providers != null) {
12149 mSystemThread.installSystemProviders(providers);
12152 mConstants.start(mContext.getContentResolver());
12153 mCoreSettingsObserver = new CoreSettingsObserver(this);
12154 mFontScaleSettingObserver = new FontScaleSettingObserver();
12156 // Now that the settings provider is published we can consider sending
12157 // in a rescue party.
12158 RescueParty.onSettingsProviderPublished(mContext);
12160 //mUsageStatsService.monitorPackages();
12163 private void startPersistentApps(int matchFlags) {
12164 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12166 synchronized (this) {
12168 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12169 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12170 for (ApplicationInfo app : apps) {
12171 if (!"android".equals(app.packageName)) {
12172 addAppLocked(app, null, false, null /* ABI override */);
12175 } catch (RemoteException ex) {
12181 * When a user is unlocked, we need to install encryption-unaware providers
12182 * belonging to any running apps.
12184 private void installEncryptionUnawareProviders(int userId) {
12185 // We're only interested in providers that are encryption unaware, and
12186 // we don't care about uninstalled apps, since there's no way they're
12187 // running at this point.
12188 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12190 synchronized (this) {
12191 final int NP = mProcessNames.getMap().size();
12192 for (int ip = 0; ip < NP; ip++) {
12193 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12194 final int NA = apps.size();
12195 for (int ia = 0; ia < NA; ia++) {
12196 final ProcessRecord app = apps.valueAt(ia);
12197 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12199 final int NG = app.pkgList.size();
12200 for (int ig = 0; ig < NG; ig++) {
12202 final String pkgName = app.pkgList.keyAt(ig);
12203 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12204 .getPackageInfo(pkgName, matchFlags, userId);
12205 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12206 for (ProviderInfo pi : pkgInfo.providers) {
12207 // TODO: keep in sync with generateApplicationProvidersLocked
12208 final boolean processMatch = Objects.equals(pi.processName,
12209 app.processName) || pi.multiprocess;
12210 final boolean userMatch = isSingleton(pi.processName,
12211 pi.applicationInfo, pi.name, pi.flags)
12212 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12213 if (processMatch && userMatch) {
12214 Log.v(TAG, "Installing " + pi);
12215 app.thread.scheduleInstallProvider(pi);
12217 Log.v(TAG, "Skipping " + pi);
12221 } catch (RemoteException ignored) {
12230 * Allows apps to retrieve the MIME type of a URI.
12231 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12232 * users, then it does not need permission to access the ContentProvider.
12233 * Either, it needs cross-user uri grants.
12235 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12237 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12238 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12240 public String getProviderMimeType(Uri uri, int userId) {
12241 enforceNotIsolatedCaller("getProviderMimeType");
12242 final String name = uri.getAuthority();
12243 int callingUid = Binder.getCallingUid();
12244 int callingPid = Binder.getCallingPid();
12246 boolean clearedIdentity = false;
12247 synchronized (this) {
12248 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12250 if (canClearIdentity(callingPid, callingUid, userId)) {
12251 clearedIdentity = true;
12252 ident = Binder.clearCallingIdentity();
12254 ContentProviderHolder holder = null;
12256 holder = getContentProviderExternalUnchecked(name, null, userId);
12257 if (holder != null) {
12258 return holder.provider.getType(uri);
12260 } catch (RemoteException e) {
12261 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12263 } catch (Exception e) {
12264 Log.w(TAG, "Exception while determining type of " + uri, e);
12267 // We need to clear the identity to call removeContentProviderExternalUnchecked
12268 if (!clearedIdentity) {
12269 ident = Binder.clearCallingIdentity();
12272 if (holder != null) {
12273 removeContentProviderExternalUnchecked(name, null, userId);
12276 Binder.restoreCallingIdentity(ident);
12283 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12284 if (UserHandle.getUserId(callingUid) == userId) {
12287 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12288 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12289 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12290 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12296 // =========================================================
12297 // GLOBAL MANAGEMENT
12298 // =========================================================
12300 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12301 boolean isolated, int isolatedUid) {
12302 String proc = customProcess != null ? customProcess : info.processName;
12303 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12304 final int userId = UserHandle.getUserId(info.uid);
12305 int uid = info.uid;
12307 if (isolatedUid == 0) {
12308 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12310 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12311 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12312 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12314 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12315 mNextIsolatedProcessUid++;
12316 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12317 // No process for this uid, use it.
12321 if (stepsLeft <= 0) {
12326 // Special case for startIsolatedProcess (internal only), where
12327 // the uid of the isolated process is specified by the caller.
12330 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12332 // Register the isolated UID with this application so BatteryStats knows to
12333 // attribute resource usage to the application.
12335 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12336 // about the process state of the isolated UID *before* it is registered with the
12337 // owning application.
12338 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12340 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12341 if (!mBooted && !mBooting
12342 && userId == UserHandle.USER_SYSTEM
12343 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12344 r.persistent = true;
12345 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12347 addProcessNameLocked(r);
12351 private boolean uidOnBackgroundWhitelist(final int uid) {
12352 final int appId = UserHandle.getAppId(uid);
12353 final int[] whitelist = mBackgroundAppIdWhitelist;
12354 final int N = whitelist.length;
12355 for (int i = 0; i < N; i++) {
12356 if (appId == whitelist[i]) {
12364 public void backgroundWhitelistUid(final int uid) {
12365 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12366 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12369 if (DEBUG_BACKGROUND_CHECK) {
12370 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12372 synchronized (this) {
12373 final int N = mBackgroundAppIdWhitelist.length;
12374 int[] newList = new int[N+1];
12375 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12376 newList[N] = UserHandle.getAppId(uid);
12377 mBackgroundAppIdWhitelist = newList;
12381 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12382 String abiOverride) {
12385 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12392 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12393 updateLruProcessLocked(app, false, null);
12394 updateOomAdjLocked();
12397 // This package really, really can not be stopped.
12399 AppGlobals.getPackageManager().setPackageStoppedState(
12400 info.packageName, false, UserHandle.getUserId(app.uid));
12401 } catch (RemoteException e) {
12402 } catch (IllegalArgumentException e) {
12403 Slog.w(TAG, "Failed trying to unstop package "
12404 + info.packageName + ": " + e);
12407 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12408 app.persistent = true;
12409 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12411 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12412 mPersistentStartingProcesses.add(app);
12413 startProcessLocked(app, "added application",
12414 customProcess != null ? customProcess : app.processName, abiOverride,
12415 null /* entryPoint */, null /* entryPointArgs */);
12421 public void unhandledBack() {
12422 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12423 "unhandledBack()");
12425 synchronized(this) {
12426 final long origId = Binder.clearCallingIdentity();
12428 getFocusedStack().unhandledBackLocked();
12430 Binder.restoreCallingIdentity(origId);
12435 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12436 enforceNotIsolatedCaller("openContentUri");
12437 final int userId = UserHandle.getCallingUserId();
12438 final Uri uri = Uri.parse(uriString);
12439 String name = uri.getAuthority();
12440 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12441 ParcelFileDescriptor pfd = null;
12443 // We record the binder invoker's uid in thread-local storage before
12444 // going to the content provider to open the file. Later, in the code
12445 // that handles all permissions checks, we look for this uid and use
12446 // that rather than the Activity Manager's own uid. The effect is that
12447 // we do the check against the caller's permissions even though it looks
12448 // to the content provider like the Activity Manager itself is making
12450 Binder token = new Binder();
12451 sCallerIdentity.set(new Identity(
12452 token, Binder.getCallingPid(), Binder.getCallingUid()));
12454 pfd = cph.provider.openFile(null, uri, "r", null, token);
12455 } catch (FileNotFoundException e) {
12456 // do nothing; pfd will be returned null
12458 // Ensure that whatever happens, we clean up the identity state
12459 sCallerIdentity.remove();
12460 // Ensure we're done with the provider.
12461 removeContentProviderExternalUnchecked(name, null, userId);
12464 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12469 // Actually is sleeping or shutting down or whatever else in the future
12470 // is an inactive state.
12471 boolean isSleepingOrShuttingDownLocked() {
12472 return isSleepingLocked() || mShuttingDown;
12475 boolean isShuttingDownLocked() {
12476 return mShuttingDown;
12479 boolean isSleepingLocked() {
12483 void onWakefulnessChanged(int wakefulness) {
12484 synchronized(this) {
12485 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12486 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12487 mWakefulness = wakefulness;
12489 if (wasAwake != isAwake) {
12490 // Also update state in a special way for running foreground services UI.
12491 mServices.updateScreenStateLocked(isAwake);
12492 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12498 void finishRunningVoiceLocked() {
12499 if (mRunningVoice != null) {
12500 mRunningVoice = null;
12501 mVoiceWakeLock.release();
12502 updateSleepIfNeededLocked();
12506 void startTimeTrackingFocusedActivityLocked() {
12507 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12508 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12509 mCurAppTimeTracker.start(resumedActivity.packageName);
12513 void updateSleepIfNeededLocked() {
12514 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12515 final boolean wasSleeping = mSleeping;
12517 if (!shouldSleep) {
12518 // If wasSleeping is true, we need to wake up activity manager state from when
12519 // we started sleeping. In either case, we need to apply the sleep tokens, which
12520 // will wake up stacks or put them to sleep as appropriate.
12523 startTimeTrackingFocusedActivityLocked();
12524 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12525 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12527 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12529 updateOomAdjLocked();
12531 } else if (!mSleeping && shouldSleep) {
12533 if (mCurAppTimeTracker != null) {
12534 mCurAppTimeTracker.stop();
12536 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12537 mStackSupervisor.goingToSleepLocked();
12538 updateOomAdjLocked();
12542 /** Pokes the task persister. */
12543 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12544 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12548 * Notifies all listeners when the pinned stack animation starts.
12551 public void notifyPinnedStackAnimationStarted() {
12552 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12556 * Notifies all listeners when the pinned stack animation ends.
12559 public void notifyPinnedStackAnimationEnded() {
12560 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12564 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12565 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12569 public boolean shutdown(int timeout) {
12570 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12571 != PackageManager.PERMISSION_GRANTED) {
12572 throw new SecurityException("Requires permission "
12573 + android.Manifest.permission.SHUTDOWN);
12576 boolean timedout = false;
12578 synchronized(this) {
12579 mShuttingDown = true;
12580 mStackSupervisor.prepareForShutdownLocked();
12581 updateEventDispatchingLocked();
12582 timedout = mStackSupervisor.shutdownLocked(timeout);
12585 mAppOpsService.shutdown();
12586 if (mUsageStatsService != null) {
12587 mUsageStatsService.prepareShutdown();
12589 mBatteryStatsService.shutdown();
12590 synchronized (this) {
12591 mProcessStats.shutdownLocked();
12592 notifyTaskPersisterLocked(null, true);
12598 public final void activitySlept(IBinder token) {
12599 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12601 final long origId = Binder.clearCallingIdentity();
12603 synchronized (this) {
12604 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12606 mStackSupervisor.activitySleptLocked(r);
12610 Binder.restoreCallingIdentity(origId);
12613 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12614 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12615 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12616 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12617 boolean wasRunningVoice = mRunningVoice != null;
12618 mRunningVoice = session;
12619 if (!wasRunningVoice) {
12620 mVoiceWakeLock.acquire();
12621 updateSleepIfNeededLocked();
12626 private void updateEventDispatchingLocked() {
12627 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12631 public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12632 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12633 != PackageManager.PERMISSION_GRANTED) {
12634 throw new SecurityException("Requires permission "
12635 + android.Manifest.permission.DEVICE_POWER);
12638 synchronized(this) {
12639 long ident = Binder.clearCallingIdentity();
12641 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12643 Binder.restoreCallingIdentity(ident);
12647 mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12652 public void notifyLockedProfile(@UserIdInt int userId) {
12654 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12655 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12657 } catch (RemoteException ex) {
12658 throw new SecurityException("Fail to check is caller a privileged app", ex);
12661 synchronized (this) {
12662 final long ident = Binder.clearCallingIdentity();
12664 if (mUserController.shouldConfirmCredentials(userId)) {
12665 if (mKeyguardController.isKeyguardLocked()) {
12666 // Showing launcher to avoid user entering credential twice.
12667 final int currentUserId = mUserController.getCurrentUserIdLocked();
12668 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12670 mStackSupervisor.lockAllProfileTasks(userId);
12673 Binder.restoreCallingIdentity(ident);
12679 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12680 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12681 synchronized (this) {
12682 final long ident = Binder.clearCallingIdentity();
12684 mActivityStarter.startConfirmCredentialIntent(intent, options);
12686 Binder.restoreCallingIdentity(ident);
12692 public void stopAppSwitches() {
12693 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12694 != PackageManager.PERMISSION_GRANTED) {
12695 throw new SecurityException("viewquires permission "
12696 + android.Manifest.permission.STOP_APP_SWITCHES);
12699 synchronized(this) {
12700 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12701 + APP_SWITCH_DELAY_TIME;
12702 mDidAppSwitch = false;
12703 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12704 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12705 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12709 public void resumeAppSwitches() {
12710 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12711 != PackageManager.PERMISSION_GRANTED) {
12712 throw new SecurityException("Requires permission "
12713 + android.Manifest.permission.STOP_APP_SWITCHES);
12716 synchronized(this) {
12717 // Note that we don't execute any pending app switches... we will
12718 // let those wait until either the timeout, or the next start
12719 // activity request.
12720 mAppSwitchesAllowedTime = 0;
12724 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12725 int callingPid, int callingUid, String name) {
12726 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12730 int perm = checkComponentPermission(
12731 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12732 sourceUid, -1, true);
12733 if (perm == PackageManager.PERMISSION_GRANTED) {
12737 // If the actual IPC caller is different from the logical source, then
12738 // also see if they are allowed to control app switches.
12739 if (callingUid != -1 && callingUid != sourceUid) {
12740 perm = checkComponentPermission(
12741 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12742 callingUid, -1, true);
12743 if (perm == PackageManager.PERMISSION_GRANTED) {
12748 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12752 public void setDebugApp(String packageName, boolean waitForDebugger,
12753 boolean persistent) {
12754 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12757 long ident = Binder.clearCallingIdentity();
12759 // Note that this is not really thread safe if there are multiple
12760 // callers into it at the same time, but that's not a situation we
12763 final ContentResolver resolver = mContext.getContentResolver();
12764 Settings.Global.putString(
12765 resolver, Settings.Global.DEBUG_APP,
12767 Settings.Global.putInt(
12768 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12769 waitForDebugger ? 1 : 0);
12772 synchronized (this) {
12774 mOrigDebugApp = mDebugApp;
12775 mOrigWaitForDebugger = mWaitForDebugger;
12777 mDebugApp = packageName;
12778 mWaitForDebugger = waitForDebugger;
12779 mDebugTransient = !persistent;
12780 if (packageName != null) {
12781 forceStopPackageLocked(packageName, -1, false, false, true, true,
12782 false, UserHandle.USER_ALL, "set debug app");
12786 Binder.restoreCallingIdentity(ident);
12790 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12791 synchronized (this) {
12792 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12793 if (!isDebuggable) {
12794 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12795 throw new SecurityException("Process not debuggable: " + app.packageName);
12799 mTrackAllocationApp = processName;
12803 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
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);
12811 mProfileApp = processName;
12813 if (mProfilerInfo != null) {
12814 if (mProfilerInfo.profileFd != null) {
12816 mProfilerInfo.profileFd.close();
12817 } catch (IOException e) {
12821 mProfilerInfo = new ProfilerInfo(profilerInfo);
12826 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12827 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12828 if (!isDebuggable) {
12829 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12830 throw new SecurityException("Process not debuggable: " + app.packageName);
12833 mNativeDebuggingApp = processName;
12837 public void setAlwaysFinish(boolean enabled) {
12838 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12839 "setAlwaysFinish()");
12841 long ident = Binder.clearCallingIdentity();
12843 Settings.Global.putInt(
12844 mContext.getContentResolver(),
12845 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12847 synchronized (this) {
12848 mAlwaysFinishActivities = enabled;
12851 Binder.restoreCallingIdentity(ident);
12856 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12857 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12858 "setActivityController()");
12859 synchronized (this) {
12860 mController = controller;
12861 mControllerIsAMonkey = imAMonkey;
12862 Watchdog.getInstance().setActivityController(controller);
12867 public void setUserIsMonkey(boolean userIsMonkey) {
12868 synchronized (this) {
12869 synchronized (mPidsSelfLocked) {
12870 final int callingPid = Binder.getCallingPid();
12871 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12872 if (proc == null) {
12873 throw new SecurityException("Unknown process: " + callingPid);
12875 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12876 throw new SecurityException("Only an instrumentation process "
12877 + "with a UiAutomation can call setUserIsMonkey");
12880 mUserIsMonkey = userIsMonkey;
12885 public boolean isUserAMonkey() {
12886 synchronized (this) {
12887 // If there is a controller also implies the user is a monkey.
12888 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12893 * @deprecated This method is only used by a few internal components and it will soon be
12894 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12895 * No new code should be calling it.
12899 public void requestBugReport(int bugreportType) {
12900 String extraOptions = null;
12901 switch (bugreportType) {
12902 case ActivityManager.BUGREPORT_OPTION_FULL:
12903 // Default options.
12905 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12906 extraOptions = "bugreportplus";
12908 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12909 extraOptions = "bugreportremote";
12911 case ActivityManager.BUGREPORT_OPTION_WEAR:
12912 extraOptions = "bugreportwear";
12914 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12915 extraOptions = "bugreporttelephony";
12918 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12921 // Always log caller, even if it does not have permission to dump.
12922 String type = extraOptions == null ? "bugreport" : extraOptions;
12923 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12925 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12926 if (extraOptions != null) {
12927 SystemProperties.set("dumpstate.options", extraOptions);
12929 SystemProperties.set("ctl.start", "bugreport");
12933 * @deprecated This method is only used by a few internal components and it will soon be
12934 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12935 * No new code should be calling it.
12939 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12941 if (!TextUtils.isEmpty(shareTitle)) {
12942 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12943 String errorStr = "shareTitle should be less than " +
12944 MAX_BUGREPORT_TITLE_SIZE + " characters";
12945 throw new IllegalArgumentException(errorStr);
12947 if (!TextUtils.isEmpty(shareDescription)) {
12950 length = shareDescription.getBytes("UTF-8").length;
12951 } catch (UnsupportedEncodingException e) {
12952 String errorStr = "shareDescription: UnsupportedEncodingException";
12953 throw new IllegalArgumentException(errorStr);
12955 if (length > SystemProperties.PROP_VALUE_MAX) {
12956 String errorStr = "shareTitle should be less than " +
12957 SystemProperties.PROP_VALUE_MAX + " bytes";
12958 throw new IllegalArgumentException(errorStr);
12960 SystemProperties.set("dumpstate.options.description", shareDescription);
12963 SystemProperties.set("dumpstate.options.title", shareTitle);
12967 Slog.d(TAG, "Bugreport notification title " + shareTitle
12968 + " description " + shareDescription);
12969 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12972 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12973 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12976 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12977 if (r != null && (r.instr != null || r.usingWrapper)) {
12978 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12980 return KEY_DISPATCHING_TIMEOUT;
12984 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12985 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12986 != PackageManager.PERMISSION_GRANTED) {
12987 throw new SecurityException("Requires permission "
12988 + android.Manifest.permission.FILTER_EVENTS);
12990 ProcessRecord proc;
12992 synchronized (this) {
12993 synchronized (mPidsSelfLocked) {
12994 proc = mPidsSelfLocked.get(pid);
12996 timeout = getInputDispatchingTimeoutLocked(proc);
12999 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13007 * Handle input dispatching timeouts.
13008 * Returns whether input dispatching should be aborted or not.
13010 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13011 final ActivityRecord activity, final ActivityRecord parent,
13012 final boolean aboveSystem, String reason) {
13013 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13014 != PackageManager.PERMISSION_GRANTED) {
13015 throw new SecurityException("Requires permission "
13016 + android.Manifest.permission.FILTER_EVENTS);
13019 final String annotation;
13020 if (reason == null) {
13021 annotation = "Input dispatching timed out";
13023 annotation = "Input dispatching timed out (" + reason + ")";
13026 if (proc != null) {
13027 synchronized (this) {
13028 if (proc.debugging) {
13032 if (proc.instr != null) {
13033 Bundle info = new Bundle();
13034 info.putString("shortMsg", "keyDispatchingTimedOut");
13035 info.putString("longMsg", annotation);
13036 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13040 mHandler.post(new Runnable() {
13042 public void run() {
13043 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13052 public Bundle getAssistContextExtras(int requestType) {
13053 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13054 null, null, true /* focused */, true /* newSessionId */,
13055 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13059 synchronized (pae) {
13060 while (!pae.haveResult) {
13063 } catch (InterruptedException e) {
13067 synchronized (this) {
13068 buildAssistBundleLocked(pae, pae.result);
13069 mPendingAssistExtras.remove(pae);
13070 mUiHandler.removeCallbacks(pae);
13076 public boolean isAssistDataAllowedOnCurrentActivity() {
13078 synchronized (this) {
13079 final ActivityStack focusedStack = getFocusedStack();
13080 if (focusedStack == null || focusedStack.isAssistantStack()) {
13084 final ActivityRecord activity = focusedStack.topActivity();
13085 if (activity == null) {
13088 userId = activity.userId;
13090 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13091 Context.DEVICE_POLICY_SERVICE);
13092 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13096 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13097 long ident = Binder.clearCallingIdentity();
13099 synchronized (this) {
13100 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13101 ActivityRecord top = getFocusedStack().topActivity();
13102 if (top != caller) {
13103 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13104 + " is not current top " + top);
13107 if (!top.nowVisible) {
13108 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13109 + " is not visible");
13113 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13116 Binder.restoreCallingIdentity(ident);
13121 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13122 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13123 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13124 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13125 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13129 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13130 IBinder activityToken, int flags) {
13131 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13132 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13133 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13136 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13137 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13138 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13140 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13141 "enqueueAssistContext()");
13143 synchronized (this) {
13144 ActivityRecord activity = getFocusedStack().topActivity();
13145 if (activity == null) {
13146 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13149 if (activity.app == null || activity.app.thread == null) {
13150 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13154 if (activityToken != null) {
13155 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13156 if (activity != caller) {
13157 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13158 + " is not current top " + activity);
13163 activity = ActivityRecord.forTokenLocked(activityToken);
13164 if (activity == null) {
13165 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13166 + " couldn't be found");
13169 if (activity.app == null || activity.app.thread == null) {
13170 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13175 PendingAssistExtras pae;
13176 Bundle extras = new Bundle();
13177 if (args != null) {
13178 extras.putAll(args);
13180 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13181 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13183 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13185 pae.isHome = activity.isHomeActivity();
13187 // Increment the sessionId if necessary
13188 if (newSessionId) {
13192 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13193 mViSessionId, flags);
13194 mPendingAssistExtras.add(pae);
13195 mUiHandler.postDelayed(pae, timeout);
13196 } catch (RemoteException e) {
13197 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13204 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13205 IResultReceiver receiver;
13206 synchronized (this) {
13207 mPendingAssistExtras.remove(pae);
13208 receiver = pae.receiver;
13210 if (receiver != null) {
13211 // Caller wants result sent back to them.
13212 Bundle sendBundle = new Bundle();
13213 // At least return the receiver extras
13214 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13215 pae.receiverExtras);
13217 pae.receiver.send(0, sendBundle);
13218 } catch (RemoteException e) {
13223 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13224 if (result != null) {
13225 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13227 if (pae.hint != null) {
13228 pae.extras.putBoolean(pae.hint, true);
13232 /** Called from an app when assist data is ready. */
13234 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13235 AssistContent content, Uri referrer) {
13236 PendingAssistExtras pae = (PendingAssistExtras)token;
13237 synchronized (pae) {
13238 pae.result = extras;
13239 pae.structure = structure;
13240 pae.content = content;
13241 if (referrer != null) {
13242 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13244 if (structure != null) {
13245 structure.setHomeActivity(pae.isHome);
13247 pae.haveResult = true;
13249 if (pae.intent == null && pae.receiver == null) {
13250 // Caller is just waiting for the result.
13254 // We are now ready to launch the assist activity.
13255 IResultReceiver sendReceiver = null;
13256 Bundle sendBundle = null;
13257 synchronized (this) {
13258 buildAssistBundleLocked(pae, extras);
13259 boolean exists = mPendingAssistExtras.remove(pae);
13260 mUiHandler.removeCallbacks(pae);
13265 if ((sendReceiver=pae.receiver) != null) {
13266 // Caller wants result sent back to them.
13267 sendBundle = new Bundle();
13268 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13269 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13270 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13271 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13272 pae.receiverExtras);
13275 if (sendReceiver != null) {
13277 sendReceiver.send(0, sendBundle);
13278 } catch (RemoteException e) {
13283 final long ident = Binder.clearCallingIdentity();
13285 if (TextUtils.equals(pae.intent.getAction(),
13286 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13287 pae.intent.putExtras(pae.extras);
13288 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13290 pae.intent.replaceExtras(pae.extras);
13291 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13292 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13293 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13294 closeSystemDialogs("assist");
13297 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13298 } catch (ActivityNotFoundException e) {
13299 Slog.w(TAG, "No activity to handle assist action.", e);
13303 Binder.restoreCallingIdentity(ident);
13307 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13309 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13310 true /* focused */, true /* newSessionId */, userHandle, args,
13311 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13314 public void registerProcessObserver(IProcessObserver observer) {
13315 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13316 "registerProcessObserver()");
13317 synchronized (this) {
13318 mProcessObservers.register(observer);
13323 public void unregisterProcessObserver(IProcessObserver observer) {
13324 synchronized (this) {
13325 mProcessObservers.unregister(observer);
13330 public int getUidProcessState(int uid, String callingPackage) {
13331 if (!hasUsageStatsPermission(callingPackage)) {
13332 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13333 "getUidProcessState");
13336 synchronized (this) {
13337 UidRecord uidRec = mActiveUids.get(uid);
13338 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13343 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13344 String callingPackage) {
13345 if (!hasUsageStatsPermission(callingPackage)) {
13346 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13347 "registerUidObserver");
13349 synchronized (this) {
13350 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13351 callingPackage, which, cutpoint));
13356 public void unregisterUidObserver(IUidObserver observer) {
13357 synchronized (this) {
13358 mUidObservers.unregister(observer);
13363 public boolean convertFromTranslucent(IBinder token) {
13364 final long origId = Binder.clearCallingIdentity();
13366 synchronized (this) {
13367 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13371 final boolean translucentChanged = r.changeWindowTranslucency(true);
13372 if (translucentChanged) {
13373 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13375 mWindowManager.setAppFullscreen(token, true);
13376 return translucentChanged;
13379 Binder.restoreCallingIdentity(origId);
13384 public boolean convertToTranslucent(IBinder token, Bundle options) {
13385 final long origId = Binder.clearCallingIdentity();
13387 synchronized (this) {
13388 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13392 final TaskRecord task = r.getTask();
13393 int index = task.mActivities.lastIndexOf(r);
13395 ActivityRecord under = task.mActivities.get(index - 1);
13396 under.returningOptions = ActivityOptions.fromBundle(options);
13398 final boolean translucentChanged = r.changeWindowTranslucency(false);
13399 if (translucentChanged) {
13400 r.getStack().convertActivityToTranslucent(r);
13402 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13403 mWindowManager.setAppFullscreen(token, false);
13404 return translucentChanged;
13407 Binder.restoreCallingIdentity(origId);
13412 public Bundle getActivityOptions(IBinder token) {
13413 final long origId = Binder.clearCallingIdentity();
13415 synchronized (this) {
13416 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13418 final ActivityOptions activityOptions = r.takeOptionsLocked();
13419 return activityOptions == null ? null : activityOptions.toBundle();
13424 Binder.restoreCallingIdentity(origId);
13429 public void setImmersive(IBinder token, boolean immersive) {
13430 synchronized(this) {
13431 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13433 throw new IllegalArgumentException();
13435 r.immersive = immersive;
13437 // update associated state if we're frontmost
13438 if (r == mStackSupervisor.getResumedActivityLocked()) {
13439 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13440 applyUpdateLockStateLocked(r);
13446 public boolean isImmersive(IBinder token) {
13447 synchronized (this) {
13448 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13450 throw new IllegalArgumentException();
13452 return r.immersive;
13457 public void setVrThread(int tid) {
13458 enforceSystemHasVrFeature();
13459 synchronized (this) {
13460 synchronized (mPidsSelfLocked) {
13461 final int pid = Binder.getCallingPid();
13462 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13463 mVrController.setVrThreadLocked(tid, pid, proc);
13469 public void setPersistentVrThread(int tid) {
13470 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13471 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13472 + Binder.getCallingPid()
13473 + ", uid=" + Binder.getCallingUid()
13474 + " requires " + permission.RESTRICTED_VR_ACCESS;
13476 throw new SecurityException(msg);
13478 enforceSystemHasVrFeature();
13479 synchronized (this) {
13480 synchronized (mPidsSelfLocked) {
13481 final int pid = Binder.getCallingPid();
13482 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13483 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13489 * Schedule the given thread a normal scheduling priority.
13491 * @param tid the tid of the thread to adjust the scheduling of.
13492 * @param suppressLogs {@code true} if any error logging should be disabled.
13494 * @return {@code true} if this succeeded.
13496 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13498 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13500 } catch (IllegalArgumentException e) {
13501 if (!suppressLogs) {
13502 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13504 } catch (SecurityException e) {
13505 if (!suppressLogs) {
13506 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13513 * Schedule the given thread an FIFO scheduling priority.
13515 * @param tid the tid of the thread to adjust the scheduling of.
13516 * @param suppressLogs {@code true} if any error logging should be disabled.
13518 * @return {@code true} if this succeeded.
13520 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13522 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13524 } catch (IllegalArgumentException e) {
13525 if (!suppressLogs) {
13526 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13528 } catch (SecurityException e) {
13529 if (!suppressLogs) {
13530 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13537 * Check that we have the features required for VR-related API calls, and throw an exception if
13540 private void enforceSystemHasVrFeature() {
13541 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13542 throw new UnsupportedOperationException("VR mode not supported on this device!");
13547 public void setRenderThread(int tid) {
13548 synchronized (this) {
13549 ProcessRecord proc;
13550 int pid = Binder.getCallingPid();
13551 if (pid == Process.myPid()) {
13552 demoteSystemServerRenderThread(tid);
13555 synchronized (mPidsSelfLocked) {
13556 proc = mPidsSelfLocked.get(pid);
13557 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13558 // ensure the tid belongs to the process
13559 if (!isThreadInProcess(pid, tid)) {
13560 throw new IllegalArgumentException(
13561 "Render thread does not belong to process");
13563 proc.renderThreadTid = tid;
13564 if (DEBUG_OOM_ADJ) {
13565 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13567 // promote to FIFO now
13568 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13569 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13570 if (mUseFifoUiScheduling) {
13571 setThreadScheduler(proc.renderThreadTid,
13572 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13574 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13578 if (DEBUG_OOM_ADJ) {
13579 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13580 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13581 mUseFifoUiScheduling);
13589 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13590 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13592 * @param tid the tid of the RenderThread
13594 private void demoteSystemServerRenderThread(int tid) {
13595 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13599 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13600 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13601 throw new UnsupportedOperationException("VR mode not supported on this device!");
13604 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13607 synchronized (this) {
13608 r = ActivityRecord.isInStackLocked(token);
13612 throw new IllegalArgumentException();
13616 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13617 VrManagerInternal.NO_ERROR) {
13621 synchronized(this) {
13622 r.requestedVrComponent = (enabled) ? packageName : null;
13624 // Update associated state if this activity is currently focused
13625 if (r == mStackSupervisor.getResumedActivityLocked()) {
13626 applyUpdateVrModeLocked(r);
13633 public boolean isVrModePackageEnabled(ComponentName packageName) {
13634 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13635 throw new UnsupportedOperationException("VR mode not supported on this device!");
13638 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13640 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13641 VrManagerInternal.NO_ERROR;
13644 public boolean isTopActivityImmersive() {
13645 enforceNotIsolatedCaller("startActivity");
13646 synchronized (this) {
13647 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13648 return (r != null) ? r.immersive : false;
13653 * @return whether the system should disable UI modes incompatible with VR mode.
13655 boolean shouldDisableNonVrUiLocked() {
13656 return mVrController.shouldDisableNonVrUiLocked();
13660 public boolean isTopOfTask(IBinder token) {
13661 synchronized (this) {
13662 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13664 throw new IllegalArgumentException();
13666 return r.getTask().getTopActivity() == r;
13671 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13672 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13673 String msg = "Permission Denial: setHasTopUi() from pid="
13674 + Binder.getCallingPid()
13675 + ", uid=" + Binder.getCallingUid()
13676 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13678 throw new SecurityException(msg);
13680 final int pid = Binder.getCallingPid();
13681 final long origId = Binder.clearCallingIdentity();
13683 synchronized (this) {
13684 boolean changed = false;
13686 synchronized (mPidsSelfLocked) {
13687 pr = mPidsSelfLocked.get(pid);
13689 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13692 if (pr.hasTopUi != hasTopUi) {
13693 if (DEBUG_OOM_ADJ) {
13694 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13696 pr.hasTopUi = hasTopUi;
13701 updateOomAdjLocked(pr, true);
13705 Binder.restoreCallingIdentity(origId);
13709 public final void enterSafeMode() {
13710 synchronized(this) {
13711 // It only makes sense to do this before the system is ready
13712 // and started launching other packages.
13713 if (!mSystemReady) {
13715 AppGlobals.getPackageManager().enterSafeMode();
13716 } catch (RemoteException e) {
13724 public final void showSafeModeOverlay() {
13725 View v = LayoutInflater.from(mContext).inflate(
13726 com.android.internal.R.layout.safe_mode, null);
13727 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13728 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13729 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13730 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13731 lp.gravity = Gravity.BOTTOM | Gravity.START;
13732 lp.format = v.getBackground().getOpacity();
13733 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13734 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13735 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13736 ((WindowManager)mContext.getSystemService(
13737 Context.WINDOW_SERVICE)).addView(v, lp);
13740 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13741 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13744 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13745 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13746 synchronized (stats) {
13747 if (mBatteryStatsService.isOnBattery()) {
13748 mBatteryStatsService.enforceCallingPermission();
13749 int MY_UID = Binder.getCallingUid();
13751 if (sender == null) {
13754 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13756 BatteryStatsImpl.Uid.Pkg pkg =
13757 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13758 sourcePkg != null ? sourcePkg : rec.key.packageName);
13759 pkg.noteWakeupAlarmLocked(tag);
13764 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13765 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13768 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13769 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13770 synchronized (stats) {
13771 mBatteryStatsService.enforceCallingPermission();
13772 int MY_UID = Binder.getCallingUid();
13774 if (sender == null) {
13777 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13779 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13783 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13784 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13787 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13788 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13789 synchronized (stats) {
13790 mBatteryStatsService.enforceCallingPermission();
13791 int MY_UID = Binder.getCallingUid();
13793 if (sender == null) {
13796 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13798 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13802 public boolean killPids(int[] pids, String pReason, boolean secure) {
13803 if (Binder.getCallingUid() != SYSTEM_UID) {
13804 throw new SecurityException("killPids only available to the system");
13806 String reason = (pReason == null) ? "Unknown" : pReason;
13807 // XXX Note: don't acquire main activity lock here, because the window
13808 // manager calls in with its locks held.
13810 boolean killed = false;
13811 synchronized (mPidsSelfLocked) {
13813 for (int i=0; i<pids.length; i++) {
13814 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13815 if (proc != null) {
13816 int type = proc.setAdj;
13817 if (type > worstType) {
13823 // If the worst oom_adj is somewhere in the cached proc LRU range,
13824 // then constrain it so we will kill all cached procs.
13825 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13826 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13827 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13830 // If this is not a secure call, don't let it kill processes that
13832 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13833 worstType = ProcessList.SERVICE_ADJ;
13836 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13837 for (int i=0; i<pids.length; i++) {
13838 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13839 if (proc == null) {
13842 int adj = proc.setAdj;
13843 if (adj >= worstType && !proc.killedByAm) {
13844 proc.kill(reason, true);
13853 public void killUid(int appId, int userId, String reason) {
13854 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13855 synchronized (this) {
13856 final long identity = Binder.clearCallingIdentity();
13858 killPackageProcessesLocked(null, appId, userId,
13859 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13860 reason != null ? reason : "kill uid");
13862 Binder.restoreCallingIdentity(identity);
13868 public boolean killProcessesBelowForeground(String reason) {
13869 if (Binder.getCallingUid() != SYSTEM_UID) {
13870 throw new SecurityException("killProcessesBelowForeground() only available to system");
13873 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13876 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13877 if (Binder.getCallingUid() != SYSTEM_UID) {
13878 throw new SecurityException("killProcessesBelowAdj() only available to system");
13881 boolean killed = false;
13882 synchronized (mPidsSelfLocked) {
13883 final int size = mPidsSelfLocked.size();
13884 for (int i = 0; i < size; i++) {
13885 final int pid = mPidsSelfLocked.keyAt(i);
13886 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13887 if (proc == null) continue;
13889 final int adj = proc.setAdj;
13890 if (adj > belowAdj && !proc.killedByAm) {
13891 proc.kill(reason, true);
13900 public void hang(final IBinder who, boolean allowRestart) {
13901 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13902 != PackageManager.PERMISSION_GRANTED) {
13903 throw new SecurityException("Requires permission "
13904 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13907 final IBinder.DeathRecipient death = new DeathRecipient() {
13909 public void binderDied() {
13910 synchronized (this) {
13917 who.linkToDeath(death, 0);
13918 } catch (RemoteException e) {
13919 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13923 synchronized (this) {
13924 Watchdog.getInstance().setAllowRestart(allowRestart);
13925 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13926 synchronized (death) {
13927 while (who.isBinderAlive()) {
13930 } catch (InterruptedException e) {
13934 Watchdog.getInstance().setAllowRestart(true);
13939 public void restart() {
13940 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13941 != PackageManager.PERMISSION_GRANTED) {
13942 throw new SecurityException("Requires permission "
13943 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13946 Log.i(TAG, "Sending shutdown broadcast...");
13948 BroadcastReceiver br = new BroadcastReceiver() {
13949 @Override public void onReceive(Context context, Intent intent) {
13950 // Now the broadcast is done, finish up the low-level shutdown.
13951 Log.i(TAG, "Shutting down activity manager...");
13953 Log.i(TAG, "Shutdown complete, restarting!");
13954 killProcess(myPid());
13959 // First send the high-level shut down broadcast.
13960 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13961 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13962 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13963 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13964 mContext.sendOrderedBroadcastAsUser(intent,
13965 UserHandle.ALL, null, br, mHandler, 0, null, null);
13967 br.onReceive(mContext, intent);
13970 private long getLowRamTimeSinceIdle(long now) {
13971 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13975 public void performIdleMaintenance() {
13976 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13977 != PackageManager.PERMISSION_GRANTED) {
13978 throw new SecurityException("Requires permission "
13979 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13982 synchronized (this) {
13983 final long now = SystemClock.uptimeMillis();
13984 final long timeSinceLastIdle = now - mLastIdleTime;
13985 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13986 mLastIdleTime = now;
13987 mLowRamTimeSinceLastIdle = 0;
13988 if (mLowRamStartTime != 0) {
13989 mLowRamStartTime = now;
13992 StringBuilder sb = new StringBuilder(128);
13993 sb.append("Idle maintenance over ");
13994 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13995 sb.append(" low RAM for ");
13996 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13997 Slog.i(TAG, sb.toString());
13999 // If at least 1/3 of our time since the last idle period has been spent
14000 // with RAM low, then we want to kill processes.
14001 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14003 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14004 ProcessRecord proc = mLruProcesses.get(i);
14005 if (proc.notCachedSinceIdle) {
14006 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14007 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14008 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14009 if (doKilling && proc.initialIdlePss != 0
14010 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14011 sb = new StringBuilder(128);
14013 sb.append(proc.processName);
14014 sb.append(" in idle maint: pss=");
14015 sb.append(proc.lastPss);
14016 sb.append(", swapPss=");
14017 sb.append(proc.lastSwapPss);
14018 sb.append(", initialPss=");
14019 sb.append(proc.initialIdlePss);
14020 sb.append(", period=");
14021 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14022 sb.append(", lowRamPeriod=");
14023 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14024 Slog.wtfQuiet(TAG, sb.toString());
14025 proc.kill("idle maint (pss " + proc.lastPss
14026 + " from " + proc.initialIdlePss + ")", true);
14029 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14030 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14031 proc.notCachedSinceIdle = true;
14032 proc.initialIdlePss = 0;
14033 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14034 mTestPssMode, isSleepingLocked(), now);
14038 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14039 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14044 public void sendIdleJobTrigger() {
14045 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14046 != PackageManager.PERMISSION_GRANTED) {
14047 throw new SecurityException("Requires permission "
14048 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14051 final long ident = Binder.clearCallingIdentity();
14053 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14054 .setPackage("android")
14055 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14056 broadcastIntent(null, intent, null, null, 0, null, null, null,
14057 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14059 Binder.restoreCallingIdentity(ident);
14063 private void retrieveSettings() {
14064 final ContentResolver resolver = mContext.getContentResolver();
14065 final boolean freeformWindowManagement =
14066 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14067 || Settings.Global.getInt(
14068 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14070 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14071 final boolean supportsPictureInPicture = supportsMultiWindow &&
14072 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14073 final boolean supportsSplitScreenMultiWindow =
14074 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14075 final boolean supportsMultiDisplay = mContext.getPackageManager()
14076 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14077 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14078 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14079 final boolean alwaysFinishActivities =
14080 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14081 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14082 final boolean forceResizable = Settings.Global.getInt(
14083 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14084 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14085 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14086 final boolean supportsLeanbackOnly =
14087 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14089 // Transfer any global setting for forcing RTL layout, into a System Property
14090 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14092 final Configuration configuration = new Configuration();
14093 Settings.System.getConfiguration(resolver, configuration);
14095 // This will take care of setting the correct layout direction flags
14096 configuration.setLayoutDirection(configuration.locale);
14099 synchronized (this) {
14100 mDebugApp = mOrigDebugApp = debugApp;
14101 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14102 mAlwaysFinishActivities = alwaysFinishActivities;
14103 mSupportsLeanbackOnly = supportsLeanbackOnly;
14104 mForceResizableActivities = forceResizable;
14105 final boolean multiWindowFormEnabled = freeformWindowManagement
14106 || supportsSplitScreenMultiWindow
14107 || supportsPictureInPicture
14108 || supportsMultiDisplay;
14109 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14110 mSupportsMultiWindow = true;
14111 mSupportsFreeformWindowManagement = freeformWindowManagement;
14112 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14113 mSupportsPictureInPicture = supportsPictureInPicture;
14114 mSupportsMultiDisplay = supportsMultiDisplay;
14116 mSupportsMultiWindow = false;
14117 mSupportsFreeformWindowManagement = false;
14118 mSupportsSplitScreenMultiWindow = false;
14119 mSupportsPictureInPicture = false;
14120 mSupportsMultiDisplay = false;
14122 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14123 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14124 // This happens before any activities are started, so we can change global configuration
14126 updateConfigurationLocked(configuration, null, true);
14127 final Configuration globalConfig = getGlobalConfiguration();
14128 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14130 // Load resources only after the current configuration has been set.
14131 final Resources res = mContext.getResources();
14132 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14133 mThumbnailWidth = res.getDimensionPixelSize(
14134 com.android.internal.R.dimen.thumbnail_width);
14135 mThumbnailHeight = res.getDimensionPixelSize(
14136 com.android.internal.R.dimen.thumbnail_height);
14137 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14138 com.android.internal.R.string.config_appsNotReportingCrashes));
14139 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14140 com.android.internal.R.bool.config_customUserSwitchUi);
14141 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14142 mFullscreenThumbnailScale = (float) res
14143 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14144 (float) globalConfig.screenWidthDp;
14146 mFullscreenThumbnailScale = res.getFraction(
14147 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14149 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14153 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14154 traceLog.traceBegin("PhaseActivityManagerReady");
14155 synchronized(this) {
14156 if (mSystemReady) {
14157 // If we're done calling all the receivers, run the next "boot phase" passed in
14158 // by the SystemServer
14159 if (goingCallback != null) {
14160 goingCallback.run();
14165 mLocalDeviceIdleController
14166 = LocalServices.getService(DeviceIdleController.LocalService.class);
14167 mAssistUtils = new AssistUtils(mContext);
14168 mVrController.onSystemReady();
14169 // Make sure we have the current profile info, since it is needed for security checks.
14170 mUserController.onSystemReady();
14171 mRecentTasks.onSystemReadyLocked();
14172 mAppOpsService.systemReady();
14173 mSystemReady = true;
14177 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14178 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14180 } catch (RemoteException e) {}
14182 ArrayList<ProcessRecord> procsToKill = null;
14183 synchronized(mPidsSelfLocked) {
14184 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14185 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14186 if (!isAllowedWhileBooting(proc.info)){
14187 if (procsToKill == null) {
14188 procsToKill = new ArrayList<ProcessRecord>();
14190 procsToKill.add(proc);
14195 synchronized(this) {
14196 if (procsToKill != null) {
14197 for (int i=procsToKill.size()-1; i>=0; i--) {
14198 ProcessRecord proc = procsToKill.get(i);
14199 Slog.i(TAG, "Removing system update proc: " + proc);
14200 removeProcessLocked(proc, true, false, "system update done");
14204 // Now that we have cleaned up any update processes, we
14205 // are ready to start launching real processes and know that
14206 // we won't trample on them any more.
14207 mProcessesReady = true;
14210 Slog.i(TAG, "System now ready");
14211 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14212 SystemClock.uptimeMillis());
14214 synchronized(this) {
14215 // Make sure we have no pre-ready processes sitting around.
14217 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14218 ResolveInfo ri = mContext.getPackageManager()
14219 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14221 CharSequence errorMsg = null;
14223 ActivityInfo ai = ri.activityInfo;
14224 ApplicationInfo app = ai.applicationInfo;
14225 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14226 mTopAction = Intent.ACTION_FACTORY_TEST;
14228 mTopComponent = new ComponentName(app.packageName,
14231 errorMsg = mContext.getResources().getText(
14232 com.android.internal.R.string.factorytest_not_system);
14235 errorMsg = mContext.getResources().getText(
14236 com.android.internal.R.string.factorytest_no_action);
14238 if (errorMsg != null) {
14241 mTopComponent = null;
14242 Message msg = Message.obtain();
14243 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14244 msg.getData().putCharSequence("msg", errorMsg);
14245 mUiHandler.sendMessage(msg);
14250 retrieveSettings();
14251 final int currentUserId;
14252 synchronized (this) {
14253 currentUserId = mUserController.getCurrentUserIdLocked();
14254 readGrantedUriPermissionsLocked();
14257 if (goingCallback != null) goingCallback.run();
14258 traceLog.traceBegin("ActivityManagerStartApps");
14259 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14260 Integer.toString(currentUserId), currentUserId);
14261 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14262 Integer.toString(currentUserId), currentUserId);
14263 mSystemServiceManager.startUser(currentUserId);
14265 synchronized (this) {
14266 // Only start up encryption-aware persistent apps; once user is
14267 // unlocked we'll come back around and start unaware apps
14268 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14270 // Start up initial activity.
14272 // Enable home activity for system user, so that the system can always boot. We don't
14273 // do this when the system user is not setup since the setup wizard should be the one
14274 // to handle home activity in this case.
14275 if (UserManager.isSplitSystemUser() &&
14276 Settings.Secure.getInt(mContext.getContentResolver(),
14277 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14278 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14280 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14281 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14282 UserHandle.USER_SYSTEM);
14283 } catch (RemoteException e) {
14284 throw e.rethrowAsRuntimeException();
14287 startHomeActivityLocked(currentUserId, "systemReady");
14290 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14291 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14292 + " data partition or your device will be unstable.");
14293 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14295 } catch (RemoteException e) {
14298 if (!Build.isBuildConsistent()) {
14299 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14300 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14303 long ident = Binder.clearCallingIdentity();
14305 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14306 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14307 | Intent.FLAG_RECEIVER_FOREGROUND);
14308 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14309 broadcastIntentLocked(null, null, intent,
14310 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14311 null, false, false, MY_PID, SYSTEM_UID,
14313 intent = new Intent(Intent.ACTION_USER_STARTING);
14314 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14315 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14316 broadcastIntentLocked(null, null, intent,
14317 null, new IIntentReceiver.Stub() {
14319 public void performReceive(Intent intent, int resultCode, String data,
14320 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14321 throws RemoteException {
14324 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14325 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14326 } catch (Throwable t) {
14327 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14329 Binder.restoreCallingIdentity(ident);
14331 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14332 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14333 traceLog.traceEnd(); // ActivityManagerStartApps
14334 traceLog.traceEnd(); // PhaseActivityManagerReady
14338 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14339 synchronized (this) {
14340 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14344 void skipCurrentReceiverLocked(ProcessRecord app) {
14345 for (BroadcastQueue queue : mBroadcastQueues) {
14346 queue.skipCurrentReceiverLocked(app);
14351 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14352 * The application process will exit immediately after this call returns.
14353 * @param app object of the crashing app, null for the system server
14354 * @param crashInfo describing the exception
14356 public void handleApplicationCrash(IBinder app,
14357 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14358 ProcessRecord r = findAppProcess(app, "Crash");
14359 final String processName = app == null ? "system_server"
14360 : (r == null ? "unknown" : r.processName);
14362 handleApplicationCrashInner("crash", r, processName, crashInfo);
14365 /* Native crash reporting uses this inner version because it needs to be somewhat
14366 * decoupled from the AM-managed cleanup lifecycle
14368 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14369 ApplicationErrorReport.CrashInfo crashInfo) {
14370 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14371 UserHandle.getUserId(Binder.getCallingUid()), processName,
14372 r == null ? -1 : r.info.flags,
14373 crashInfo.exceptionClassName,
14374 crashInfo.exceptionMessage,
14375 crashInfo.throwFileName,
14376 crashInfo.throwLineNumber);
14378 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14380 mAppErrors.crashApplication(r, crashInfo);
14383 public void handleApplicationStrictModeViolation(
14386 StrictMode.ViolationInfo info) {
14387 ProcessRecord r = findAppProcess(app, "StrictMode");
14392 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14393 Integer stackFingerprint = info.hashCode();
14394 boolean logIt = true;
14395 synchronized (mAlreadyLoggedViolatedStacks) {
14396 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14398 // TODO: sub-sample into EventLog for these, with
14399 // the info.durationMillis? Then we'd get
14400 // the relative pain numbers, without logging all
14401 // the stack traces repeatedly. We'd want to do
14402 // likewise in the client code, which also does
14403 // dup suppression, before the Binder call.
14405 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14406 mAlreadyLoggedViolatedStacks.clear();
14408 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14412 logStrictModeViolationToDropBox(r, info);
14416 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14417 AppErrorResult result = new AppErrorResult();
14418 synchronized (this) {
14419 final long origId = Binder.clearCallingIdentity();
14421 Message msg = Message.obtain();
14422 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14423 HashMap<String, Object> data = new HashMap<String, Object>();
14424 data.put("result", result);
14425 data.put("app", r);
14426 data.put("violationMask", violationMask);
14427 data.put("info", info);
14429 mUiHandler.sendMessage(msg);
14431 Binder.restoreCallingIdentity(origId);
14433 int res = result.get();
14434 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14438 // Depending on the policy in effect, there could be a bunch of
14439 // these in quick succession so we try to batch these together to
14440 // minimize disk writes, number of dropbox entries, and maximize
14441 // compression, by having more fewer, larger records.
14442 private void logStrictModeViolationToDropBox(
14443 ProcessRecord process,
14444 StrictMode.ViolationInfo info) {
14445 if (info == null) {
14448 final boolean isSystemApp = process == null ||
14449 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14450 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14451 final String processName = process == null ? "unknown" : process.processName;
14452 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14453 final DropBoxManager dbox = (DropBoxManager)
14454 mContext.getSystemService(Context.DROPBOX_SERVICE);
14456 // Exit early if the dropbox isn't configured to accept this report type.
14457 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14459 boolean bufferWasEmpty;
14460 boolean needsFlush;
14461 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14462 synchronized (sb) {
14463 bufferWasEmpty = sb.length() == 0;
14464 appendDropBoxProcessHeaders(process, processName, sb);
14465 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14466 sb.append("System-App: ").append(isSystemApp).append("\n");
14467 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14468 if (info.violationNumThisLoop != 0) {
14469 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14471 if (info.numAnimationsRunning != 0) {
14472 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14474 if (info.broadcastIntentAction != null) {
14475 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14477 if (info.durationMillis != -1) {
14478 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14480 if (info.numInstances != -1) {
14481 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14483 if (info.tags != null) {
14484 for (String tag : info.tags) {
14485 sb.append("Span-Tag: ").append(tag).append("\n");
14489 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14490 sb.append(info.crashInfo.stackTrace);
14493 if (info.message != null) {
14494 sb.append(info.message);
14498 // Only buffer up to ~64k. Various logging bits truncate
14500 needsFlush = (sb.length() > 64 * 1024);
14503 // Flush immediately if the buffer's grown too large, or this
14504 // is a non-system app. Non-system apps are isolated with a
14505 // different tag & policy and not batched.
14507 // Batching is useful during internal testing with
14508 // StrictMode settings turned up high. Without batching,
14509 // thousands of separate files could be created on boot.
14510 if (!isSystemApp || needsFlush) {
14511 new Thread("Error dump: " + dropboxTag) {
14513 public void run() {
14515 synchronized (sb) {
14516 report = sb.toString();
14517 sb.delete(0, sb.length());
14520 if (report.length() != 0) {
14521 dbox.addText(dropboxTag, report);
14528 // System app batching:
14529 if (!bufferWasEmpty) {
14530 // An existing dropbox-writing thread is outstanding, so
14531 // we don't need to start it up. The existing thread will
14532 // catch the buffer appends we just did.
14536 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14537 // (After this point, we shouldn't access AMS internal data structures.)
14538 new Thread("Error dump: " + dropboxTag) {
14540 public void run() {
14541 // 5 second sleep to let stacks arrive and be batched together
14543 Thread.sleep(5000); // 5 seconds
14544 } catch (InterruptedException e) {}
14546 String errorReport;
14547 synchronized (mStrictModeBuffer) {
14548 errorReport = mStrictModeBuffer.toString();
14549 if (errorReport.length() == 0) {
14552 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14553 mStrictModeBuffer.trimToSize();
14555 dbox.addText(dropboxTag, errorReport);
14561 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14562 * @param app object of the crashing app, null for the system server
14563 * @param tag reported by the caller
14564 * @param system whether this wtf is coming from the system
14565 * @param crashInfo describing the context of the error
14566 * @return true if the process should exit immediately (WTF is fatal)
14568 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14569 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14570 final int callingUid = Binder.getCallingUid();
14571 final int callingPid = Binder.getCallingPid();
14574 // If this is coming from the system, we could very well have low-level
14575 // system locks held, so we want to do this all asynchronously. And we
14576 // never want this to become fatal, so there is that too.
14577 mHandler.post(new Runnable() {
14578 @Override public void run() {
14579 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14585 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14588 final boolean isFatal = Build.IS_ENG || Settings.Global
14589 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14590 final boolean isSystem = (r == null) || r.persistent;
14592 if (isFatal && !isSystem) {
14593 mAppErrors.crashApplication(r, crashInfo);
14600 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14601 final ApplicationErrorReport.CrashInfo crashInfo) {
14602 final ProcessRecord r = findAppProcess(app, "WTF");
14603 final String processName = app == null ? "system_server"
14604 : (r == null ? "unknown" : r.processName);
14606 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14607 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14609 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14615 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14616 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14618 private ProcessRecord findAppProcess(IBinder app, String reason) {
14623 synchronized (this) {
14624 final int NP = mProcessNames.getMap().size();
14625 for (int ip=0; ip<NP; ip++) {
14626 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14627 final int NA = apps.size();
14628 for (int ia=0; ia<NA; ia++) {
14629 ProcessRecord p = apps.valueAt(ia);
14630 if (p.thread != null && p.thread.asBinder() == app) {
14636 Slog.w(TAG, "Can't find mystery application for " + reason
14637 + " from pid=" + Binder.getCallingPid()
14638 + " uid=" + Binder.getCallingUid() + ": " + app);
14644 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14645 * to append various headers to the dropbox log text.
14647 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14648 StringBuilder sb) {
14649 // Watchdog thread ends up invoking this function (with
14650 // a null ProcessRecord) to add the stack file to dropbox.
14651 // Do not acquire a lock on this (am) in such cases, as it
14652 // could cause a potential deadlock, if and when watchdog
14653 // is invoked due to unavailability of lock on am and it
14654 // would prevent watchdog from killing system_server.
14655 if (process == null) {
14656 sb.append("Process: ").append(processName).append("\n");
14659 // Note: ProcessRecord 'process' is guarded by the service
14660 // instance. (notably process.pkgList, which could otherwise change
14661 // concurrently during execution of this method)
14662 synchronized (this) {
14663 sb.append("Process: ").append(processName).append("\n");
14664 sb.append("PID: ").append(process.pid).append("\n");
14665 int flags = process.info.flags;
14666 IPackageManager pm = AppGlobals.getPackageManager();
14667 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14668 for (int ip=0; ip<process.pkgList.size(); ip++) {
14669 String pkg = process.pkgList.keyAt(ip);
14670 sb.append("Package: ").append(pkg);
14672 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14674 sb.append(" v").append(pi.versionCode);
14675 if (pi.versionName != null) {
14676 sb.append(" (").append(pi.versionName).append(")");
14679 } catch (RemoteException e) {
14680 Slog.e(TAG, "Error getting package info: " + pkg, e);
14684 if (process.info.isInstantApp()) {
14685 sb.append("Instant-App: true\n");
14690 private static String processClass(ProcessRecord process) {
14691 if (process == null || process.pid == MY_PID) {
14692 return "system_server";
14693 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14694 return "system_app";
14700 private volatile long mWtfClusterStart;
14701 private volatile int mWtfClusterCount;
14704 * Write a description of an error (crash, WTF, ANR) to the drop box.
14705 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14706 * @param process which caused the error, null means the system server
14707 * @param activity which triggered the error, null if unknown
14708 * @param parent activity related to the error, null if unknown
14709 * @param subject line related to the error, null if absent
14710 * @param report in long form describing the error, null if absent
14711 * @param dataFile text file to include in the report, null if none
14712 * @param crashInfo giving an application stack trace, null if absent
14714 public void addErrorToDropBox(String eventType,
14715 ProcessRecord process, String processName, ActivityRecord activity,
14716 ActivityRecord parent, String subject,
14717 final String report, final File dataFile,
14718 final ApplicationErrorReport.CrashInfo crashInfo) {
14719 // NOTE -- this must never acquire the ActivityManagerService lock,
14720 // otherwise the watchdog may be prevented from resetting the system.
14722 // Bail early if not published yet
14723 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14724 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14726 // Exit early if the dropbox isn't configured to accept this report type.
14727 final String dropboxTag = processClass(process) + "_" + eventType;
14728 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14730 // Rate-limit how often we're willing to do the heavy lifting below to
14731 // collect and record logs; currently 5 logs per 10 second period.
14732 final long now = SystemClock.elapsedRealtime();
14733 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14734 mWtfClusterStart = now;
14735 mWtfClusterCount = 1;
14737 if (mWtfClusterCount++ >= 5) return;
14740 final StringBuilder sb = new StringBuilder(1024);
14741 appendDropBoxProcessHeaders(process, processName, sb);
14742 if (process != null) {
14743 sb.append("Foreground: ")
14744 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14747 if (activity != null) {
14748 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14750 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14751 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14753 if (parent != null && parent != activity) {
14754 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14756 if (subject != null) {
14757 sb.append("Subject: ").append(subject).append("\n");
14759 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14760 if (Debug.isDebuggerConnected()) {
14761 sb.append("Debugger: Connected\n");
14765 // Do the rest in a worker thread to avoid blocking the caller on I/O
14766 // (After this point, we shouldn't access AMS internal data structures.)
14767 Thread worker = new Thread("Error dump: " + dropboxTag) {
14769 public void run() {
14770 if (report != null) {
14774 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14775 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14776 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14777 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14779 if (dataFile != null && maxDataFileSize > 0) {
14781 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14782 "\n\n[[TRUNCATED]]"));
14783 } catch (IOException e) {
14784 Slog.e(TAG, "Error reading " + dataFile, e);
14787 if (crashInfo != null && crashInfo.stackTrace != null) {
14788 sb.append(crashInfo.stackTrace);
14794 // Merge several logcat streams, and take the last N lines
14795 InputStreamReader input = null;
14797 java.lang.Process logcat = new ProcessBuilder(
14798 "/system/bin/timeout", "-k", "15s", "10s",
14799 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14800 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14801 .redirectErrorStream(true).start();
14803 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14804 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14805 input = new InputStreamReader(logcat.getInputStream());
14808 char[] buf = new char[8192];
14809 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14810 } catch (IOException e) {
14811 Slog.e(TAG, "Error running logcat", e);
14813 if (input != null) try { input.close(); } catch (IOException e) {}
14817 dbox.addText(dropboxTag, sb.toString());
14821 if (process == null) {
14822 // If process is null, we are being called from some internal code
14823 // and may be about to die -- run this synchronously.
14831 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14832 enforceNotIsolatedCaller("getProcessesInErrorState");
14833 // assume our apps are happy - lazy create the list
14834 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14836 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14837 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14838 int userId = UserHandle.getUserId(Binder.getCallingUid());
14840 synchronized (this) {
14842 // iterate across all processes
14843 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14844 ProcessRecord app = mLruProcesses.get(i);
14845 if (!allUsers && app.userId != userId) {
14848 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14849 // This one's in trouble, so we'll generate a report for it
14850 // crashes are higher priority (in case there's a crash *and* an anr)
14851 ActivityManager.ProcessErrorStateInfo report = null;
14852 if (app.crashing) {
14853 report = app.crashingReport;
14854 } else if (app.notResponding) {
14855 report = app.notRespondingReport;
14858 if (report != null) {
14859 if (errList == null) {
14860 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14862 errList.add(report);
14864 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14865 " crashing = " + app.crashing +
14866 " notResponding = " + app.notResponding);
14875 static int procStateToImportance(int procState, int memAdj,
14876 ActivityManager.RunningAppProcessInfo currApp,
14877 int clientTargetSdk) {
14878 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14879 procState, clientTargetSdk);
14880 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14881 currApp.lru = memAdj;
14888 private void fillInProcMemInfo(ProcessRecord app,
14889 ActivityManager.RunningAppProcessInfo outInfo,
14890 int clientTargetSdk) {
14891 outInfo.pid = app.pid;
14892 outInfo.uid = app.info.uid;
14893 if (mHeavyWeightProcess == app) {
14894 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14896 if (app.persistent) {
14897 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14899 if (app.activities.size() > 0) {
14900 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14902 outInfo.lastTrimLevel = app.trimMemoryLevel;
14903 int adj = app.curAdj;
14904 int procState = app.curProcState;
14905 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14906 outInfo.importanceReasonCode = app.adjTypeCode;
14907 outInfo.processState = app.curProcState;
14911 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14912 enforceNotIsolatedCaller("getRunningAppProcesses");
14914 final int callingUid = Binder.getCallingUid();
14915 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14917 // Lazy instantiation of list
14918 List<ActivityManager.RunningAppProcessInfo> runList = null;
14919 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14920 callingUid) == PackageManager.PERMISSION_GRANTED;
14921 final int userId = UserHandle.getUserId(callingUid);
14922 final boolean allUids = isGetTasksAllowed(
14923 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14925 synchronized (this) {
14926 // Iterate across all processes
14927 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14928 ProcessRecord app = mLruProcesses.get(i);
14929 if ((!allUsers && app.userId != userId)
14930 || (!allUids && app.uid != callingUid)) {
14933 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14934 // Generate process state info for running application
14935 ActivityManager.RunningAppProcessInfo currApp =
14936 new ActivityManager.RunningAppProcessInfo(app.processName,
14937 app.pid, app.getPackageList());
14938 fillInProcMemInfo(app, currApp, clientTargetSdk);
14939 if (app.adjSource instanceof ProcessRecord) {
14940 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14941 currApp.importanceReasonImportance =
14942 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14943 app.adjSourceProcState);
14944 } else if (app.adjSource instanceof ActivityRecord) {
14945 ActivityRecord r = (ActivityRecord)app.adjSource;
14946 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14948 if (app.adjTarget instanceof ComponentName) {
14949 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14951 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14952 // + " lru=" + currApp.lru);
14953 if (runList == null) {
14954 runList = new ArrayList<>();
14956 runList.add(currApp);
14964 public List<ApplicationInfo> getRunningExternalApplications() {
14965 enforceNotIsolatedCaller("getRunningExternalApplications");
14966 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14967 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14968 if (runningApps != null && runningApps.size() > 0) {
14969 Set<String> extList = new HashSet<String>();
14970 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14971 if (app.pkgList != null) {
14972 for (String pkg : app.pkgList) {
14977 IPackageManager pm = AppGlobals.getPackageManager();
14978 for (String pkg : extList) {
14980 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14981 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14984 } catch (RemoteException e) {
14992 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14993 enforceNotIsolatedCaller("getMyMemoryState");
14995 final int callingUid = Binder.getCallingUid();
14996 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14998 synchronized (this) {
14999 ProcessRecord proc;
15000 synchronized (mPidsSelfLocked) {
15001 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15003 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15008 public int getMemoryTrimLevel() {
15009 enforceNotIsolatedCaller("getMyMemoryState");
15010 synchronized (this) {
15011 return mLastMemoryLevel;
15016 public void onShellCommand(FileDescriptor in, FileDescriptor out,
15017 FileDescriptor err, String[] args, ShellCallback callback,
15018 ResultReceiver resultReceiver) {
15019 (new ActivityManagerShellCommand(this, false)).exec(
15020 this, in, out, err, args, callback, resultReceiver);
15023 SleepToken acquireSleepToken(String tag, int displayId) {
15024 synchronized (this) {
15025 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15026 updateSleepIfNeededLocked();
15032 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15033 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15035 boolean dumpAll = false;
15036 boolean dumpClient = false;
15037 boolean dumpCheckin = false;
15038 boolean dumpCheckinFormat = false;
15039 boolean dumpVisibleStacksOnly = false;
15040 boolean dumpFocusedStackOnly = false;
15041 String dumpPackage = null;
15044 while (opti < args.length) {
15045 String opt = args[opti];
15046 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15050 if ("-a".equals(opt)) {
15052 } else if ("-c".equals(opt)) {
15054 } else if ("-v".equals(opt)) {
15055 dumpVisibleStacksOnly = true;
15056 } else if ("-f".equals(opt)) {
15057 dumpFocusedStackOnly = true;
15058 } else if ("-p".equals(opt)) {
15059 if (opti < args.length) {
15060 dumpPackage = args[opti];
15063 pw.println("Error: -p option requires package argument");
15067 } else if ("--checkin".equals(opt)) {
15068 dumpCheckin = dumpCheckinFormat = true;
15069 } else if ("-C".equals(opt)) {
15070 dumpCheckinFormat = true;
15071 } else if ("-h".equals(opt)) {
15072 ActivityManagerShellCommand.dumpHelp(pw, true);
15075 pw.println("Unknown argument: " + opt + "; use -h for help");
15079 long origId = Binder.clearCallingIdentity();
15080 boolean more = false;
15081 // Is the caller requesting to dump a particular piece of data?
15082 if (opti < args.length) {
15083 String cmd = args[opti];
15085 if ("activities".equals(cmd) || "a".equals(cmd)) {
15086 synchronized (this) {
15087 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15089 } else if ("lastanr".equals(cmd)) {
15090 synchronized (this) {
15091 dumpLastANRLocked(pw);
15093 } else if ("starter".equals(cmd)) {
15094 synchronized (this) {
15095 dumpActivityStarterLocked(pw, dumpPackage);
15097 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15098 synchronized (this) {
15099 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15101 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15104 if (opti >= args.length) {
15106 newArgs = EMPTY_STRING_ARRAY;
15108 dumpPackage = args[opti];
15110 newArgs = new String[args.length - opti];
15111 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15112 args.length - opti);
15114 synchronized (this) {
15115 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15117 } else if ("broadcast-stats".equals(cmd)) {
15120 if (opti >= args.length) {
15122 newArgs = EMPTY_STRING_ARRAY;
15124 dumpPackage = args[opti];
15126 newArgs = new String[args.length - opti];
15127 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15128 args.length - opti);
15130 synchronized (this) {
15131 if (dumpCheckinFormat) {
15132 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15135 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15138 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15141 if (opti >= args.length) {
15143 newArgs = EMPTY_STRING_ARRAY;
15145 dumpPackage = args[opti];
15147 newArgs = new String[args.length - opti];
15148 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15149 args.length - opti);
15151 synchronized (this) {
15152 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15154 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15157 if (opti >= args.length) {
15159 newArgs = EMPTY_STRING_ARRAY;
15161 dumpPackage = args[opti];
15163 newArgs = new String[args.length - opti];
15164 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15165 args.length - opti);
15167 synchronized (this) {
15168 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15170 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15171 synchronized (this) {
15172 dumpOomLocked(fd, pw, args, opti, true);
15174 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15175 synchronized (this) {
15176 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15178 } else if ("provider".equals(cmd)) {
15181 if (opti >= args.length) {
15183 newArgs = EMPTY_STRING_ARRAY;
15187 newArgs = new String[args.length - opti];
15188 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15190 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15191 pw.println("No providers match: " + name);
15192 pw.println("Use -h for help.");
15194 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15195 synchronized (this) {
15196 dumpProvidersLocked(fd, pw, args, opti, true, null);
15198 } else if ("service".equals(cmd)) {
15201 if (opti >= args.length) {
15203 newArgs = EMPTY_STRING_ARRAY;
15207 newArgs = new String[args.length - opti];
15208 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15209 args.length - opti);
15211 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15212 pw.println("No services match: " + name);
15213 pw.println("Use -h for help.");
15215 } else if ("package".equals(cmd)) {
15217 if (opti >= args.length) {
15218 pw.println("package: no package name specified");
15219 pw.println("Use -h for help.");
15221 dumpPackage = args[opti];
15223 newArgs = new String[args.length - opti];
15224 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15225 args.length - opti);
15230 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15231 synchronized (this) {
15232 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15234 } else if ("settings".equals(cmd)) {
15235 synchronized (this) {
15236 mConstants.dump(pw);
15238 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15240 ActiveServices.ServiceDumper dumper;
15241 synchronized (this) {
15242 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15245 dumper.dumpWithClient();
15247 synchronized (this) {
15248 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15249 dumpPackage).dumpLocked();
15252 } else if ("locks".equals(cmd)) {
15253 LockGuard.dump(fd, pw, args);
15255 // Dumping a single activity?
15256 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15257 dumpFocusedStackOnly)) {
15258 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15259 int res = shell.exec(this, null, fd, null, args, null,
15260 new ResultReceiver(null));
15262 pw.println("Bad activity command, or no activities match: " + cmd);
15263 pw.println("Use -h for help.");
15268 Binder.restoreCallingIdentity(origId);
15273 // No piece of data specified, dump everything.
15274 if (dumpCheckinFormat) {
15275 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15276 } else if (dumpClient) {
15277 ActiveServices.ServiceDumper sdumper;
15278 synchronized (this) {
15279 mConstants.dump(pw);
15282 pw.println("-------------------------------------------------------------------------------");
15284 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15287 pw.println("-------------------------------------------------------------------------------");
15289 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15292 pw.println("-------------------------------------------------------------------------------");
15294 if (dumpAll || dumpPackage != null) {
15295 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15298 pw.println("-------------------------------------------------------------------------------");
15301 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15304 pw.println("-------------------------------------------------------------------------------");
15306 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15309 pw.println("-------------------------------------------------------------------------------");
15311 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15314 sdumper.dumpWithClient();
15316 synchronized (this) {
15318 pw.println("-------------------------------------------------------------------------------");
15320 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15323 pw.println("-------------------------------------------------------------------------------");
15325 dumpLastANRLocked(pw);
15328 pw.println("-------------------------------------------------------------------------------");
15330 dumpActivityStarterLocked(pw, dumpPackage);
15333 pw.println("-------------------------------------------------------------------------------");
15335 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15336 if (mAssociations.size() > 0) {
15339 pw.println("-------------------------------------------------------------------------------");
15341 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15345 pw.println("-------------------------------------------------------------------------------");
15347 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15351 synchronized (this) {
15352 mConstants.dump(pw);
15355 pw.println("-------------------------------------------------------------------------------");
15357 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15360 pw.println("-------------------------------------------------------------------------------");
15362 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15365 pw.println("-------------------------------------------------------------------------------");
15367 if (dumpAll || dumpPackage != null) {
15368 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15371 pw.println("-------------------------------------------------------------------------------");
15374 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15377 pw.println("-------------------------------------------------------------------------------");
15379 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15382 pw.println("-------------------------------------------------------------------------------");
15384 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15388 pw.println("-------------------------------------------------------------------------------");
15390 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15393 pw.println("-------------------------------------------------------------------------------");
15395 dumpLastANRLocked(pw);
15398 pw.println("-------------------------------------------------------------------------------");
15400 dumpActivityStarterLocked(pw, dumpPackage);
15403 pw.println("-------------------------------------------------------------------------------");
15405 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15406 if (mAssociations.size() > 0) {
15409 pw.println("-------------------------------------------------------------------------------");
15411 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15415 pw.println("-------------------------------------------------------------------------------");
15417 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15420 Binder.restoreCallingIdentity(origId);
15423 private void dumpLastANRLocked(PrintWriter pw) {
15424 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15425 if (mLastANRState == null) {
15426 pw.println(" <no ANR has occurred since boot>");
15428 pw.println(mLastANRState);
15432 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15433 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15434 mActivityStarter.dump(pw, "", dumpPackage);
15437 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15438 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15439 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15440 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15443 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15444 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15445 pw.println(header);
15447 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15449 boolean needSep = printedAnything;
15451 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15452 mStackSupervisor.getResumedActivityLocked(),
15453 dumpPackage, needSep, " ResumedActivity: ");
15455 printedAnything = true;
15459 if (dumpPackage == null) {
15463 printedAnything = true;
15464 mStackSupervisor.dump(pw, " ");
15467 if (!printedAnything) {
15468 pw.println(" (nothing)");
15472 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15473 int opti, boolean dumpAll, String dumpPackage) {
15474 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15476 boolean printedAnything = false;
15478 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15479 boolean printedHeader = false;
15481 final int N = mRecentTasks.size();
15482 for (int i=0; i<N; i++) {
15483 TaskRecord tr = mRecentTasks.get(i);
15484 if (dumpPackage != null) {
15485 if (tr.realActivity == null ||
15486 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15490 if (!printedHeader) {
15491 pw.println(" Recent tasks:");
15492 printedHeader = true;
15493 printedAnything = true;
15495 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15498 mRecentTasks.get(i).dump(pw, " ");
15503 if (!printedAnything) {
15504 pw.println(" (nothing)");
15508 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15509 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15510 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15513 if (dumpPackage != null) {
15514 IPackageManager pm = AppGlobals.getPackageManager();
15516 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15517 } catch (RemoteException e) {
15521 boolean printedAnything = false;
15523 final long now = SystemClock.uptimeMillis();
15525 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15526 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15527 = mAssociations.valueAt(i1);
15528 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15529 SparseArray<ArrayMap<String, Association>> sourceUids
15530 = targetComponents.valueAt(i2);
15531 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15532 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15533 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15534 Association ass = sourceProcesses.valueAt(i4);
15535 if (dumpPackage != null) {
15536 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15537 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15541 printedAnything = true;
15543 pw.print(ass.mTargetProcess);
15545 UserHandle.formatUid(pw, ass.mTargetUid);
15547 pw.print(ass.mSourceProcess);
15549 UserHandle.formatUid(pw, ass.mSourceUid);
15552 pw.print(ass.mTargetComponent.flattenToShortString());
15555 long dur = ass.mTime;
15556 if (ass.mNesting > 0) {
15557 dur += now - ass.mStartTime;
15559 TimeUtils.formatDuration(dur, pw);
15561 pw.print(ass.mCount);
15562 pw.print(" times)");
15564 for (int i=0; i<ass.mStateTimes.length; i++) {
15565 long amt = ass.mStateTimes[i];
15566 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15567 amt += now - ass.mLastStateUptime;
15571 pw.print(ProcessList.makeProcStateString(
15572 i + ActivityManager.MIN_PROCESS_STATE));
15574 TimeUtils.formatDuration(amt, pw);
15575 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15581 if (ass.mNesting > 0) {
15582 pw.print(" Currently active: ");
15583 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15592 if (!printedAnything) {
15593 pw.println(" (nothing)");
15597 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15598 String header, boolean needSep) {
15599 boolean printed = false;
15600 int whichAppId = -1;
15601 if (dumpPackage != null) {
15603 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15605 whichAppId = UserHandle.getAppId(info.uid);
15606 } catch (NameNotFoundException e) {
15607 e.printStackTrace();
15610 for (int i=0; i<uids.size(); i++) {
15611 UidRecord uidRec = uids.valueAt(i);
15612 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15621 pw.println(header);
15624 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15625 pw.print(": "); pw.println(uidRec);
15630 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15631 int opti, boolean dumpAll, String dumpPackage) {
15632 boolean needSep = false;
15633 boolean printedAnything = false;
15636 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15639 final int NP = mProcessNames.getMap().size();
15640 for (int ip=0; ip<NP; ip++) {
15641 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15642 final int NA = procs.size();
15643 for (int ia=0; ia<NA; ia++) {
15644 ProcessRecord r = procs.valueAt(ia);
15645 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15649 pw.println(" All known processes:");
15651 printedAnything = true;
15653 pw.print(r.persistent ? " *PERS*" : " *APP*");
15654 pw.print(" UID "); pw.print(procs.keyAt(ia));
15655 pw.print(" "); pw.println(r);
15657 if (r.persistent) {
15664 if (mIsolatedProcesses.size() > 0) {
15665 boolean printed = false;
15666 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15667 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15668 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15675 pw.println(" Isolated process list (sorted by uid):");
15676 printedAnything = true;
15680 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15685 if (mActiveInstrumentation.size() > 0) {
15686 boolean printed = false;
15687 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15688 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15689 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15690 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15697 pw.println(" Active instrumentation:");
15698 printedAnything = true;
15702 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15708 if (mActiveUids.size() > 0) {
15709 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15710 printedAnything = needSep = true;
15714 if (mValidateUids.size() > 0) {
15715 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15716 printedAnything = needSep = true;
15721 if (mLruProcesses.size() > 0) {
15725 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15726 pw.print(" total, non-act at ");
15727 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15728 pw.print(", non-svc at ");
15729 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15731 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15733 printedAnything = true;
15736 if (dumpAll || dumpPackage != null) {
15737 synchronized (mPidsSelfLocked) {
15738 boolean printed = false;
15739 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15740 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15741 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15745 if (needSep) pw.println();
15747 pw.println(" PID mappings:");
15749 printedAnything = true;
15751 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15752 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15757 if (mImportantProcesses.size() > 0) {
15758 synchronized (mPidsSelfLocked) {
15759 boolean printed = false;
15760 for (int i = 0; i< mImportantProcesses.size(); i++) {
15761 ProcessRecord r = mPidsSelfLocked.get(
15762 mImportantProcesses.valueAt(i).pid);
15763 if (dumpPackage != null && (r == null
15764 || !r.pkgList.containsKey(dumpPackage))) {
15768 if (needSep) pw.println();
15770 pw.println(" Foreground Processes:");
15772 printedAnything = true;
15774 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15775 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15780 if (mPersistentStartingProcesses.size() > 0) {
15781 if (needSep) pw.println();
15783 printedAnything = true;
15784 pw.println(" Persisent processes that are starting:");
15785 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15786 "Starting Norm", "Restarting PERS", dumpPackage);
15789 if (mRemovedProcesses.size() > 0) {
15790 if (needSep) pw.println();
15792 printedAnything = true;
15793 pw.println(" Processes that are being removed:");
15794 dumpProcessList(pw, this, mRemovedProcesses, " ",
15795 "Removed Norm", "Removed PERS", dumpPackage);
15798 if (mProcessesOnHold.size() > 0) {
15799 if (needSep) pw.println();
15801 printedAnything = true;
15802 pw.println(" Processes that are on old until the system is ready:");
15803 dumpProcessList(pw, this, mProcessesOnHold, " ",
15804 "OnHold Norm", "OnHold PERS", dumpPackage);
15807 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15809 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15811 printedAnything = true;
15814 if (dumpPackage == null) {
15817 mUserController.dump(pw, dumpAll);
15819 if (mHomeProcess != null && (dumpPackage == null
15820 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15825 pw.println(" mHomeProcess: " + mHomeProcess);
15827 if (mPreviousProcess != null && (dumpPackage == null
15828 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15833 pw.println(" mPreviousProcess: " + mPreviousProcess);
15836 StringBuilder sb = new StringBuilder(128);
15837 sb.append(" mPreviousProcessVisibleTime: ");
15838 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15841 if (mHeavyWeightProcess != null && (dumpPackage == null
15842 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15847 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15849 if (dumpPackage == null) {
15850 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15851 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15854 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15855 if (mCompatModePackages.getPackages().size() > 0) {
15856 boolean printed = false;
15857 for (Map.Entry<String, Integer> entry
15858 : mCompatModePackages.getPackages().entrySet()) {
15859 String pkg = entry.getKey();
15860 int mode = entry.getValue();
15861 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15865 pw.println(" mScreenCompatPackages:");
15868 pw.print(" "); pw.print(pkg); pw.print(": ");
15869 pw.print(mode); pw.println();
15872 final int NI = mUidObservers.getRegisteredCallbackCount();
15873 boolean printed = false;
15874 for (int i=0; i<NI; i++) {
15875 final UidObserverRegistration reg = (UidObserverRegistration)
15876 mUidObservers.getRegisteredCallbackCookie(i);
15877 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15879 pw.println(" mUidObservers:");
15882 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15883 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15884 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15887 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15890 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15893 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15894 pw.print(" STATE");
15895 pw.print(" (cut="); pw.print(reg.cutpoint);
15899 if (reg.lastProcStates != null) {
15900 final int NJ = reg.lastProcStates.size();
15901 for (int j=0; j<NJ; j++) {
15902 pw.print(" Last ");
15903 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15904 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15909 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15910 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15911 if (mPendingTempWhitelist.size() > 0) {
15912 pw.println(" mPendingTempWhitelist:");
15913 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15914 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15916 UserHandle.formatUid(pw, ptw.targetUid);
15918 TimeUtils.formatDuration(ptw.duration, pw);
15920 pw.println(ptw.tag);
15924 if (dumpPackage == null) {
15925 pw.println(" mWakefulness="
15926 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15927 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
15928 pw.println(" mSleeping=" + mSleeping);
15929 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15930 if (mRunningVoice != null) {
15931 pw.println(" mRunningVoice=" + mRunningVoice);
15932 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15935 pw.println(" mVrController=" + mVrController);
15936 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15937 || mOrigWaitForDebugger) {
15938 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15939 || dumpPackage.equals(mOrigDebugApp)) {
15944 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15945 + " mDebugTransient=" + mDebugTransient
15946 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15949 if (mCurAppTimeTracker != null) {
15950 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15952 if (mMemWatchProcesses.getMap().size() > 0) {
15953 pw.println(" Mem watch processes:");
15954 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15955 = mMemWatchProcesses.getMap();
15956 for (int i=0; i<procs.size(); i++) {
15957 final String proc = procs.keyAt(i);
15958 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15959 for (int j=0; j<uids.size(); j++) {
15964 StringBuilder sb = new StringBuilder();
15965 sb.append(" ").append(proc).append('/');
15966 UserHandle.formatUid(sb, uids.keyAt(j));
15967 Pair<Long, String> val = uids.valueAt(j);
15968 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15969 if (val.second != null) {
15970 sb.append(", report to ").append(val.second);
15972 pw.println(sb.toString());
15975 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15976 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15977 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15978 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15980 if (mTrackAllocationApp != null) {
15981 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15986 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15989 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15990 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15991 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15996 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15997 if (mProfilerInfo != null) {
15998 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
15999 mProfilerInfo.profileFd);
16000 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
16001 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16002 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16003 pw.println(" mProfileType=" + mProfileType);
16007 if (mNativeDebuggingApp != null) {
16008 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16013 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
16016 if (dumpPackage == null) {
16017 if (mAlwaysFinishActivities) {
16018 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16020 if (mController != null) {
16021 pw.println(" mController=" + mController
16022 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16025 pw.println(" Total persistent processes: " + numPers);
16026 pw.println(" mProcessesReady=" + mProcessesReady
16027 + " mSystemReady=" + mSystemReady
16028 + " mBooted=" + mBooted
16029 + " mFactoryTest=" + mFactoryTest);
16030 pw.println(" mBooting=" + mBooting
16031 + " mCallFinishBooting=" + mCallFinishBooting
16032 + " mBootAnimationComplete=" + mBootAnimationComplete);
16033 pw.print(" mLastPowerCheckUptime=");
16034 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16036 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16037 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16038 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16039 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
16040 + " (" + mLruProcesses.size() + " total)"
16041 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16042 + " mNumServiceProcs=" + mNumServiceProcs
16043 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16044 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
16045 + " mLastMemoryLevel=" + mLastMemoryLevel
16046 + " mLastNumProcesses=" + mLastNumProcesses);
16047 long now = SystemClock.uptimeMillis();
16048 pw.print(" mLastIdleTime=");
16049 TimeUtils.formatDuration(now, mLastIdleTime, pw);
16050 pw.print(" mLowRamSinceLastIdle=");
16051 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16056 if (!printedAnything) {
16057 pw.println(" (nothing)");
16061 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16062 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16063 if (mProcessesToGc.size() > 0) {
16064 boolean printed = false;
16065 long now = SystemClock.uptimeMillis();
16066 for (int i=0; i<mProcessesToGc.size(); i++) {
16067 ProcessRecord proc = mProcessesToGc.get(i);
16068 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16072 if (needSep) pw.println();
16074 pw.println(" Processes that are waiting to GC:");
16077 pw.print(" Process "); pw.println(proc);
16078 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16079 pw.print(", last gced=");
16080 pw.print(now-proc.lastRequestedGc);
16081 pw.print(" ms ago, last lowMem=");
16082 pw.print(now-proc.lastLowMemory);
16083 pw.println(" ms ago");
16090 void printOomLevel(PrintWriter pw, String name, int adj) {
16094 if (adj < 10) pw.print(' ');
16096 if (adj > -10) pw.print(' ');
16102 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16106 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16107 int opti, boolean dumpAll) {
16108 boolean needSep = false;
16110 if (mLruProcesses.size() > 0) {
16111 if (needSep) pw.println();
16113 pw.println(" OOM levels:");
16114 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16115 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16116 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16117 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16118 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16119 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16120 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16121 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16122 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16123 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16124 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16125 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16126 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16127 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16129 if (needSep) pw.println();
16130 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16131 pw.print(" total, non-act at ");
16132 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16133 pw.print(", non-svc at ");
16134 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16136 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16140 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16143 pw.println(" mHomeProcess: " + mHomeProcess);
16144 pw.println(" mPreviousProcess: " + mPreviousProcess);
16145 if (mHeavyWeightProcess != null) {
16146 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16153 * There are three ways to call this:
16154 * - no provider specified: dump all the providers
16155 * - a flattened component name that matched an existing provider was specified as the
16156 * first arg: dump that one provider
16157 * - the first arg isn't the flattened component name of an existing provider:
16158 * dump all providers whose component contains the first arg as a substring
16160 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16161 int opti, boolean dumpAll) {
16162 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16165 static class ItemMatcher {
16166 ArrayList<ComponentName> components;
16167 ArrayList<String> strings;
16168 ArrayList<Integer> objects;
16175 void build(String name) {
16176 ComponentName componentName = ComponentName.unflattenFromString(name);
16177 if (componentName != null) {
16178 if (components == null) {
16179 components = new ArrayList<ComponentName>();
16181 components.add(componentName);
16185 // Not a '/' separated full component name; maybe an object ID?
16187 objectId = Integer.parseInt(name, 16);
16188 if (objects == null) {
16189 objects = new ArrayList<Integer>();
16191 objects.add(objectId);
16193 } catch (RuntimeException e) {
16194 // Not an integer; just do string match.
16195 if (strings == null) {
16196 strings = new ArrayList<String>();
16204 int build(String[] args, int opti) {
16205 for (; opti<args.length; opti++) {
16206 String name = args[opti];
16207 if ("--".equals(name)) {
16215 boolean match(Object object, ComponentName comp) {
16219 if (components != null) {
16220 for (int i=0; i<components.size(); i++) {
16221 if (components.get(i).equals(comp)) {
16226 if (objects != null) {
16227 for (int i=0; i<objects.size(); i++) {
16228 if (System.identityHashCode(object) == objects.get(i)) {
16233 if (strings != null) {
16234 String flat = comp.flattenToString();
16235 for (int i=0; i<strings.size(); i++) {
16236 if (flat.contains(strings.get(i))) {
16246 * There are three things that cmd can be:
16247 * - a flattened component name that matches an existing activity
16248 * - the cmd arg isn't the flattened component name of an existing activity:
16249 * dump all activity whose component contains the cmd as a substring
16250 * - A hex number of the ActivityRecord object instance.
16252 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16253 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16255 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16256 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16257 ArrayList<ActivityRecord> activities;
16259 synchronized (this) {
16260 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16261 dumpFocusedStackOnly);
16264 if (activities.size() <= 0) {
16268 String[] newArgs = new String[args.length - opti];
16269 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16271 TaskRecord lastTask = null;
16272 boolean needSep = false;
16273 for (int i=activities.size()-1; i>=0; i--) {
16274 ActivityRecord r = activities.get(i);
16279 synchronized (this) {
16280 final TaskRecord task = r.getTask();
16281 if (lastTask != task) {
16283 pw.print("TASK "); pw.print(lastTask.affinity);
16284 pw.print(" id="); pw.print(lastTask.taskId);
16285 pw.print(" userId="); pw.println(lastTask.userId);
16287 lastTask.dump(pw, " ");
16291 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16297 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16298 * there is a thread associated with the activity.
16300 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16301 final ActivityRecord r, String[] args, boolean dumpAll) {
16302 String innerPrefix = prefix + " ";
16303 synchronized (this) {
16304 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16305 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16307 if (r.app != null) pw.println(r.app.pid);
16308 else pw.println("(not running)");
16310 r.dump(pw, innerPrefix);
16313 if (r.app != null && r.app.thread != null) {
16314 // flush anything that is already in the PrintWriter since the thread is going
16315 // to write to the file descriptor directly
16318 TransferPipe tp = new TransferPipe();
16320 r.app.thread.dumpActivity(tp.getWriteFd(),
16321 r.appToken, innerPrefix, args);
16326 } catch (IOException e) {
16327 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16328 } catch (RemoteException e) {
16329 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16334 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16335 int opti, boolean dumpAll, String dumpPackage) {
16336 boolean needSep = false;
16337 boolean onlyHistory = false;
16338 boolean printedAnything = false;
16340 if ("history".equals(dumpPackage)) {
16341 if (opti < args.length && "-s".equals(args[opti])) {
16344 onlyHistory = true;
16345 dumpPackage = null;
16348 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16349 if (!onlyHistory && dumpAll) {
16350 if (mRegisteredReceivers.size() > 0) {
16351 boolean printed = false;
16352 Iterator it = mRegisteredReceivers.values().iterator();
16353 while (it.hasNext()) {
16354 ReceiverList r = (ReceiverList)it.next();
16355 if (dumpPackage != null && (r.app == null ||
16356 !dumpPackage.equals(r.app.info.packageName))) {
16360 pw.println(" Registered Receivers:");
16363 printedAnything = true;
16365 pw.print(" * "); pw.println(r);
16370 if (mReceiverResolver.dump(pw, needSep ?
16371 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16372 " ", dumpPackage, false, false)) {
16374 printedAnything = true;
16378 for (BroadcastQueue q : mBroadcastQueues) {
16379 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16380 printedAnything |= needSep;
16385 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16386 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16391 printedAnything = true;
16392 pw.print(" Sticky broadcasts for user ");
16393 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16394 StringBuilder sb = new StringBuilder(128);
16395 for (Map.Entry<String, ArrayList<Intent>> ent
16396 : mStickyBroadcasts.valueAt(user).entrySet()) {
16397 pw.print(" * Sticky action "); pw.print(ent.getKey());
16400 ArrayList<Intent> intents = ent.getValue();
16401 final int N = intents.size();
16402 for (int i=0; i<N; i++) {
16404 sb.append(" Intent: ");
16405 intents.get(i).toShortString(sb, false, true, false, false);
16406 pw.println(sb.toString());
16407 Bundle bundle = intents.get(i).getExtras();
16408 if (bundle != null) {
16410 pw.println(bundle.toString());
16420 if (!onlyHistory && dumpAll) {
16422 for (BroadcastQueue queue : mBroadcastQueues) {
16423 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16424 + queue.mBroadcastsScheduled);
16426 pw.println(" mHandler:");
16427 mHandler.dump(new PrintWriterPrinter(pw), " ");
16429 printedAnything = true;
16432 if (!printedAnything) {
16433 pw.println(" (nothing)");
16437 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16438 int opti, boolean dumpAll, String dumpPackage) {
16439 if (mCurBroadcastStats == null) {
16443 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16444 final long now = SystemClock.elapsedRealtime();
16445 if (mLastBroadcastStats != null) {
16446 pw.print(" Last stats (from ");
16447 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16449 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16451 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16452 - mLastBroadcastStats.mStartUptime, pw);
16453 pw.println(" uptime):");
16454 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16455 pw.println(" (nothing)");
16459 pw.print(" Current stats (from ");
16460 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16461 pw.print(" to now, ");
16462 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16463 - mCurBroadcastStats.mStartUptime, pw);
16464 pw.println(" uptime):");
16465 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16466 pw.println(" (nothing)");
16470 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16471 int opti, boolean fullCheckin, String dumpPackage) {
16472 if (mCurBroadcastStats == null) {
16476 if (mLastBroadcastStats != null) {
16477 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16479 mLastBroadcastStats = null;
16483 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16485 mCurBroadcastStats = null;
16489 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16490 int opti, boolean dumpAll, String dumpPackage) {
16492 boolean printedAnything = false;
16494 ItemMatcher matcher = new ItemMatcher();
16495 matcher.build(args, opti);
16497 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16499 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16500 printedAnything |= needSep;
16502 if (mLaunchingProviders.size() > 0) {
16503 boolean printed = false;
16504 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16505 ContentProviderRecord r = mLaunchingProviders.get(i);
16506 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16510 if (needSep) pw.println();
16512 pw.println(" Launching content providers:");
16514 printedAnything = true;
16516 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16521 if (!printedAnything) {
16522 pw.println(" (nothing)");
16526 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16527 int opti, boolean dumpAll, String dumpPackage) {
16528 boolean needSep = false;
16529 boolean printedAnything = false;
16531 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16533 if (mGrantedUriPermissions.size() > 0) {
16534 boolean printed = false;
16536 if (dumpPackage != null) {
16538 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16539 MATCH_ANY_USER, 0);
16540 } catch (NameNotFoundException e) {
16544 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16545 int uid = mGrantedUriPermissions.keyAt(i);
16546 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16549 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16551 if (needSep) pw.println();
16553 pw.println(" Granted Uri Permissions:");
16555 printedAnything = true;
16557 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16558 for (UriPermission perm : perms.values()) {
16559 pw.print(" "); pw.println(perm);
16561 perm.dump(pw, " ");
16567 if (!printedAnything) {
16568 pw.println(" (nothing)");
16572 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16573 int opti, boolean dumpAll, String dumpPackage) {
16574 boolean printed = false;
16576 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16578 if (mIntentSenderRecords.size() > 0) {
16579 // Organize these by package name, so they are easier to read.
16580 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16581 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16582 final Iterator<WeakReference<PendingIntentRecord>> it
16583 = mIntentSenderRecords.values().iterator();
16584 while (it.hasNext()) {
16585 WeakReference<PendingIntentRecord> ref = it.next();
16586 PendingIntentRecord rec = ref != null ? ref.get() : null;
16591 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16594 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16595 if (list == null) {
16596 list = new ArrayList<>();
16597 byPackage.put(rec.key.packageName, list);
16601 for (int i = 0; i < byPackage.size(); i++) {
16602 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16604 pw.print(" * "); pw.print(byPackage.keyAt(i));
16605 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16606 for (int j = 0; j < intents.size(); j++) {
16607 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16609 intents.get(j).dump(pw, " ");
16613 if (weakRefs.size() > 0) {
16615 pw.println(" * WEAK REFS:");
16616 for (int i = 0; i < weakRefs.size(); i++) {
16617 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16623 pw.println(" (nothing)");
16627 private static final int dumpProcessList(PrintWriter pw,
16628 ActivityManagerService service, List list,
16629 String prefix, String normalLabel, String persistentLabel,
16630 String dumpPackage) {
16632 final int N = list.size()-1;
16633 for (int i=N; i>=0; i--) {
16634 ProcessRecord r = (ProcessRecord)list.get(i);
16635 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16638 pw.println(String.format("%s%s #%2d: %s",
16639 prefix, (r.persistent ? persistentLabel : normalLabel),
16641 if (r.persistent) {
16648 private static final boolean dumpProcessOomList(PrintWriter pw,
16649 ActivityManagerService service, List<ProcessRecord> origList,
16650 String prefix, String normalLabel, String persistentLabel,
16651 boolean inclDetails, String dumpPackage) {
16653 ArrayList<Pair<ProcessRecord, Integer>> list
16654 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16655 for (int i=0; i<origList.size(); i++) {
16656 ProcessRecord r = origList.get(i);
16657 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16660 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16663 if (list.size() <= 0) {
16667 Comparator<Pair<ProcessRecord, Integer>> comparator
16668 = new Comparator<Pair<ProcessRecord, Integer>>() {
16670 public int compare(Pair<ProcessRecord, Integer> object1,
16671 Pair<ProcessRecord, Integer> object2) {
16672 if (object1.first.setAdj != object2.first.setAdj) {
16673 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16675 if (object1.first.setProcState != object2.first.setProcState) {
16676 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16678 if (object1.second.intValue() != object2.second.intValue()) {
16679 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16685 Collections.sort(list, comparator);
16687 final long curUptime = SystemClock.uptimeMillis();
16688 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16690 for (int i=list.size()-1; i>=0; i--) {
16691 ProcessRecord r = list.get(i).first;
16692 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16694 switch (r.setSchedGroup) {
16695 case ProcessList.SCHED_GROUP_BACKGROUND:
16698 case ProcessList.SCHED_GROUP_DEFAULT:
16701 case ProcessList.SCHED_GROUP_TOP_APP:
16709 if (r.foregroundActivities) {
16711 } else if (r.foregroundServices) {
16716 String procState = ProcessList.makeProcStateString(r.curProcState);
16718 pw.print(r.persistent ? persistentLabel : normalLabel);
16720 int num = (origList.size()-1)-list.get(i).second;
16721 if (num < 10) pw.print(' ');
16726 pw.print(schedGroup);
16728 pw.print(foreground);
16730 pw.print(procState);
16732 if (r.trimMemoryLevel < 10) pw.print(' ');
16733 pw.print(r.trimMemoryLevel);
16735 pw.print(r.toShortString());
16737 pw.print(r.adjType);
16739 if (r.adjSource != null || r.adjTarget != null) {
16742 if (r.adjTarget instanceof ComponentName) {
16743 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16744 } else if (r.adjTarget != null) {
16745 pw.print(r.adjTarget.toString());
16747 pw.print("{null}");
16750 if (r.adjSource instanceof ProcessRecord) {
16752 pw.print(((ProcessRecord)r.adjSource).toShortString());
16754 } else if (r.adjSource != null) {
16755 pw.println(r.adjSource.toString());
16757 pw.println("{null}");
16763 pw.print("oom: max="); pw.print(r.maxAdj);
16764 pw.print(" curRaw="); pw.print(r.curRawAdj);
16765 pw.print(" setRaw="); pw.print(r.setRawAdj);
16766 pw.print(" cur="); pw.print(r.curAdj);
16767 pw.print(" set="); pw.println(r.setAdj);
16770 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16771 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16772 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16773 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16774 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16778 pw.print("cached="); pw.print(r.cached);
16779 pw.print(" empty="); pw.print(r.empty);
16780 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16782 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16783 if (r.lastCpuTime != 0) {
16784 long timeUsed = r.curCpuTime - r.lastCpuTime;
16787 pw.print("run cpu over ");
16788 TimeUtils.formatDuration(uptimeSince, pw);
16789 pw.print(" used ");
16790 TimeUtils.formatDuration(timeUsed, pw);
16792 pw.print((timeUsed*100)/uptimeSince);
16801 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16803 ArrayList<ProcessRecord> procs;
16804 synchronized (this) {
16805 if (args != null && args.length > start
16806 && args[start].charAt(0) != '-') {
16807 procs = new ArrayList<ProcessRecord>();
16810 pid = Integer.parseInt(args[start]);
16811 } catch (NumberFormatException e) {
16813 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16814 ProcessRecord proc = mLruProcesses.get(i);
16815 if (proc.pid == pid) {
16817 } else if (allPkgs && proc.pkgList != null
16818 && proc.pkgList.containsKey(args[start])) {
16820 } else if (proc.processName.equals(args[start])) {
16824 if (procs.size() <= 0) {
16828 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16834 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16835 PrintWriter pw, String[] args) {
16836 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16837 if (procs == null) {
16838 pw.println("No process found for: " + args[0]);
16842 long uptime = SystemClock.uptimeMillis();
16843 long realtime = SystemClock.elapsedRealtime();
16844 pw.println("Applications Graphics Acceleration Info:");
16845 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16847 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16848 ProcessRecord r = procs.get(i);
16849 if (r.thread != null) {
16850 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16853 TransferPipe tp = new TransferPipe();
16855 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16860 } catch (IOException e) {
16861 pw.println("Failure while dumping the app: " + r);
16863 } catch (RemoteException e) {
16864 pw.println("Got a RemoteException while dumping the app " + r);
16871 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16872 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16873 if (procs == null) {
16874 pw.println("No process found for: " + args[0]);
16878 pw.println("Applications Database Info:");
16880 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16881 ProcessRecord r = procs.get(i);
16882 if (r.thread != null) {
16883 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16886 TransferPipe tp = new TransferPipe();
16888 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16893 } catch (IOException e) {
16894 pw.println("Failure while dumping the app: " + r);
16896 } catch (RemoteException e) {
16897 pw.println("Got a RemoteException while dumping the app " + r);
16904 final static class MemItem {
16905 final boolean isProc;
16906 final String label;
16907 final String shortLabel;
16909 final long swapPss;
16911 final boolean hasActivities;
16912 ArrayList<MemItem> subitems;
16914 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16915 boolean _hasActivities) {
16918 shortLabel = _shortLabel;
16920 swapPss = _swapPss;
16922 hasActivities = _hasActivities;
16925 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16928 shortLabel = _shortLabel;
16930 swapPss = _swapPss;
16932 hasActivities = false;
16936 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16937 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16938 if (sort && !isCompact) {
16939 Collections.sort(items, new Comparator<MemItem>() {
16941 public int compare(MemItem lhs, MemItem rhs) {
16942 if (lhs.pss < rhs.pss) {
16944 } else if (lhs.pss > rhs.pss) {
16952 for (int i=0; i<items.size(); i++) {
16953 MemItem mi = items.get(i);
16956 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16957 mi.label, stringifyKBSize(mi.swapPss));
16959 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16961 } else if (mi.isProc) {
16962 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16963 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16964 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16965 pw.println(mi.hasActivities ? ",a" : ",e");
16967 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16968 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16970 if (mi.subitems != null) {
16971 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16972 true, isCompact, dumpSwapPss);
16977 // These are in KB.
16978 static final long[] DUMP_MEM_BUCKETS = new long[] {
16979 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16980 120*1024, 160*1024, 200*1024,
16981 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16982 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16985 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16986 boolean stackLike) {
16987 int start = label.lastIndexOf('.');
16988 if (start >= 0) start++;
16990 int end = label.length();
16991 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16992 if (DUMP_MEM_BUCKETS[i] >= memKB) {
16993 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16994 out.append(bucket);
16995 out.append(stackLike ? "MB." : "MB ");
16996 out.append(label, start, end);
17000 out.append(memKB/1024);
17001 out.append(stackLike ? "MB." : "MB ");
17002 out.append(label, start, end);
17005 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17006 ProcessList.NATIVE_ADJ,
17007 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17008 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17009 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17010 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17011 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17012 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17014 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17016 "System", "Persistent", "Persistent Service", "Foreground",
17017 "Visible", "Perceptible",
17018 "Heavy Weight", "Backup",
17019 "A Services", "Home",
17020 "Previous", "B Services", "Cached"
17022 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17024 "sys", "pers", "persvc", "fore",
17027 "servicea", "home",
17028 "prev", "serviceb", "cached"
17031 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17032 long realtime, boolean isCheckinRequest, boolean isCompact) {
17034 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17036 if (isCheckinRequest || isCompact) {
17037 // short checkin version
17038 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17040 pw.println("Applications Memory Usage (in Kilobytes):");
17041 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17045 private static final int KSM_SHARED = 0;
17046 private static final int KSM_SHARING = 1;
17047 private static final int KSM_UNSHARED = 2;
17048 private static final int KSM_VOLATILE = 3;
17050 private final long[] getKsmInfo() {
17051 long[] longOut = new long[4];
17052 final int[] SINGLE_LONG_FORMAT = new int[] {
17053 PROC_SPACE_TERM| PROC_OUT_LONG
17055 long[] longTmp = new long[1];
17056 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17057 SINGLE_LONG_FORMAT, null, longTmp, null);
17058 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17060 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17061 SINGLE_LONG_FORMAT, null, longTmp, null);
17062 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17064 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17065 SINGLE_LONG_FORMAT, null, longTmp, null);
17066 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17068 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17069 SINGLE_LONG_FORMAT, null, longTmp, null);
17070 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17074 private static String stringifySize(long size, int order) {
17075 Locale locale = Locale.US;
17078 return String.format(locale, "%,13d", size);
17080 return String.format(locale, "%,9dK", size / 1024);
17082 return String.format(locale, "%,5dM", size / 1024 / 1024);
17083 case 1024 * 1024 * 1024:
17084 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17086 throw new IllegalArgumentException("Invalid size order");
17090 private static String stringifyKBSize(long size) {
17091 return stringifySize(size * 1024, 1024);
17094 // Update this version number in case you change the 'compact' format
17095 private static final int MEMINFO_COMPACT_VERSION = 1;
17097 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17098 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17099 boolean dumpDetails = false;
17100 boolean dumpFullDetails = false;
17101 boolean dumpDalvik = false;
17102 boolean dumpSummaryOnly = false;
17103 boolean dumpUnreachable = false;
17104 boolean oomOnly = false;
17105 boolean isCompact = false;
17106 boolean localOnly = false;
17107 boolean packages = false;
17108 boolean isCheckinRequest = false;
17109 boolean dumpSwapPss = false;
17112 while (opti < args.length) {
17113 String opt = args[opti];
17114 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17118 if ("-a".equals(opt)) {
17119 dumpDetails = true;
17120 dumpFullDetails = true;
17122 dumpSwapPss = true;
17123 } else if ("-d".equals(opt)) {
17125 } else if ("-c".equals(opt)) {
17127 } else if ("-s".equals(opt)) {
17128 dumpDetails = true;
17129 dumpSummaryOnly = true;
17130 } else if ("-S".equals(opt)) {
17131 dumpSwapPss = true;
17132 } else if ("--unreachable".equals(opt)) {
17133 dumpUnreachable = true;
17134 } else if ("--oom".equals(opt)) {
17136 } else if ("--local".equals(opt)) {
17138 } else if ("--package".equals(opt)) {
17140 } else if ("--checkin".equals(opt)) {
17141 isCheckinRequest = true;
17143 } else if ("-h".equals(opt)) {
17144 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17145 pw.println(" -a: include all available information for each process.");
17146 pw.println(" -d: include dalvik details.");
17147 pw.println(" -c: dump in a compact machine-parseable representation.");
17148 pw.println(" -s: dump only summary of application memory usage.");
17149 pw.println(" -S: dump also SwapPss.");
17150 pw.println(" --oom: only show processes organized by oom adj.");
17151 pw.println(" --local: only collect details locally, don't call process.");
17152 pw.println(" --package: interpret process arg as package, dumping all");
17153 pw.println(" processes that have loaded that package.");
17154 pw.println(" --checkin: dump data for a checkin");
17155 pw.println("If [process] is specified it can be the name or ");
17156 pw.println("pid of a specific process to dump.");
17159 pw.println("Unknown argument: " + opt + "; use -h for help");
17163 long uptime = SystemClock.uptimeMillis();
17164 long realtime = SystemClock.elapsedRealtime();
17165 final long[] tmpLong = new long[1];
17167 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17168 if (procs == null) {
17169 // No Java processes. Maybe they want to print a native process.
17170 if (args != null && args.length > opti
17171 && args[opti].charAt(0) != '-') {
17172 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17173 = new ArrayList<ProcessCpuTracker.Stats>();
17174 updateCpuStatsNow();
17177 findPid = Integer.parseInt(args[opti]);
17178 } catch (NumberFormatException e) {
17180 synchronized (mProcessCpuTracker) {
17181 final int N = mProcessCpuTracker.countStats();
17182 for (int i=0; i<N; i++) {
17183 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17184 if (st.pid == findPid || (st.baseName != null
17185 && st.baseName.equals(args[opti]))) {
17186 nativeProcs.add(st);
17190 if (nativeProcs.size() > 0) {
17191 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17193 Debug.MemoryInfo mi = null;
17194 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17195 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17196 final int pid = r.pid;
17197 if (!isCheckinRequest && dumpDetails) {
17198 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17201 mi = new Debug.MemoryInfo();
17203 if (dumpDetails || (!brief && !oomOnly)) {
17204 Debug.getMemoryInfo(pid, mi);
17206 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17207 mi.dalvikPrivateDirty = (int)tmpLong[0];
17209 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17210 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17211 if (isCheckinRequest) {
17218 pw.println("No process found for: " + args[opti]);
17222 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17223 dumpDetails = true;
17226 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17228 String[] innerArgs = new String[args.length-opti];
17229 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17231 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17232 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17233 long nativePss = 0;
17234 long nativeSwapPss = 0;
17235 long dalvikPss = 0;
17236 long dalvikSwapPss = 0;
17237 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17239 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17242 long otherSwapPss = 0;
17243 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17244 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17246 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17247 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17248 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17249 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17252 long totalSwapPss = 0;
17253 long cachedPss = 0;
17254 long cachedSwapPss = 0;
17255 boolean hasSwapPss = false;
17257 Debug.MemoryInfo mi = null;
17258 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17259 final ProcessRecord r = procs.get(i);
17260 final IApplicationThread thread;
17263 final boolean hasActivities;
17264 synchronized (this) {
17267 oomAdj = r.getSetAdjWithServices();
17268 hasActivities = r.activities.size() > 0;
17270 if (thread != null) {
17271 if (!isCheckinRequest && dumpDetails) {
17272 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17275 mi = new Debug.MemoryInfo();
17277 if (dumpDetails || (!brief && !oomOnly)) {
17278 Debug.getMemoryInfo(pid, mi);
17279 hasSwapPss = mi.hasSwappedOutPss;
17281 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17282 mi.dalvikPrivateDirty = (int)tmpLong[0];
17286 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17287 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17288 if (isCheckinRequest) {
17294 TransferPipe tp = new TransferPipe();
17296 thread.dumpMemInfo(tp.getWriteFd(),
17297 mi, isCheckinRequest, dumpFullDetails,
17298 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17303 } catch (IOException e) {
17304 if (!isCheckinRequest) {
17305 pw.println("Got IoException! " + e);
17308 } catch (RemoteException e) {
17309 if (!isCheckinRequest) {
17310 pw.println("Got RemoteException! " + e);
17317 final long myTotalPss = mi.getTotalPss();
17318 final long myTotalUss = mi.getTotalUss();
17319 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17321 synchronized (this) {
17322 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17323 // Record this for posterity if the process has been stable.
17324 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17328 if (!isCheckinRequest && mi != null) {
17329 totalPss += myTotalPss;
17330 totalSwapPss += myTotalSwapPss;
17331 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17332 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17333 myTotalSwapPss, pid, hasActivities);
17334 procMems.add(pssItem);
17335 procMemsMap.put(pid, pssItem);
17337 nativePss += mi.nativePss;
17338 nativeSwapPss += mi.nativeSwappedOutPss;
17339 dalvikPss += mi.dalvikPss;
17340 dalvikSwapPss += mi.dalvikSwappedOutPss;
17341 for (int j=0; j<dalvikSubitemPss.length; j++) {
17342 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17343 dalvikSubitemSwapPss[j] +=
17344 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17346 otherPss += mi.otherPss;
17347 otherSwapPss += mi.otherSwappedOutPss;
17348 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17349 long mem = mi.getOtherPss(j);
17352 mem = mi.getOtherSwappedOutPss(j);
17353 miscSwapPss[j] += mem;
17354 otherSwapPss -= mem;
17357 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17358 cachedPss += myTotalPss;
17359 cachedSwapPss += myTotalSwapPss;
17362 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17363 if (oomIndex == (oomPss.length - 1)
17364 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17365 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17366 oomPss[oomIndex] += myTotalPss;
17367 oomSwapPss[oomIndex] += myTotalSwapPss;
17368 if (oomProcs[oomIndex] == null) {
17369 oomProcs[oomIndex] = new ArrayList<MemItem>();
17371 oomProcs[oomIndex].add(pssItem);
17379 long nativeProcTotalPss = 0;
17381 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17382 // If we are showing aggregations, also look for native processes to
17383 // include so that our aggregations are more accurate.
17384 updateCpuStatsNow();
17386 synchronized (mProcessCpuTracker) {
17387 final int N = mProcessCpuTracker.countStats();
17388 for (int i=0; i<N; i++) {
17389 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17390 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17392 mi = new Debug.MemoryInfo();
17394 if (!brief && !oomOnly) {
17395 Debug.getMemoryInfo(st.pid, mi);
17397 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17398 mi.nativePrivateDirty = (int)tmpLong[0];
17401 final long myTotalPss = mi.getTotalPss();
17402 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17403 totalPss += myTotalPss;
17404 nativeProcTotalPss += myTotalPss;
17406 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17407 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17408 procMems.add(pssItem);
17410 nativePss += mi.nativePss;
17411 nativeSwapPss += mi.nativeSwappedOutPss;
17412 dalvikPss += mi.dalvikPss;
17413 dalvikSwapPss += mi.dalvikSwappedOutPss;
17414 for (int j=0; j<dalvikSubitemPss.length; j++) {
17415 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17416 dalvikSubitemSwapPss[j] +=
17417 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17419 otherPss += mi.otherPss;
17420 otherSwapPss += mi.otherSwappedOutPss;
17421 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17422 long mem = mi.getOtherPss(j);
17425 mem = mi.getOtherSwappedOutPss(j);
17426 miscSwapPss[j] += mem;
17427 otherSwapPss -= mem;
17429 oomPss[0] += myTotalPss;
17430 oomSwapPss[0] += myTotalSwapPss;
17431 if (oomProcs[0] == null) {
17432 oomProcs[0] = new ArrayList<MemItem>();
17434 oomProcs[0].add(pssItem);
17439 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17441 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17442 final int dalvikId = -2;
17443 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17444 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17445 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17446 String label = Debug.MemoryInfo.getOtherLabel(j);
17447 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17449 if (dalvikSubitemPss.length > 0) {
17450 // Add dalvik subitems.
17451 for (MemItem memItem : catMems) {
17452 int memItemStart = 0, memItemEnd = 0;
17453 if (memItem.id == dalvikId) {
17454 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17455 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17456 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17457 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17458 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17459 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17460 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17461 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17462 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17463 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17464 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17466 continue; // No subitems, continue.
17468 memItem.subitems = new ArrayList<MemItem>();
17469 for (int j=memItemStart; j<=memItemEnd; j++) {
17470 final String name = Debug.MemoryInfo.getOtherLabel(
17471 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17472 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17473 dalvikSubitemSwapPss[j], j));
17478 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17479 for (int j=0; j<oomPss.length; j++) {
17480 if (oomPss[j] != 0) {
17481 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17482 : DUMP_MEM_OOM_LABEL[j];
17483 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17484 DUMP_MEM_OOM_ADJ[j]);
17485 item.subitems = oomProcs[j];
17490 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17491 if (!brief && !oomOnly && !isCompact) {
17493 pw.println("Total PSS by process:");
17494 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17498 pw.println("Total PSS by OOM adjustment:");
17500 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17501 if (!brief && !oomOnly) {
17502 PrintWriter out = categoryPw != null ? categoryPw : pw;
17505 out.println("Total PSS by category:");
17507 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17512 MemInfoReader memInfo = new MemInfoReader();
17513 memInfo.readMemInfo();
17514 if (nativeProcTotalPss > 0) {
17515 synchronized (this) {
17516 final long cachedKb = memInfo.getCachedSizeKb();
17517 final long freeKb = memInfo.getFreeSizeKb();
17518 final long zramKb = memInfo.getZramTotalSizeKb();
17519 final long kernelKb = memInfo.getKernelUsedSizeKb();
17520 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17521 kernelKb*1024, nativeProcTotalPss*1024);
17522 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17523 nativeProcTotalPss);
17528 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17529 pw.print(" (status ");
17530 switch (mLastMemoryLevel) {
17531 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17532 pw.println("normal)");
17534 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17535 pw.println("moderate)");
17537 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17538 pw.println("low)");
17540 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17541 pw.println("critical)");
17544 pw.print(mLastMemoryLevel);
17548 pw.print(" Free RAM: ");
17549 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17550 + memInfo.getFreeSizeKb()));
17552 pw.print(stringifyKBSize(cachedPss));
17553 pw.print(" cached pss + ");
17554 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17555 pw.print(" cached kernel + ");
17556 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17557 pw.println(" free)");
17559 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17560 pw.print(cachedPss + memInfo.getCachedSizeKb()
17561 + memInfo.getFreeSizeKb()); pw.print(",");
17562 pw.println(totalPss - cachedPss);
17565 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17566 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17567 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17569 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17570 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17571 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17572 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17573 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17575 pw.print("lostram,"); pw.println(lostRAM);
17578 if (memInfo.getZramTotalSizeKb() != 0) {
17580 pw.print(" ZRAM: ");
17581 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17582 pw.print(" physical used for ");
17583 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17584 - memInfo.getSwapFreeSizeKb()));
17585 pw.print(" in swap (");
17586 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17587 pw.println(" total swap)");
17589 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17590 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17591 pw.println(memInfo.getSwapFreeSizeKb());
17594 final long[] ksm = getKsmInfo();
17596 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17597 || ksm[KSM_VOLATILE] != 0) {
17598 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17599 pw.print(" saved from shared ");
17600 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17601 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17602 pw.print(" unshared; ");
17603 pw.print(stringifyKBSize(
17604 ksm[KSM_VOLATILE])); pw.println(" volatile");
17606 pw.print(" Tuning: ");
17607 pw.print(ActivityManager.staticGetMemoryClass());
17608 pw.print(" (large ");
17609 pw.print(ActivityManager.staticGetLargeMemoryClass());
17610 pw.print("), oom ");
17611 pw.print(stringifySize(
17612 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17613 pw.print(", restore limit ");
17614 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17615 if (ActivityManager.isLowRamDeviceStatic()) {
17616 pw.print(" (low-ram)");
17618 if (ActivityManager.isHighEndGfx()) {
17619 pw.print(" (high-end-gfx)");
17623 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17624 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17625 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17626 pw.print("tuning,");
17627 pw.print(ActivityManager.staticGetMemoryClass());
17629 pw.print(ActivityManager.staticGetLargeMemoryClass());
17631 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17632 if (ActivityManager.isLowRamDeviceStatic()) {
17633 pw.print(",low-ram");
17635 if (ActivityManager.isHighEndGfx()) {
17636 pw.print(",high-end-gfx");
17644 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17645 long memtrack, String name) {
17647 sb.append(ProcessList.makeOomAdjString(oomAdj));
17649 sb.append(ProcessList.makeProcStateString(procState));
17651 ProcessList.appendRamKb(sb, pss);
17654 if (memtrack > 0) {
17656 sb.append(stringifyKBSize(memtrack));
17657 sb.append(" memtrack)");
17661 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17662 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17663 sb.append(" (pid ");
17666 sb.append(mi.adjType);
17668 if (mi.adjReason != null) {
17670 sb.append(mi.adjReason);
17675 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17676 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17677 for (int i=0, N=memInfos.size(); i<N; i++) {
17678 ProcessMemInfo mi = memInfos.get(i);
17679 infoMap.put(mi.pid, mi);
17681 updateCpuStatsNow();
17682 long[] memtrackTmp = new long[1];
17683 final List<ProcessCpuTracker.Stats> stats;
17684 // Get a list of Stats that have vsize > 0
17685 synchronized (mProcessCpuTracker) {
17686 stats = mProcessCpuTracker.getStats((st) -> {
17687 return st.vsize > 0;
17690 final int statsCount = stats.size();
17691 for (int i = 0; i < statsCount; i++) {
17692 ProcessCpuTracker.Stats st = stats.get(i);
17693 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17695 if (infoMap.indexOfKey(st.pid) < 0) {
17696 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17697 ProcessList.NATIVE_ADJ, -1, "native", null);
17699 mi.memtrack = memtrackTmp[0];
17706 long totalMemtrack = 0;
17707 for (int i=0, N=memInfos.size(); i<N; i++) {
17708 ProcessMemInfo mi = memInfos.get(i);
17710 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17711 mi.memtrack = memtrackTmp[0];
17713 totalPss += mi.pss;
17714 totalMemtrack += mi.memtrack;
17716 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17717 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17718 if (lhs.oomAdj != rhs.oomAdj) {
17719 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17721 if (lhs.pss != rhs.pss) {
17722 return lhs.pss < rhs.pss ? 1 : -1;
17728 StringBuilder tag = new StringBuilder(128);
17729 StringBuilder stack = new StringBuilder(128);
17730 tag.append("Low on memory -- ");
17731 appendMemBucket(tag, totalPss, "total", false);
17732 appendMemBucket(stack, totalPss, "total", true);
17734 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17735 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17736 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17738 boolean firstLine = true;
17739 int lastOomAdj = Integer.MIN_VALUE;
17740 long extraNativeRam = 0;
17741 long extraNativeMemtrack = 0;
17742 long cachedPss = 0;
17743 for (int i=0, N=memInfos.size(); i<N; i++) {
17744 ProcessMemInfo mi = memInfos.get(i);
17746 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17747 cachedPss += mi.pss;
17750 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17751 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17752 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17753 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17754 if (lastOomAdj != mi.oomAdj) {
17755 lastOomAdj = mi.oomAdj;
17756 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17759 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17764 stack.append("\n\t at ");
17772 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17773 appendMemBucket(tag, mi.pss, mi.name, false);
17775 appendMemBucket(stack, mi.pss, mi.name, true);
17776 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17777 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17779 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17780 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17781 stack.append(DUMP_MEM_OOM_LABEL[k]);
17783 stack.append(DUMP_MEM_OOM_ADJ[k]);
17790 appendMemInfo(fullNativeBuilder, mi);
17791 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17792 // The short form only has native processes that are >= 512K.
17793 if (mi.pss >= 512) {
17794 appendMemInfo(shortNativeBuilder, mi);
17796 extraNativeRam += mi.pss;
17797 extraNativeMemtrack += mi.memtrack;
17800 // Short form has all other details, but if we have collected RAM
17801 // from smaller native processes let's dump a summary of that.
17802 if (extraNativeRam > 0) {
17803 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17804 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17805 shortNativeBuilder.append('\n');
17806 extraNativeRam = 0;
17808 appendMemInfo(fullJavaBuilder, mi);
17812 fullJavaBuilder.append(" ");
17813 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17814 fullJavaBuilder.append(": TOTAL");
17815 if (totalMemtrack > 0) {
17816 fullJavaBuilder.append(" (");
17817 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17818 fullJavaBuilder.append(" memtrack)");
17821 fullJavaBuilder.append("\n");
17823 MemInfoReader memInfo = new MemInfoReader();
17824 memInfo.readMemInfo();
17825 final long[] infos = memInfo.getRawInfo();
17827 StringBuilder memInfoBuilder = new StringBuilder(1024);
17828 Debug.getMemInfo(infos);
17829 memInfoBuilder.append(" MemInfo: ");
17830 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17831 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17832 memInfoBuilder.append(stringifyKBSize(
17833 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17834 memInfoBuilder.append(stringifyKBSize(
17835 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17836 memInfoBuilder.append(stringifyKBSize(
17837 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17838 memInfoBuilder.append(" ");
17839 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17840 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17841 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17842 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17843 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17844 memInfoBuilder.append(" ZRAM: ");
17845 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17846 memInfoBuilder.append(" RAM, ");
17847 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17848 memInfoBuilder.append(" swap total, ");
17849 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17850 memInfoBuilder.append(" swap free\n");
17852 final long[] ksm = getKsmInfo();
17853 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17854 || ksm[KSM_VOLATILE] != 0) {
17855 memInfoBuilder.append(" KSM: ");
17856 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17857 memInfoBuilder.append(" saved from shared ");
17858 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17859 memInfoBuilder.append("\n ");
17860 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17861 memInfoBuilder.append(" unshared; ");
17862 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17863 memInfoBuilder.append(" volatile\n");
17865 memInfoBuilder.append(" Free RAM: ");
17866 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17867 + memInfo.getFreeSizeKb()));
17868 memInfoBuilder.append("\n");
17869 memInfoBuilder.append(" Used RAM: ");
17870 memInfoBuilder.append(stringifyKBSize(
17871 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17872 memInfoBuilder.append("\n");
17873 memInfoBuilder.append(" Lost RAM: ");
17874 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17875 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17876 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17877 memInfoBuilder.append("\n");
17878 Slog.i(TAG, "Low on memory:");
17879 Slog.i(TAG, shortNativeBuilder.toString());
17880 Slog.i(TAG, fullJavaBuilder.toString());
17881 Slog.i(TAG, memInfoBuilder.toString());
17883 StringBuilder dropBuilder = new StringBuilder(1024);
17885 StringWriter oomSw = new StringWriter();
17886 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17887 StringWriter catSw = new StringWriter();
17888 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17889 String[] emptyArgs = new String[] { };
17890 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17892 String oomString = oomSw.toString();
17894 dropBuilder.append("Low on memory:");
17895 dropBuilder.append(stack);
17896 dropBuilder.append('\n');
17897 dropBuilder.append(fullNativeBuilder);
17898 dropBuilder.append(fullJavaBuilder);
17899 dropBuilder.append('\n');
17900 dropBuilder.append(memInfoBuilder);
17901 dropBuilder.append('\n');
17903 dropBuilder.append(oomString);
17904 dropBuilder.append('\n');
17906 StringWriter catSw = new StringWriter();
17907 synchronized (ActivityManagerService.this) {
17908 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17909 String[] emptyArgs = new String[] { };
17911 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17913 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17914 false, null).dumpLocked();
17916 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17919 dropBuilder.append(catSw.toString());
17920 addErrorToDropBox("lowmem", null, "system_server", null,
17921 null, tag.toString(), dropBuilder.toString(), null, null);
17922 //Slog.i(TAG, "Sent to dropbox:");
17923 //Slog.i(TAG, dropBuilder.toString());
17924 synchronized (ActivityManagerService.this) {
17925 long now = SystemClock.uptimeMillis();
17926 if (mLastMemUsageReportTime < now) {
17927 mLastMemUsageReportTime = now;
17933 * Searches array of arguments for the specified string
17934 * @param args array of argument strings
17935 * @param value value to search for
17936 * @return true if the value is contained in the array
17938 private static boolean scanArgs(String[] args, String value) {
17939 if (args != null) {
17940 for (String arg : args) {
17941 if (value.equals(arg)) {
17949 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17950 ContentProviderRecord cpr, boolean always) {
17951 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17953 if (!inLaunching || always) {
17954 synchronized (cpr) {
17955 cpr.launchingApp = null;
17958 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17959 String names[] = cpr.info.authority.split(";");
17960 for (int j = 0; j < names.length; j++) {
17961 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17965 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17966 ContentProviderConnection conn = cpr.connections.get(i);
17967 if (conn.waiting) {
17968 // If this connection is waiting for the provider, then we don't
17969 // need to mess with its process unless we are always removing
17970 // or for some reason the provider is not currently launching.
17971 if (inLaunching && !always) {
17975 ProcessRecord capp = conn.client;
17977 if (conn.stableCount > 0) {
17978 if (!capp.persistent && capp.thread != null
17980 && capp.pid != MY_PID) {
17981 capp.kill("depends on provider "
17982 + cpr.name.flattenToShortString()
17983 + " in dying proc " + (proc != null ? proc.processName : "??")
17984 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17986 } else if (capp.thread != null && conn.provider.provider != null) {
17988 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17989 } catch (RemoteException e) {
17991 // In the protocol here, we don't expect the client to correctly
17992 // clean up this connection, we'll just remove it.
17993 cpr.connections.remove(i);
17994 if (conn.client.conProviders.remove(conn)) {
17995 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18000 if (inLaunching && always) {
18001 mLaunchingProviders.remove(cpr);
18003 return inLaunching;
18007 * Main code for cleaning up a process when it has gone away. This is
18008 * called both as a result of the process dying, or directly when stopping
18009 * a process when running in single process mode.
18011 * @return Returns true if the given process has been restarted, so the
18012 * app that was passed in must remain on the process lists.
18014 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18015 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18017 removeLruProcessLocked(app);
18018 ProcessList.remove(app.pid);
18021 mProcessesToGc.remove(app);
18022 mPendingPssProcesses.remove(app);
18024 // Dismiss any open dialogs.
18025 if (app.crashDialog != null && !app.forceCrashReport) {
18026 app.crashDialog.dismiss();
18027 app.crashDialog = null;
18029 if (app.anrDialog != null) {
18030 app.anrDialog.dismiss();
18031 app.anrDialog = null;
18033 if (app.waitDialog != null) {
18034 app.waitDialog.dismiss();
18035 app.waitDialog = null;
18038 app.crashing = false;
18039 app.notResponding = false;
18041 app.resetPackageList(mProcessStats);
18042 app.unlinkDeathRecipient();
18043 app.makeInactive(mProcessStats);
18044 app.waitingToKill = null;
18045 app.forcingToImportant = null;
18046 updateProcessForegroundLocked(app, false, false);
18047 app.foregroundActivities = false;
18048 app.hasShownUi = false;
18049 app.treatLikeActivity = false;
18050 app.hasAboveClient = false;
18051 app.hasClientActivities = false;
18053 mServices.killServicesLocked(app, allowRestart);
18055 boolean restart = false;
18057 // Remove published content providers.
18058 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18059 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18060 final boolean always = app.bad || !allowRestart;
18061 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18062 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18063 // We left the provider in the launching list, need to
18068 cpr.provider = null;
18071 app.pubProviders.clear();
18073 // Take care of any launching providers waiting for this process.
18074 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18078 // Unregister from connected content providers.
18079 if (!app.conProviders.isEmpty()) {
18080 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18081 ContentProviderConnection conn = app.conProviders.get(i);
18082 conn.provider.connections.remove(conn);
18083 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18084 conn.provider.name);
18086 app.conProviders.clear();
18089 // At this point there may be remaining entries in mLaunchingProviders
18090 // where we were the only one waiting, so they are no longer of use.
18091 // Look for these and clean up if found.
18092 // XXX Commented out for now. Trying to figure out a way to reproduce
18093 // the actual situation to identify what is actually going on.
18095 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18096 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18097 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18098 synchronized (cpr) {
18099 cpr.launchingApp = null;
18106 skipCurrentReceiverLocked(app);
18108 // Unregister any receivers.
18109 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18110 removeReceiverLocked(app.receivers.valueAt(i));
18112 app.receivers.clear();
18114 // If the app is undergoing backup, tell the backup manager about it
18115 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18116 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18117 + mBackupTarget.appInfo + " died during backup");
18118 mHandler.post(new Runnable() {
18122 IBackupManager bm = IBackupManager.Stub.asInterface(
18123 ServiceManager.getService(Context.BACKUP_SERVICE));
18124 bm.agentDisconnected(app.info.packageName);
18125 } catch (RemoteException e) {
18126 // can't happen; backup manager is local
18132 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18133 ProcessChangeItem item = mPendingProcessChanges.get(i);
18134 if (item.pid == app.pid) {
18135 mPendingProcessChanges.remove(i);
18136 mAvailProcessChanges.add(item);
18139 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18140 null).sendToTarget();
18142 // If the caller is restarting this app, then leave it in its
18143 // current lists and let the caller take care of it.
18148 if (!app.persistent || app.isolated) {
18149 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18150 "Removing non-persistent process during cleanup: " + app);
18151 if (!replacingPid) {
18152 removeProcessNameLocked(app.processName, app.uid, app);
18154 if (mHeavyWeightProcess == app) {
18155 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18156 mHeavyWeightProcess.userId, 0));
18157 mHeavyWeightProcess = null;
18159 } else if (!app.removed) {
18160 // This app is persistent, so we need to keep its record around.
18161 // If it is not already on the pending app list, add it there
18162 // and start a new process for it.
18163 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18164 mPersistentStartingProcesses.add(app);
18168 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18169 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18170 mProcessesOnHold.remove(app);
18172 if (app == mHomeProcess) {
18173 mHomeProcess = null;
18175 if (app == mPreviousProcess) {
18176 mPreviousProcess = null;
18179 if (restart && !app.isolated) {
18180 // We have components that still need to be running in the
18181 // process, so re-launch it.
18183 ProcessList.remove(app.pid);
18185 addProcessNameLocked(app);
18186 startProcessLocked(app, "restart", app.processName);
18188 } else if (app.pid > 0 && app.pid != MY_PID) {
18191 synchronized (mPidsSelfLocked) {
18192 mPidsSelfLocked.remove(app.pid);
18193 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18195 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18196 if (app.isolated) {
18197 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18204 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18205 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18206 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18207 if (cpr.launchingApp == app) {
18214 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18215 // Look through the content providers we are waiting to have launched,
18216 // and if any run in this process then either schedule a restart of
18217 // the process or kill the client waiting for it if this process has
18219 boolean restart = false;
18220 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18221 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18222 if (cpr.launchingApp == app) {
18223 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18226 removeDyingProviderLocked(app, cpr, true);
18233 // =========================================================
18235 // =========================================================
18238 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18240 enforceNotIsolatedCaller("getServices");
18242 final int callingUid = Binder.getCallingUid();
18243 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18244 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18245 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18247 synchronized (this) {
18248 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18249 allowed, canInteractAcrossUsers);
18254 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18255 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18256 synchronized (this) {
18257 return mServices.getRunningServiceControlPanelLocked(name);
18262 public ComponentName startService(IApplicationThread caller, Intent service,
18263 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18264 throws TransactionTooLargeException {
18265 enforceNotIsolatedCaller("startService");
18266 // Refuse possible leaked file descriptors
18267 if (service != null && service.hasFileDescriptors() == true) {
18268 throw new IllegalArgumentException("File descriptors passed in Intent");
18271 if (callingPackage == null) {
18272 throw new IllegalArgumentException("callingPackage cannot be null");
18275 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18276 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18277 synchronized(this) {
18278 final int callingPid = Binder.getCallingPid();
18279 final int callingUid = Binder.getCallingUid();
18280 final long origId = Binder.clearCallingIdentity();
18283 res = mServices.startServiceLocked(caller, service,
18284 resolvedType, callingPid, callingUid,
18285 requireForeground, callingPackage, userId);
18287 Binder.restoreCallingIdentity(origId);
18293 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18294 boolean fgRequired, String callingPackage, int userId)
18295 throws TransactionTooLargeException {
18296 synchronized(this) {
18297 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18298 "startServiceInPackage: " + service + " type=" + resolvedType);
18299 final long origId = Binder.clearCallingIdentity();
18302 res = mServices.startServiceLocked(null, service,
18303 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18305 Binder.restoreCallingIdentity(origId);
18312 public int stopService(IApplicationThread caller, Intent service,
18313 String resolvedType, int userId) {
18314 enforceNotIsolatedCaller("stopService");
18315 // Refuse possible leaked file descriptors
18316 if (service != null && service.hasFileDescriptors() == true) {
18317 throw new IllegalArgumentException("File descriptors passed in Intent");
18320 synchronized(this) {
18321 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18326 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18327 enforceNotIsolatedCaller("peekService");
18328 // Refuse possible leaked file descriptors
18329 if (service != null && service.hasFileDescriptors() == true) {
18330 throw new IllegalArgumentException("File descriptors passed in Intent");
18333 if (callingPackage == null) {
18334 throw new IllegalArgumentException("callingPackage cannot be null");
18337 synchronized(this) {
18338 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18343 public boolean stopServiceToken(ComponentName className, IBinder token,
18345 synchronized(this) {
18346 return mServices.stopServiceTokenLocked(className, token, startId);
18351 public void setServiceForeground(ComponentName className, IBinder token,
18352 int id, Notification notification, int flags) {
18353 synchronized(this) {
18354 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18359 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18360 boolean requireFull, String name, String callerPackage) {
18361 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18362 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18365 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18366 String className, int flags) {
18367 boolean result = false;
18368 // For apps that don't have pre-defined UIDs, check for permission
18369 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18370 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18371 if (ActivityManager.checkUidPermission(
18372 INTERACT_ACROSS_USERS,
18373 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18374 ComponentName comp = new ComponentName(aInfo.packageName, className);
18375 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18376 + " requests FLAG_SINGLE_USER, but app does not hold "
18377 + INTERACT_ACROSS_USERS;
18379 throw new SecurityException(msg);
18381 // Permission passed
18384 } else if ("system".equals(componentProcessName)) {
18386 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18387 // Phone app and persistent apps are allowed to export singleuser providers.
18388 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18389 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18391 if (DEBUG_MU) Slog.v(TAG_MU,
18392 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18393 + Integer.toHexString(flags) + ") = " + result);
18398 * Checks to see if the caller is in the same app as the singleton
18399 * component, or the component is in a special app. It allows special apps
18400 * to export singleton components but prevents exporting singleton
18401 * components for regular apps.
18403 boolean isValidSingletonCall(int callingUid, int componentUid) {
18404 int componentAppId = UserHandle.getAppId(componentUid);
18405 return UserHandle.isSameApp(callingUid, componentUid)
18406 || componentAppId == SYSTEM_UID
18407 || componentAppId == PHONE_UID
18408 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18409 == PackageManager.PERMISSION_GRANTED;
18412 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18413 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18414 int userId) throws TransactionTooLargeException {
18415 enforceNotIsolatedCaller("bindService");
18417 // Refuse possible leaked file descriptors
18418 if (service != null && service.hasFileDescriptors() == true) {
18419 throw new IllegalArgumentException("File descriptors passed in Intent");
18422 if (callingPackage == null) {
18423 throw new IllegalArgumentException("callingPackage cannot be null");
18426 synchronized(this) {
18427 return mServices.bindServiceLocked(caller, token, service,
18428 resolvedType, connection, flags, callingPackage, userId);
18432 public boolean unbindService(IServiceConnection connection) {
18433 synchronized (this) {
18434 return mServices.unbindServiceLocked(connection);
18438 public void publishService(IBinder token, Intent intent, IBinder service) {
18439 // Refuse possible leaked file descriptors
18440 if (intent != null && intent.hasFileDescriptors() == true) {
18441 throw new IllegalArgumentException("File descriptors passed in Intent");
18444 synchronized(this) {
18445 if (!(token instanceof ServiceRecord)) {
18446 throw new IllegalArgumentException("Invalid service token");
18448 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18452 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18453 // Refuse possible leaked file descriptors
18454 if (intent != null && intent.hasFileDescriptors() == true) {
18455 throw new IllegalArgumentException("File descriptors passed in Intent");
18458 synchronized(this) {
18459 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18463 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18464 synchronized(this) {
18465 if (!(token instanceof ServiceRecord)) {
18466 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18467 throw new IllegalArgumentException("Invalid service token");
18469 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18473 // =========================================================
18474 // BACKUP AND RESTORE
18475 // =========================================================
18477 // Cause the target app to be launched if necessary and its backup agent
18478 // instantiated. The backup agent will invoke backupAgentCreated() on the
18479 // activity manager to announce its creation.
18480 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18481 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18482 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18484 IPackageManager pm = AppGlobals.getPackageManager();
18485 ApplicationInfo app = null;
18487 app = pm.getApplicationInfo(packageName, 0, userId);
18488 } catch (RemoteException e) {
18489 // can't happen; package manager is process-local
18492 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18499 synchronized(this) {
18500 // !!! TODO: currently no check here that we're already bound
18501 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18502 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18503 synchronized (stats) {
18504 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18507 // Backup agent is now in use, its package can't be stopped.
18509 AppGlobals.getPackageManager().setPackageStoppedState(
18510 app.packageName, false, UserHandle.getUserId(app.uid));
18511 } catch (RemoteException e) {
18512 } catch (IllegalArgumentException e) {
18513 Slog.w(TAG, "Failed trying to unstop package "
18514 + app.packageName + ": " + e);
18517 BackupRecord r = new BackupRecord(ss, app, backupMode);
18518 ComponentName hostingName =
18519 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18520 ? new ComponentName(app.packageName, app.backupAgentName)
18521 : new ComponentName("android", "FullBackupAgent");
18522 // startProcessLocked() returns existing proc's record if it's already running
18523 ProcessRecord proc = startProcessLocked(app.processName, app,
18524 false, 0, "backup", hostingName, false, false, false);
18525 if (proc == null) {
18526 Slog.e(TAG, "Unable to start backup agent process " + r);
18530 // If the app is a regular app (uid >= 10000) and not the system server or phone
18531 // process, etc, then mark it as being in full backup so that certain calls to the
18532 // process can be blocked. This is not reset to false anywhere because we kill the
18533 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18534 if (UserHandle.isApp(app.uid) &&
18535 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18536 proc.inFullBackup = true;
18539 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18540 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18542 mBackupAppName = app.packageName;
18544 // Try not to kill the process during backup
18545 updateOomAdjLocked(proc, true);
18547 // If the process is already attached, schedule the creation of the backup agent now.
18548 // If it is not yet live, this will be done when it attaches to the framework.
18549 if (proc.thread != null) {
18550 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18552 proc.thread.scheduleCreateBackupAgent(app,
18553 compatibilityInfoForPackageLocked(app), backupMode);
18554 } catch (RemoteException e) {
18555 // Will time out on the backup manager side
18558 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18560 // Invariants: at this point, the target app process exists and the application
18561 // is either already running or in the process of coming up. mBackupTarget and
18562 // mBackupAppName describe the app, so that when it binds back to the AM we
18563 // know that it's scheduled for a backup-agent operation.
18566 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18567 if (oldBackupUid != -1) {
18568 js.removeBackingUpUid(oldBackupUid);
18570 if (newBackupUid != -1) {
18571 js.addBackingUpUid(newBackupUid);
18578 public void clearPendingBackup() {
18579 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18580 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18582 synchronized (this) {
18583 mBackupTarget = null;
18584 mBackupAppName = null;
18587 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18588 js.clearAllBackingUpUids();
18591 // A backup agent has just come up
18592 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18593 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18596 synchronized(this) {
18597 if (!agentPackageName.equals(mBackupAppName)) {
18598 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18603 long oldIdent = Binder.clearCallingIdentity();
18605 IBackupManager bm = IBackupManager.Stub.asInterface(
18606 ServiceManager.getService(Context.BACKUP_SERVICE));
18607 bm.agentConnected(agentPackageName, agent);
18608 } catch (RemoteException e) {
18609 // can't happen; the backup manager service is local
18610 } catch (Exception e) {
18611 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18612 e.printStackTrace();
18614 Binder.restoreCallingIdentity(oldIdent);
18618 // done with this agent
18619 public void unbindBackupAgent(ApplicationInfo appInfo) {
18620 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18621 if (appInfo == null) {
18622 Slog.w(TAG, "unbind backup agent for null app");
18628 synchronized(this) {
18630 if (mBackupAppName == null) {
18631 Slog.w(TAG, "Unbinding backup agent with no active backup");
18635 if (!mBackupAppName.equals(appInfo.packageName)) {
18636 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18640 // Not backing this app up any more; reset its OOM adjustment
18641 final ProcessRecord proc = mBackupTarget.app;
18642 updateOomAdjLocked(proc, true);
18643 proc.inFullBackup = false;
18645 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18647 // If the app crashed during backup, 'thread' will be null here
18648 if (proc.thread != null) {
18650 proc.thread.scheduleDestroyBackupAgent(appInfo,
18651 compatibilityInfoForPackageLocked(appInfo));
18652 } catch (Exception e) {
18653 Slog.e(TAG, "Exception when unbinding backup agent:");
18654 e.printStackTrace();
18658 mBackupTarget = null;
18659 mBackupAppName = null;
18663 if (oldBackupUid != -1) {
18664 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18665 js.removeBackingUpUid(oldBackupUid);
18669 // =========================================================
18671 // =========================================================
18673 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18674 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18677 // Easy case -- we have the app's ProcessRecord.
18678 if (record != null) {
18679 return record.info.isInstantApp();
18681 // Otherwise check with PackageManager.
18682 if (callerPackage == null) {
18683 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18684 throw new IllegalArgumentException("Calling application did not provide package name");
18686 mAppOpsService.checkPackage(uid, callerPackage);
18688 IPackageManager pm = AppGlobals.getPackageManager();
18689 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18690 } catch (RemoteException e) {
18691 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18696 boolean isPendingBroadcastProcessLocked(int pid) {
18697 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18698 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18701 void skipPendingBroadcastLocked(int pid) {
18702 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18703 for (BroadcastQueue queue : mBroadcastQueues) {
18704 queue.skipPendingBroadcastLocked(pid);
18708 // The app just attached; send any pending broadcasts that it should receive
18709 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18710 boolean didSomething = false;
18711 for (BroadcastQueue queue : mBroadcastQueues) {
18712 didSomething |= queue.sendPendingBroadcastsLocked(app);
18714 return didSomething;
18717 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18718 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18720 enforceNotIsolatedCaller("registerReceiver");
18721 ArrayList<Intent> stickyIntents = null;
18722 ProcessRecord callerApp = null;
18723 final boolean visibleToInstantApps
18724 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18727 boolean instantApp;
18728 synchronized(this) {
18729 if (caller != null) {
18730 callerApp = getRecordForAppLocked(caller);
18731 if (callerApp == null) {
18732 throw new SecurityException(
18733 "Unable to find app for caller " + caller
18734 + " (pid=" + Binder.getCallingPid()
18735 + ") when registering receiver " + receiver);
18737 if (callerApp.info.uid != SYSTEM_UID &&
18738 !callerApp.pkgList.containsKey(callerPackage) &&
18739 !"android".equals(callerPackage)) {
18740 throw new SecurityException("Given caller package " + callerPackage
18741 + " is not running in process " + callerApp);
18743 callingUid = callerApp.info.uid;
18744 callingPid = callerApp.pid;
18746 callerPackage = null;
18747 callingUid = Binder.getCallingUid();
18748 callingPid = Binder.getCallingPid();
18751 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18752 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18753 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18755 Iterator<String> actions = filter.actionsIterator();
18756 if (actions == null) {
18757 ArrayList<String> noAction = new ArrayList<String>(1);
18758 noAction.add(null);
18759 actions = noAction.iterator();
18762 // Collect stickies of users
18763 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18764 while (actions.hasNext()) {
18765 String action = actions.next();
18766 for (int id : userIds) {
18767 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18768 if (stickies != null) {
18769 ArrayList<Intent> intents = stickies.get(action);
18770 if (intents != null) {
18771 if (stickyIntents == null) {
18772 stickyIntents = new ArrayList<Intent>();
18774 stickyIntents.addAll(intents);
18781 ArrayList<Intent> allSticky = null;
18782 if (stickyIntents != null) {
18783 final ContentResolver resolver = mContext.getContentResolver();
18784 // Look for any matching sticky broadcasts...
18785 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18786 Intent intent = stickyIntents.get(i);
18787 // Don't provided intents that aren't available to instant apps.
18789 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18792 // If intent has scheme "content", it will need to acccess
18793 // provider that needs to lock mProviderMap in ActivityThread
18794 // and also it may need to wait application response, so we
18795 // cannot lock ActivityManagerService here.
18796 if (filter.match(resolver, intent, true, TAG) >= 0) {
18797 if (allSticky == null) {
18798 allSticky = new ArrayList<Intent>();
18800 allSticky.add(intent);
18805 // The first sticky in the list is returned directly back to the client.
18806 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18807 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18808 if (receiver == null) {
18812 synchronized (this) {
18813 if (callerApp != null && (callerApp.thread == null
18814 || callerApp.thread.asBinder() != caller.asBinder())) {
18815 // Original caller already died
18818 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18820 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18822 if (rl.app != null) {
18823 rl.app.receivers.add(rl);
18826 receiver.asBinder().linkToDeath(rl, 0);
18827 } catch (RemoteException e) {
18830 rl.linkedToDeath = true;
18832 mRegisteredReceivers.put(receiver.asBinder(), rl);
18833 } else if (rl.uid != callingUid) {
18834 throw new IllegalArgumentException(
18835 "Receiver requested to register for uid " + callingUid
18836 + " was previously registered for uid " + rl.uid
18837 + " callerPackage is " + callerPackage);
18838 } else if (rl.pid != callingPid) {
18839 throw new IllegalArgumentException(
18840 "Receiver requested to register for pid " + callingPid
18841 + " was previously registered for pid " + rl.pid
18842 + " callerPackage is " + callerPackage);
18843 } else if (rl.userId != userId) {
18844 throw new IllegalArgumentException(
18845 "Receiver requested to register for user " + userId
18846 + " was previously registered for user " + rl.userId
18847 + " callerPackage is " + callerPackage);
18849 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18850 permission, callingUid, userId, instantApp, visibleToInstantApps);
18852 if (!bf.debugCheck()) {
18853 Slog.w(TAG, "==> For Dynamic broadcast");
18855 mReceiverResolver.addFilter(bf);
18857 // Enqueue broadcasts for all existing stickies that match
18859 if (allSticky != null) {
18860 ArrayList receivers = new ArrayList();
18863 final int stickyCount = allSticky.size();
18864 for (int i = 0; i < stickyCount; i++) {
18865 Intent intent = allSticky.get(i);
18866 BroadcastQueue queue = broadcastQueueForIntent(intent);
18867 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18868 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18869 null, 0, null, null, false, true, true, -1);
18870 queue.enqueueParallelBroadcastLocked(r);
18871 queue.scheduleBroadcastsLocked();
18879 public void unregisterReceiver(IIntentReceiver receiver) {
18880 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18882 final long origId = Binder.clearCallingIdentity();
18884 boolean doTrim = false;
18886 synchronized(this) {
18887 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18889 final BroadcastRecord r = rl.curBroadcast;
18890 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18891 final boolean doNext = r.queue.finishReceiverLocked(
18892 r, r.resultCode, r.resultData, r.resultExtras,
18893 r.resultAbort, false);
18896 r.queue.processNextBroadcast(false);
18900 if (rl.app != null) {
18901 rl.app.receivers.remove(rl);
18903 removeReceiverLocked(rl);
18904 if (rl.linkedToDeath) {
18905 rl.linkedToDeath = false;
18906 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18911 // If we actually concluded any broadcasts, we might now be able
18912 // to trim the recipients' apps from our working set
18914 trimApplications();
18919 Binder.restoreCallingIdentity(origId);
18923 void removeReceiverLocked(ReceiverList rl) {
18924 mRegisteredReceivers.remove(rl.receiver.asBinder());
18925 for (int i = rl.size() - 1; i >= 0; i--) {
18926 mReceiverResolver.removeFilter(rl.get(i));
18930 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18931 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18932 ProcessRecord r = mLruProcesses.get(i);
18933 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18935 r.thread.dispatchPackageBroadcast(cmd, packages);
18936 } catch (RemoteException ex) {
18942 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18943 int callingUid, int[] users) {
18944 // TODO: come back and remove this assumption to triage all broadcasts
18945 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18947 List<ResolveInfo> receivers = null;
18949 HashSet<ComponentName> singleUserReceivers = null;
18950 boolean scannedFirstReceivers = false;
18951 for (int user : users) {
18952 // Skip users that have Shell restrictions, with exception of always permitted
18953 // Shell broadcasts
18954 if (callingUid == SHELL_UID
18955 && mUserController.hasUserRestriction(
18956 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18957 && !isPermittedShellBroadcast(intent)) {
18960 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18961 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18962 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18963 // If this is not the system user, we need to check for
18964 // any receivers that should be filtered out.
18965 for (int i=0; i<newReceivers.size(); i++) {
18966 ResolveInfo ri = newReceivers.get(i);
18967 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18968 newReceivers.remove(i);
18973 if (newReceivers != null && newReceivers.size() == 0) {
18974 newReceivers = null;
18976 if (receivers == null) {
18977 receivers = newReceivers;
18978 } else if (newReceivers != null) {
18979 // We need to concatenate the additional receivers
18980 // found with what we have do far. This would be easy,
18981 // but we also need to de-dup any receivers that are
18983 if (!scannedFirstReceivers) {
18984 // Collect any single user receivers we had already retrieved.
18985 scannedFirstReceivers = true;
18986 for (int i=0; i<receivers.size(); i++) {
18987 ResolveInfo ri = receivers.get(i);
18988 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18989 ComponentName cn = new ComponentName(
18990 ri.activityInfo.packageName, ri.activityInfo.name);
18991 if (singleUserReceivers == null) {
18992 singleUserReceivers = new HashSet<ComponentName>();
18994 singleUserReceivers.add(cn);
18998 // Add the new results to the existing results, tracking
18999 // and de-dupping single user receivers.
19000 for (int i=0; i<newReceivers.size(); i++) {
19001 ResolveInfo ri = newReceivers.get(i);
19002 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19003 ComponentName cn = new ComponentName(
19004 ri.activityInfo.packageName, ri.activityInfo.name);
19005 if (singleUserReceivers == null) {
19006 singleUserReceivers = new HashSet<ComponentName>();
19008 if (!singleUserReceivers.contains(cn)) {
19009 singleUserReceivers.add(cn);
19018 } catch (RemoteException ex) {
19019 // pm is in same process, this will never happen.
19024 private boolean isPermittedShellBroadcast(Intent intent) {
19025 // remote bugreport should always be allowed to be taken
19026 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19029 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19030 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19031 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19032 // Don't yell about broadcasts sent via shell
19036 final String action = intent.getAction();
19037 if (isProtectedBroadcast
19038 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19039 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19040 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19041 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19042 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19043 || Intent.ACTION_MASTER_CLEAR.equals(action)
19044 || Intent.ACTION_FACTORY_RESET.equals(action)
19045 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19046 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19047 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19048 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19049 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19050 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19051 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19052 // Broadcast is either protected, or it's a public action that
19053 // we've relaxed, so it's fine for system internals to send.
19057 // This broadcast may be a problem... but there are often system components that
19058 // want to send an internal broadcast to themselves, which is annoying to have to
19059 // explicitly list each action as a protected broadcast, so we will check for that
19060 // one safe case and allow it: an explicit broadcast, only being received by something
19061 // that has protected itself.
19062 if (receivers != null && receivers.size() > 0
19063 && (intent.getPackage() != null || intent.getComponent() != null)) {
19064 boolean allProtected = true;
19065 for (int i = receivers.size()-1; i >= 0; i--) {
19066 Object target = receivers.get(i);
19067 if (target instanceof ResolveInfo) {
19068 ResolveInfo ri = (ResolveInfo)target;
19069 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19070 allProtected = false;
19074 BroadcastFilter bf = (BroadcastFilter)target;
19075 if (bf.requiredPermission == null) {
19076 allProtected = false;
19081 if (allProtected) {
19087 // The vast majority of broadcasts sent from system internals
19088 // should be protected to avoid security holes, so yell loudly
19089 // to ensure we examine these cases.
19090 if (callerApp != null) {
19091 Log.wtf(TAG, "Sending non-protected broadcast " + action
19092 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19095 Log.wtf(TAG, "Sending non-protected broadcast " + action
19096 + " from system uid " + UserHandle.formatUid(callingUid)
19097 + " pkg " + callerPackage,
19102 final int broadcastIntentLocked(ProcessRecord callerApp,
19103 String callerPackage, Intent intent, String resolvedType,
19104 IIntentReceiver resultTo, int resultCode, String resultData,
19105 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19106 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19107 intent = new Intent(intent);
19109 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19110 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19111 if (callerInstantApp) {
19112 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19115 // By default broadcasts do not go to stopped apps.
19116 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19118 // If we have not finished booting, don't allow this to launch new processes.
19119 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19120 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19123 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19124 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19125 + " ordered=" + ordered + " userid=" + userId);
19126 if ((resultTo != null) && !ordered) {
19127 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19130 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19131 ALLOW_NON_FULL, "broadcast", callerPackage);
19133 // Make sure that the user who is receiving this broadcast is running.
19134 // If not, we will just skip it. Make an exception for shutdown broadcasts
19135 // and upgrade steps.
19137 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19138 if ((callingUid != SYSTEM_UID
19139 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19140 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19141 Slog.w(TAG, "Skipping broadcast of " + intent
19142 + ": user " + userId + " is stopped");
19143 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19147 BroadcastOptions brOptions = null;
19148 if (bOptions != null) {
19149 brOptions = new BroadcastOptions(bOptions);
19150 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19151 // See if the caller is allowed to do this. Note we are checking against
19152 // the actual real caller (not whoever provided the operation as say a
19153 // PendingIntent), because that who is actually supplied the arguments.
19154 if (checkComponentPermission(
19155 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19156 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19157 != PackageManager.PERMISSION_GRANTED) {
19158 String msg = "Permission Denial: " + intent.getAction()
19159 + " broadcast from " + callerPackage + " (pid=" + callingPid
19160 + ", uid=" + callingUid + ")"
19162 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19164 throw new SecurityException(msg);
19169 // Verify that protected broadcasts are only being sent by system code,
19170 // and that system code is only sending protected broadcasts.
19171 final String action = intent.getAction();
19172 final boolean isProtectedBroadcast;
19174 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19175 } catch (RemoteException e) {
19176 Slog.w(TAG, "Remote exception", e);
19177 return ActivityManager.BROADCAST_SUCCESS;
19180 final boolean isCallerSystem;
19181 switch (UserHandle.getAppId(callingUid)) {
19185 case BLUETOOTH_UID:
19187 isCallerSystem = true;
19190 isCallerSystem = (callerApp != null) && callerApp.persistent;
19194 // First line security check before anything else: stop non-system apps from
19195 // sending protected broadcasts.
19196 if (!isCallerSystem) {
19197 if (isProtectedBroadcast) {
19198 String msg = "Permission Denial: not allowed to send broadcast "
19199 + action + " from pid="
19200 + callingPid + ", uid=" + callingUid;
19202 throw new SecurityException(msg);
19204 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19205 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19206 // Special case for compatibility: we don't want apps to send this,
19207 // but historically it has not been protected and apps may be using it
19208 // to poke their own app widget. So, instead of making it protected,
19209 // just limit it to the caller.
19210 if (callerPackage == null) {
19211 String msg = "Permission Denial: not allowed to send broadcast "
19212 + action + " from unknown caller.";
19214 throw new SecurityException(msg);
19215 } else if (intent.getComponent() != null) {
19216 // They are good enough to send to an explicit component... verify
19217 // it is being sent to the calling app.
19218 if (!intent.getComponent().getPackageName().equals(
19220 String msg = "Permission Denial: not allowed to send broadcast "
19222 + intent.getComponent().getPackageName() + " from "
19225 throw new SecurityException(msg);
19228 // Limit broadcast to their own package.
19229 intent.setPackage(callerPackage);
19234 if (action != null) {
19235 if (getBackgroundLaunchBroadcasts().contains(action)) {
19236 if (DEBUG_BACKGROUND_CHECK) {
19237 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19239 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19243 case Intent.ACTION_UID_REMOVED:
19244 case Intent.ACTION_PACKAGE_REMOVED:
19245 case Intent.ACTION_PACKAGE_CHANGED:
19246 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19247 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19248 case Intent.ACTION_PACKAGES_SUSPENDED:
19249 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19250 // Handle special intents: if this broadcast is from the package
19251 // manager about a package being removed, we need to remove all of
19252 // its activities from the history stack.
19253 if (checkComponentPermission(
19254 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19255 callingPid, callingUid, -1, true)
19256 != PackageManager.PERMISSION_GRANTED) {
19257 String msg = "Permission Denial: " + intent.getAction()
19258 + " broadcast from " + callerPackage + " (pid=" + callingPid
19259 + ", uid=" + callingUid + ")"
19261 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19263 throw new SecurityException(msg);
19266 case Intent.ACTION_UID_REMOVED:
19267 final int uid = getUidFromIntent(intent);
19269 mBatteryStatsService.removeUid(uid);
19270 mAppOpsService.uidRemoved(uid);
19273 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19274 // If resources are unavailable just force stop all those packages
19275 // and flush the attribute cache as well.
19277 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19278 if (list != null && list.length > 0) {
19279 for (int i = 0; i < list.length; i++) {
19280 forceStopPackageLocked(list[i], -1, false, true, true,
19281 false, false, userId, "storage unmount");
19283 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19284 sendPackageBroadcastLocked(
19285 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19289 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19290 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19292 case Intent.ACTION_PACKAGE_REMOVED:
19293 case Intent.ACTION_PACKAGE_CHANGED:
19294 Uri data = intent.getData();
19296 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19297 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19298 final boolean replacing =
19299 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19300 final boolean killProcess =
19301 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19302 final boolean fullUninstall = removed && !replacing;
19305 forceStopPackageLocked(ssp, UserHandle.getAppId(
19306 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19307 false, true, true, false, fullUninstall, userId,
19308 removed ? "pkg removed" : "pkg changed");
19310 final int cmd = killProcess
19311 ? ApplicationThreadConstants.PACKAGE_REMOVED
19312 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19313 sendPackageBroadcastLocked(cmd,
19314 new String[] {ssp}, userId);
19315 if (fullUninstall) {
19316 mAppOpsService.packageRemoved(
19317 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19319 // Remove all permissions granted from/to this package
19320 removeUriPermissionsForPackageLocked(ssp, userId, true);
19322 removeTasksByPackageNameLocked(ssp, userId);
19324 mServices.forceStopPackageLocked(ssp, userId);
19326 // Hide the "unsupported display" dialog if necessary.
19327 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19328 mUnsupportedDisplaySizeDialog.getPackageName())) {
19329 mUnsupportedDisplaySizeDialog.dismiss();
19330 mUnsupportedDisplaySizeDialog = null;
19332 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19333 mBatteryStatsService.notePackageUninstalled(ssp);
19337 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19338 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19339 userId, ProcessList.INVALID_ADJ,
19340 false, true, true, false, "change " + ssp);
19342 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19343 intent.getStringArrayExtra(
19344 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19348 case Intent.ACTION_PACKAGES_SUSPENDED:
19349 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19350 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19351 intent.getAction());
19352 final String[] packageNames = intent.getStringArrayExtra(
19353 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19354 final int userHandle = intent.getIntExtra(
19355 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19357 synchronized(ActivityManagerService.this) {
19358 mRecentTasks.onPackagesSuspendedChanged(
19359 packageNames, suspended, userHandle);
19364 case Intent.ACTION_PACKAGE_REPLACED:
19366 final Uri data = intent.getData();
19368 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19369 ApplicationInfo aInfo = null;
19371 aInfo = AppGlobals.getPackageManager()
19372 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19373 } catch (RemoteException ignore) {}
19374 if (aInfo == null) {
19375 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19376 + " ssp=" + ssp + " data=" + data);
19377 return ActivityManager.BROADCAST_SUCCESS;
19379 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19380 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19381 new String[] {ssp}, userId);
19385 case Intent.ACTION_PACKAGE_ADDED:
19387 // Special case for adding a package: by default turn on compatibility mode.
19388 Uri data = intent.getData();
19390 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19391 final boolean replacing =
19392 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19393 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19396 ApplicationInfo ai = AppGlobals.getPackageManager().
19397 getApplicationInfo(ssp, 0, 0);
19398 mBatteryStatsService.notePackageInstalled(ssp,
19399 ai != null ? ai.versionCode : 0);
19400 } catch (RemoteException e) {
19405 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19407 Uri data = intent.getData();
19409 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19410 // Hide the "unsupported display" dialog if necessary.
19411 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19412 mUnsupportedDisplaySizeDialog.getPackageName())) {
19413 mUnsupportedDisplaySizeDialog.dismiss();
19414 mUnsupportedDisplaySizeDialog = null;
19416 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19420 case Intent.ACTION_TIMEZONE_CHANGED:
19421 // If this is the time zone changed action, queue up a message that will reset
19422 // the timezone of all currently running processes. This message will get
19423 // queued up before the broadcast happens.
19424 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19426 case Intent.ACTION_TIME_CHANGED:
19427 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19428 // the tri-state value it may contain and "unknown".
19429 // For convenience we re-use the Intent extra values.
19430 final int NO_EXTRA_VALUE_FOUND = -1;
19431 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19432 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19433 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19434 // Only send a message if the time preference is available.
19435 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19436 Message updateTimePreferenceMsg =
19437 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19438 timeFormatPreferenceMsgValue, 0);
19439 mHandler.sendMessage(updateTimePreferenceMsg);
19441 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19442 synchronized (stats) {
19443 stats.noteCurrentTimeChangedLocked();
19446 case Intent.ACTION_CLEAR_DNS_CACHE:
19447 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19449 case Proxy.PROXY_CHANGE_ACTION:
19450 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19451 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19453 case android.hardware.Camera.ACTION_NEW_PICTURE:
19454 case android.hardware.Camera.ACTION_NEW_VIDEO:
19455 // In N we just turned these off; in O we are turing them back on partly,
19456 // only for registered receivers. This will still address the main problem
19457 // (a spam of apps waking up when a picture is taken putting significant
19458 // memory pressure on the system at a bad point), while still allowing apps
19459 // that are already actively running to know about this happening.
19460 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19462 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19463 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19465 case "com.android.launcher.action.INSTALL_SHORTCUT":
19466 // As of O, we no longer support this broadcasts, even for pre-O apps.
19467 // Apps should now be using ShortcutManager.pinRequestShortcut().
19468 Log.w(TAG, "Broadcast " + action
19469 + " no longer supported. It will not be delivered.");
19470 return ActivityManager.BROADCAST_SUCCESS;
19473 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19474 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19475 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19476 final int uid = getUidFromIntent(intent);
19478 final UidRecord uidRec = mActiveUids.get(uid);
19479 if (uidRec != null) {
19480 uidRec.updateHasInternetPermission();
19486 // Add to the sticky list if requested.
19488 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19489 callingPid, callingUid)
19490 != PackageManager.PERMISSION_GRANTED) {
19491 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19492 + callingPid + ", uid=" + callingUid
19493 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19495 throw new SecurityException(msg);
19497 if (requiredPermissions != null && requiredPermissions.length > 0) {
19498 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19499 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19500 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19502 if (intent.getComponent() != null) {
19503 throw new SecurityException(
19504 "Sticky broadcasts can't target a specific component");
19506 // We use userId directly here, since the "all" target is maintained
19507 // as a separate set of sticky broadcasts.
19508 if (userId != UserHandle.USER_ALL) {
19509 // But first, if this is not a broadcast to all users, then
19510 // make sure it doesn't conflict with an existing broadcast to
19512 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19513 UserHandle.USER_ALL);
19514 if (stickies != null) {
19515 ArrayList<Intent> list = stickies.get(intent.getAction());
19516 if (list != null) {
19517 int N = list.size();
19519 for (i=0; i<N; i++) {
19520 if (intent.filterEquals(list.get(i))) {
19521 throw new IllegalArgumentException(
19522 "Sticky broadcast " + intent + " for user "
19523 + userId + " conflicts with existing global broadcast");
19529 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19530 if (stickies == null) {
19531 stickies = new ArrayMap<>();
19532 mStickyBroadcasts.put(userId, stickies);
19534 ArrayList<Intent> list = stickies.get(intent.getAction());
19535 if (list == null) {
19536 list = new ArrayList<>();
19537 stickies.put(intent.getAction(), list);
19539 final int stickiesCount = list.size();
19541 for (i = 0; i < stickiesCount; i++) {
19542 if (intent.filterEquals(list.get(i))) {
19543 // This sticky already exists, replace it.
19544 list.set(i, new Intent(intent));
19548 if (i >= stickiesCount) {
19549 list.add(new Intent(intent));
19554 if (userId == UserHandle.USER_ALL) {
19555 // Caller wants broadcast to go to all started users.
19556 users = mUserController.getStartedUserArrayLocked();
19558 // Caller wants broadcast to go to one specific user.
19559 users = new int[] {userId};
19562 // Figure out who all will receive this broadcast.
19563 List receivers = null;
19564 List<BroadcastFilter> registeredReceivers = null;
19565 // Need to resolve the intent to interested receivers...
19566 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19568 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19570 if (intent.getComponent() == null) {
19571 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19572 // Query one target user at a time, excluding shell-restricted users
19573 for (int i = 0; i < users.length; i++) {
19574 if (mUserController.hasUserRestriction(
19575 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19578 List<BroadcastFilter> registeredReceiversForUser =
19579 mReceiverResolver.queryIntent(intent,
19580 resolvedType, false /*defaultOnly*/, users[i]);
19581 if (registeredReceivers == null) {
19582 registeredReceivers = registeredReceiversForUser;
19583 } else if (registeredReceiversForUser != null) {
19584 registeredReceivers.addAll(registeredReceiversForUser);
19588 registeredReceivers = mReceiverResolver.queryIntent(intent,
19589 resolvedType, false /*defaultOnly*/, userId);
19593 final boolean replacePending =
19594 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19596 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19597 + " replacePending=" + replacePending);
19599 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19600 if (!ordered && NR > 0) {
19601 // If we are not serializing this broadcast, then send the
19602 // registered receivers separately so they don't wait for the
19603 // components to be launched.
19604 if (isCallerSystem) {
19605 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19606 isProtectedBroadcast, registeredReceivers);
19608 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19609 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19610 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19611 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19612 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19613 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19614 final boolean replaced = replacePending
19615 && (queue.replaceParallelBroadcastLocked(r) != null);
19616 // Note: We assume resultTo is null for non-ordered broadcasts.
19618 queue.enqueueParallelBroadcastLocked(r);
19619 queue.scheduleBroadcastsLocked();
19621 registeredReceivers = null;
19625 // Merge into one list.
19627 if (receivers != null) {
19628 // A special case for PACKAGE_ADDED: do not allow the package
19629 // being added to see this broadcast. This prevents them from
19630 // using this as a back door to get run as soon as they are
19631 // installed. Maybe in the future we want to have a special install
19632 // broadcast or such for apps, but we'd like to deliberately make
19634 String skipPackages[] = null;
19635 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19636 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19637 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19638 Uri data = intent.getData();
19639 if (data != null) {
19640 String pkgName = data.getSchemeSpecificPart();
19641 if (pkgName != null) {
19642 skipPackages = new String[] { pkgName };
19645 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19646 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19648 if (skipPackages != null && (skipPackages.length > 0)) {
19649 for (String skipPackage : skipPackages) {
19650 if (skipPackage != null) {
19651 int NT = receivers.size();
19652 for (int it=0; it<NT; it++) {
19653 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19654 if (curt.activityInfo.packageName.equals(skipPackage)) {
19655 receivers.remove(it);
19664 int NT = receivers != null ? receivers.size() : 0;
19666 ResolveInfo curt = null;
19667 BroadcastFilter curr = null;
19668 while (it < NT && ir < NR) {
19669 if (curt == null) {
19670 curt = (ResolveInfo)receivers.get(it);
19672 if (curr == null) {
19673 curr = registeredReceivers.get(ir);
19675 if (curr.getPriority() >= curt.priority) {
19676 // Insert this broadcast record into the final list.
19677 receivers.add(it, curr);
19683 // Skip to the next ResolveInfo in the final list.
19690 if (receivers == null) {
19691 receivers = new ArrayList();
19693 receivers.add(registeredReceivers.get(ir));
19697 if (isCallerSystem) {
19698 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19699 isProtectedBroadcast, receivers);
19702 if ((receivers != null && receivers.size() > 0)
19703 || resultTo != null) {
19704 BroadcastQueue queue = broadcastQueueForIntent(intent);
19705 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19706 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19707 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19708 resultData, resultExtras, ordered, sticky, false, userId);
19710 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19711 + ": prev had " + queue.mOrderedBroadcasts.size());
19712 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19713 "Enqueueing broadcast " + r.intent.getAction());
19715 final BroadcastRecord oldRecord =
19716 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19717 if (oldRecord != null) {
19718 // Replaced, fire the result-to receiver.
19719 if (oldRecord.resultTo != null) {
19720 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19722 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19724 Activity.RESULT_CANCELED, null, null,
19725 false, false, oldRecord.userId);
19726 } catch (RemoteException e) {
19727 Slog.w(TAG, "Failure ["
19728 + queue.mQueueName + "] sending broadcast result of "
19734 queue.enqueueOrderedBroadcastLocked(r);
19735 queue.scheduleBroadcastsLocked();
19738 // There was nobody interested in the broadcast, but we still want to record
19739 // that it happened.
19740 if (intent.getComponent() == null && intent.getPackage() == null
19741 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19742 // This was an implicit broadcast... let's record it for posterity.
19743 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19747 return ActivityManager.BROADCAST_SUCCESS;
19751 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19753 private int getUidFromIntent(Intent intent) {
19754 if (intent == null) {
19757 final Bundle intentExtras = intent.getExtras();
19758 return intent.hasExtra(Intent.EXTRA_UID)
19759 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19762 final void rotateBroadcastStatsIfNeededLocked() {
19763 final long now = SystemClock.elapsedRealtime();
19764 if (mCurBroadcastStats == null ||
19765 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19766 mLastBroadcastStats = mCurBroadcastStats;
19767 if (mLastBroadcastStats != null) {
19768 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19769 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19771 mCurBroadcastStats = new BroadcastStats();
19775 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19776 int skipCount, long dispatchTime) {
19777 rotateBroadcastStatsIfNeededLocked();
19778 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19781 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19782 rotateBroadcastStatsIfNeededLocked();
19783 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19786 final Intent verifyBroadcastLocked(Intent intent) {
19787 // Refuse possible leaked file descriptors
19788 if (intent != null && intent.hasFileDescriptors() == true) {
19789 throw new IllegalArgumentException("File descriptors passed in Intent");
19792 int flags = intent.getFlags();
19794 if (!mProcessesReady) {
19795 // if the caller really truly claims to know what they're doing, go
19796 // ahead and allow the broadcast without launching any receivers
19797 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19798 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19799 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19800 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19801 + " before boot completion");
19802 throw new IllegalStateException("Cannot broadcast before boot completed");
19806 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19807 throw new IllegalArgumentException(
19808 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19811 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19812 switch (Binder.getCallingUid()) {
19817 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19818 + Binder.getCallingUid());
19819 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19827 public final int broadcastIntent(IApplicationThread caller,
19828 Intent intent, String resolvedType, IIntentReceiver resultTo,
19829 int resultCode, String resultData, Bundle resultExtras,
19830 String[] requiredPermissions, int appOp, Bundle bOptions,
19831 boolean serialized, boolean sticky, int userId) {
19832 enforceNotIsolatedCaller("broadcastIntent");
19833 synchronized(this) {
19834 intent = verifyBroadcastLocked(intent);
19836 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19837 final int callingPid = Binder.getCallingPid();
19838 final int callingUid = Binder.getCallingUid();
19839 final long origId = Binder.clearCallingIdentity();
19840 int res = broadcastIntentLocked(callerApp,
19841 callerApp != null ? callerApp.info.packageName : null,
19842 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19843 requiredPermissions, appOp, bOptions, serialized, sticky,
19844 callingPid, callingUid, userId);
19845 Binder.restoreCallingIdentity(origId);
19851 int broadcastIntentInPackage(String packageName, int uid,
19852 Intent intent, String resolvedType, IIntentReceiver resultTo,
19853 int resultCode, String resultData, Bundle resultExtras,
19854 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19856 synchronized(this) {
19857 intent = verifyBroadcastLocked(intent);
19859 final long origId = Binder.clearCallingIdentity();
19860 String[] requiredPermissions = requiredPermission == null ? null
19861 : new String[] {requiredPermission};
19862 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19863 resultTo, resultCode, resultData, resultExtras,
19864 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19865 sticky, -1, uid, userId);
19866 Binder.restoreCallingIdentity(origId);
19871 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19872 // Refuse possible leaked file descriptors
19873 if (intent != null && intent.hasFileDescriptors() == true) {
19874 throw new IllegalArgumentException("File descriptors passed in Intent");
19877 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19878 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19880 synchronized(this) {
19881 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19882 != PackageManager.PERMISSION_GRANTED) {
19883 String msg = "Permission Denial: unbroadcastIntent() from pid="
19884 + Binder.getCallingPid()
19885 + ", uid=" + Binder.getCallingUid()
19886 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19888 throw new SecurityException(msg);
19890 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19891 if (stickies != null) {
19892 ArrayList<Intent> list = stickies.get(intent.getAction());
19893 if (list != null) {
19894 int N = list.size();
19896 for (i=0; i<N; i++) {
19897 if (intent.filterEquals(list.get(i))) {
19902 if (list.size() <= 0) {
19903 stickies.remove(intent.getAction());
19906 if (stickies.size() <= 0) {
19907 mStickyBroadcasts.remove(userId);
19913 void backgroundServicesFinishedLocked(int userId) {
19914 for (BroadcastQueue queue : mBroadcastQueues) {
19915 queue.backgroundServicesFinishedLocked(userId);
19919 public void finishReceiver(IBinder who, int resultCode, String resultData,
19920 Bundle resultExtras, boolean resultAbort, int flags) {
19921 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19923 // Refuse possible leaked file descriptors
19924 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19925 throw new IllegalArgumentException("File descriptors passed in Bundle");
19928 final long origId = Binder.clearCallingIdentity();
19930 boolean doNext = false;
19933 synchronized(this) {
19934 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19935 ? mFgBroadcastQueue : mBgBroadcastQueue;
19936 r = queue.getMatchingOrderedReceiver(who);
19938 doNext = r.queue.finishReceiverLocked(r, resultCode,
19939 resultData, resultExtras, resultAbort, true);
19944 r.queue.processNextBroadcast(false);
19946 trimApplications();
19948 Binder.restoreCallingIdentity(origId);
19952 // =========================================================
19954 // =========================================================
19956 public boolean startInstrumentation(ComponentName className,
19957 String profileFile, int flags, Bundle arguments,
19958 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19959 int userId, String abiOverride) {
19960 enforceNotIsolatedCaller("startInstrumentation");
19961 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19962 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19963 // Refuse possible leaked file descriptors
19964 if (arguments != null && arguments.hasFileDescriptors()) {
19965 throw new IllegalArgumentException("File descriptors passed in Bundle");
19968 synchronized(this) {
19969 InstrumentationInfo ii = null;
19970 ApplicationInfo ai = null;
19972 ii = mContext.getPackageManager().getInstrumentationInfo(
19973 className, STOCK_PM_FLAGS);
19974 ai = AppGlobals.getPackageManager().getApplicationInfo(
19975 ii.targetPackage, STOCK_PM_FLAGS, userId);
19976 } catch (PackageManager.NameNotFoundException e) {
19977 } catch (RemoteException e) {
19980 reportStartInstrumentationFailureLocked(watcher, className,
19981 "Unable to find instrumentation info for: " + className);
19985 reportStartInstrumentationFailureLocked(watcher, className,
19986 "Unable to find instrumentation target package: " + ii.targetPackage);
19989 if (!ai.hasCode()) {
19990 reportStartInstrumentationFailureLocked(watcher, className,
19991 "Instrumentation target has no code: " + ii.targetPackage);
19995 int match = mContext.getPackageManager().checkSignatures(
19996 ii.targetPackage, ii.packageName);
19997 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19998 String msg = "Permission Denial: starting instrumentation "
19999 + className + " from pid="
20000 + Binder.getCallingPid()
20001 + ", uid=" + Binder.getCallingPid()
20002 + " not allowed because package " + ii.packageName
20003 + " does not have a signature matching the target "
20004 + ii.targetPackage;
20005 reportStartInstrumentationFailureLocked(watcher, className, msg);
20006 throw new SecurityException(msg);
20009 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20010 activeInstr.mClass = className;
20011 String defProcess = ai.processName;;
20012 if (ii.targetProcesses == null) {
20013 activeInstr.mTargetProcesses = new String[]{ai.processName};
20014 } else if (ii.targetProcesses.equals("*")) {
20015 activeInstr.mTargetProcesses = new String[0];
20017 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20018 defProcess = activeInstr.mTargetProcesses[0];
20020 activeInstr.mTargetInfo = ai;
20021 activeInstr.mProfileFile = profileFile;
20022 activeInstr.mArguments = arguments;
20023 activeInstr.mWatcher = watcher;
20024 activeInstr.mUiAutomationConnection = uiAutomationConnection;
20025 activeInstr.mResultClass = className;
20027 final long origId = Binder.clearCallingIdentity();
20028 // Instrumentation can kill and relaunch even persistent processes
20029 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20031 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20032 app.instr = activeInstr;
20033 activeInstr.mFinished = false;
20034 activeInstr.mRunningProcesses.add(app);
20035 if (!mActiveInstrumentation.contains(activeInstr)) {
20036 mActiveInstrumentation.add(activeInstr);
20038 Binder.restoreCallingIdentity(origId);
20045 * Report errors that occur while attempting to start Instrumentation. Always writes the
20046 * error to the logs, but if somebody is watching, send the report there too. This enables
20047 * the "am" command to report errors with more information.
20049 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
20050 * @param cn The component name of the instrumentation.
20051 * @param report The error report.
20053 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20054 ComponentName cn, String report) {
20055 Slog.w(TAG, report);
20056 if (watcher != null) {
20057 Bundle results = new Bundle();
20058 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20059 results.putString("Error", report);
20060 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20064 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20065 if (app.instr == null) {
20066 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20070 if (!app.instr.mFinished && results != null) {
20071 if (app.instr.mCurResults == null) {
20072 app.instr.mCurResults = new Bundle(results);
20074 app.instr.mCurResults.putAll(results);
20079 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20080 int userId = UserHandle.getCallingUserId();
20081 // Refuse possible leaked file descriptors
20082 if (results != null && results.hasFileDescriptors()) {
20083 throw new IllegalArgumentException("File descriptors passed in Intent");
20086 synchronized(this) {
20087 ProcessRecord app = getRecordForAppLocked(target);
20089 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20092 final long origId = Binder.clearCallingIdentity();
20093 addInstrumentationResultsLocked(app, results);
20094 Binder.restoreCallingIdentity(origId);
20098 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20099 if (app.instr == null) {
20100 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20104 if (!app.instr.mFinished) {
20105 if (app.instr.mWatcher != null) {
20106 Bundle finalResults = app.instr.mCurResults;
20107 if (finalResults != null) {
20108 if (app.instr.mCurResults != null && results != null) {
20109 finalResults.putAll(results);
20112 finalResults = results;
20114 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20115 app.instr.mClass, resultCode, finalResults);
20118 // Can't call out of the system process with a lock held, so post a message.
20119 if (app.instr.mUiAutomationConnection != null) {
20120 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20121 app.instr.mUiAutomationConnection).sendToTarget();
20123 app.instr.mFinished = true;
20126 app.instr.removeProcess(app);
20129 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20133 public void finishInstrumentation(IApplicationThread target,
20134 int resultCode, Bundle results) {
20135 int userId = UserHandle.getCallingUserId();
20136 // Refuse possible leaked file descriptors
20137 if (results != null && results.hasFileDescriptors()) {
20138 throw new IllegalArgumentException("File descriptors passed in Intent");
20141 synchronized(this) {
20142 ProcessRecord app = getRecordForAppLocked(target);
20144 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20147 final long origId = Binder.clearCallingIdentity();
20148 finishInstrumentationLocked(app, resultCode, results);
20149 Binder.restoreCallingIdentity(origId);
20153 // =========================================================
20155 // =========================================================
20157 public ConfigurationInfo getDeviceConfigurationInfo() {
20158 ConfigurationInfo config = new ConfigurationInfo();
20159 synchronized (this) {
20160 final Configuration globalConfig = getGlobalConfiguration();
20161 config.reqTouchScreen = globalConfig.touchscreen;
20162 config.reqKeyboardType = globalConfig.keyboard;
20163 config.reqNavigation = globalConfig.navigation;
20164 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20165 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20166 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20168 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20169 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20170 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20172 config.reqGlEsVersion = GL_ES_VERSION;
20177 ActivityStack getFocusedStack() {
20178 return mStackSupervisor.getFocusedStack();
20182 public int getFocusedStackId() throws RemoteException {
20183 ActivityStack focusedStack = getFocusedStack();
20184 if (focusedStack != null) {
20185 return focusedStack.getStackId();
20190 public Configuration getConfiguration() {
20192 synchronized(this) {
20193 ci = new Configuration(getGlobalConfiguration());
20194 ci.userSetLocale = false;
20200 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20201 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20202 synchronized (this) {
20203 mSuppressResizeConfigChanges = suppress;
20208 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20209 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20210 * activity and clearing the task at the same time.
20213 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20214 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20215 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20216 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20218 synchronized (this) {
20219 final long origId = Binder.clearCallingIdentity();
20221 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20223 Binder.restoreCallingIdentity(origId);
20229 public void updatePersistentConfiguration(Configuration values) {
20230 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20231 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20232 if (values == null) {
20233 throw new NullPointerException("Configuration must not be null");
20236 int userId = UserHandle.getCallingUserId();
20238 synchronized(this) {
20239 updatePersistentConfigurationLocked(values, userId);
20243 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20244 final long origId = Binder.clearCallingIdentity();
20246 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20248 Binder.restoreCallingIdentity(origId);
20252 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20253 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20254 FONT_SCALE, 1.0f, userId);
20256 synchronized (this) {
20257 if (getGlobalConfiguration().fontScale == scaleFactor) {
20261 final Configuration configuration
20262 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20263 configuration.fontScale = scaleFactor;
20264 updatePersistentConfigurationLocked(configuration, userId);
20268 private void enforceWriteSettingsPermission(String func) {
20269 int uid = Binder.getCallingUid();
20270 if (uid == ROOT_UID) {
20274 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20275 Settings.getPackageNameForUid(mContext, uid), false)) {
20279 String msg = "Permission Denial: " + func + " from pid="
20280 + Binder.getCallingPid()
20282 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20284 throw new SecurityException(msg);
20288 public boolean updateConfiguration(Configuration values) {
20289 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20291 synchronized(this) {
20292 if (values == null && mWindowManager != null) {
20293 // sentinel: fetch the current configuration from the window manager
20294 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20297 if (mWindowManager != null) {
20298 // Update OOM levels based on display size.
20299 mProcessList.applyDisplaySize(mWindowManager);
20302 final long origId = Binder.clearCallingIdentity();
20304 if (values != null) {
20305 Settings.System.clearConfiguration(values);
20307 updateConfigurationLocked(values, null, false, false /* persistent */,
20308 UserHandle.USER_NULL, false /* deferResume */,
20309 mTmpUpdateConfigurationResult);
20310 return mTmpUpdateConfigurationResult.changes != 0;
20312 Binder.restoreCallingIdentity(origId);
20317 void updateUserConfigurationLocked() {
20318 final Configuration configuration = new Configuration(getGlobalConfiguration());
20319 final int currentUserId = mUserController.getCurrentUserIdLocked();
20320 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20321 currentUserId, Settings.System.canWrite(mContext));
20322 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20323 false /* persistent */, currentUserId, false /* deferResume */);
20326 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20327 boolean initLocale) {
20328 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20331 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20332 boolean initLocale, boolean deferResume) {
20333 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20334 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20335 UserHandle.USER_NULL, deferResume);
20338 // To cache the list of supported system locales
20339 private String[] mSupportedSystemLocales = null;
20341 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20342 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20343 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20344 deferResume, null /* result */);
20348 * Do either or both things: (1) change the current configuration, and (2)
20349 * make sure the given activity is running with the (now) current
20350 * configuration. Returns true if the activity has been left running, or
20351 * false if <var>starting</var> is being destroyed to match the new
20354 * @param userId is only used when persistent parameter is set to true to persist configuration
20355 * for that particular user
20357 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20358 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20359 UpdateConfigurationResult result) {
20361 boolean kept = true;
20363 if (mWindowManager != null) {
20364 mWindowManager.deferSurfaceLayout();
20367 if (values != null) {
20368 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20372 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20374 if (mWindowManager != null) {
20375 mWindowManager.continueSurfaceLayout();
20379 if (result != null) {
20380 result.changes = changes;
20381 result.activityRelaunched = !kept;
20386 /** Update default (global) configuration and notify listeners about changes. */
20387 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20388 boolean persistent, int userId, boolean deferResume) {
20389 mTempConfig.setTo(getGlobalConfiguration());
20390 final int changes = mTempConfig.updateFrom(values);
20391 if (changes == 0) {
20392 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20393 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20394 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20395 // (even if there are no actual changes) to unfreeze the window.
20396 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20400 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20401 "Updating global configuration to: " + values);
20403 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20405 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20406 final LocaleList locales = values.getLocales();
20407 int bestLocaleIndex = 0;
20408 if (locales.size() > 1) {
20409 if (mSupportedSystemLocales == null) {
20410 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20412 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20414 SystemProperties.set("persist.sys.locale",
20415 locales.get(bestLocaleIndex).toLanguageTag());
20416 LocaleList.setDefault(locales, bestLocaleIndex);
20417 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20418 locales.get(bestLocaleIndex)));
20421 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20422 mTempConfig.seq = mConfigurationSeq;
20424 // Update stored global config and notify everyone about the change.
20425 mStackSupervisor.onConfigurationChanged(mTempConfig);
20427 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20428 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20429 mUsageStatsService.reportConfigurationChange(mTempConfig,
20430 mUserController.getCurrentUserIdLocked());
20432 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20433 mShowDialogs = shouldShowDialogs(mTempConfig);
20435 AttributeCache ac = AttributeCache.instance();
20437 ac.updateConfiguration(mTempConfig);
20440 // Make sure all resources in our process are updated right now, so that anyone who is going
20441 // to retrieve resource values after we return will be sure to get the new ones. This is
20442 // especially important during boot, where the first config change needs to guarantee all
20443 // resources have that config before following boot code is executed.
20444 mSystemThread.applyConfigurationToResources(mTempConfig);
20446 // We need another copy of global config because we're scheduling some calls instead of
20447 // running them in place. We need to be sure that object we send will be handled unchanged.
20448 final Configuration configCopy = new Configuration(mTempConfig);
20449 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20450 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20451 msg.obj = configCopy;
20453 mHandler.sendMessage(msg);
20456 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20457 ProcessRecord app = mLruProcesses.get(i);
20459 if (app.thread != null) {
20460 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20461 + app.processName + " new config " + configCopy);
20462 app.thread.scheduleConfigurationChanged(configCopy);
20464 } catch (Exception e) {
20468 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20469 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20470 | Intent.FLAG_RECEIVER_FOREGROUND
20471 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20472 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20473 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20474 UserHandle.USER_ALL);
20475 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20476 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20477 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20478 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20479 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20480 if (initLocale || !mProcessesReady) {
20481 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20483 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20484 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20485 UserHandle.USER_ALL);
20488 // Override configuration of the default display duplicates global config, so we need to
20489 // update it also. This will also notify WindowManager about changes.
20490 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20497 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20498 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20500 synchronized (this) {
20501 // Check if display is initialized in AM.
20502 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20503 // Call might come when display is not yet added or has already been removed.
20504 if (DEBUG_CONFIGURATION) {
20505 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20511 if (values == null && mWindowManager != null) {
20512 // sentinel: fetch the current configuration from the window manager
20513 values = mWindowManager.computeNewConfiguration(displayId);
20516 if (mWindowManager != null) {
20517 // Update OOM levels based on display size.
20518 mProcessList.applyDisplaySize(mWindowManager);
20521 final long origId = Binder.clearCallingIdentity();
20523 if (values != null) {
20524 Settings.System.clearConfiguration(values);
20526 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20527 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20528 return mTmpUpdateConfigurationResult.changes != 0;
20530 Binder.restoreCallingIdentity(origId);
20535 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20536 boolean deferResume, int displayId) {
20537 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20538 displayId, null /* result */);
20542 * Updates override configuration specific for the selected display. If no config is provided,
20543 * new one will be computed in WM based on current display info.
20545 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20546 ActivityRecord starting, boolean deferResume, int displayId,
20547 UpdateConfigurationResult result) {
20549 boolean kept = true;
20551 if (mWindowManager != null) {
20552 mWindowManager.deferSurfaceLayout();
20555 if (values != null) {
20556 if (displayId == DEFAULT_DISPLAY) {
20557 // Override configuration of the default display duplicates global config, so
20558 // we're calling global config update instead for default display. It will also
20559 // apply the correct override config.
20560 changes = updateGlobalConfiguration(values, false /* initLocale */,
20561 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20563 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20567 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20569 if (mWindowManager != null) {
20570 mWindowManager.continueSurfaceLayout();
20574 if (result != null) {
20575 result.changes = changes;
20576 result.activityRelaunched = !kept;
20581 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20583 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20584 final int changes = mTempConfig.updateFrom(values);
20585 if (changes != 0) {
20586 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20587 + mTempConfig + " for displayId=" + displayId);
20588 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20590 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20591 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20592 // Reset the unsupported display size dialog.
20593 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20595 killAllBackgroundProcessesExcept(N,
20596 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20600 // Update the configuration with WM first and check if any of the stacks need to be resized
20601 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20602 // necessary. This way we don't need to relaunch again afterwards in
20603 // ensureActivityConfigurationLocked().
20604 if (mWindowManager != null) {
20605 final int[] resizedStacks =
20606 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20607 if (resizedStacks != null) {
20608 for (int stackId : resizedStacks) {
20609 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20617 /** Applies latest configuration and/or visibility updates if needed. */
20618 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20619 boolean kept = true;
20620 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20621 // mainStack is null during startup.
20622 if (mainStack != null) {
20623 if (changes != 0 && starting == null) {
20624 // If the configuration changed, and the caller is not already
20625 // in the process of starting an activity, then find the top
20626 // activity to check if its configuration needs to change.
20627 starting = mainStack.topRunningActivityLocked();
20630 if (starting != null) {
20631 kept = starting.ensureActivityConfigurationLocked(changes,
20632 false /* preserveWindow */);
20633 // And we need to make sure at this point that all other activities
20634 // are made visible with the correct configuration.
20635 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20636 !PRESERVE_WINDOWS);
20643 /** Helper method that requests bounds from WM and applies them to stack. */
20644 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20645 final Rect newStackBounds = new Rect();
20646 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20647 mStackSupervisor.resizeStackLocked(
20648 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20649 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20650 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20654 * Decide based on the configuration whether we should show the ANR,
20655 * crash, etc dialogs. The idea is that if there is no affordance to
20656 * press the on-screen buttons, or the user experience would be more
20657 * greatly impacted than the crash itself, we shouldn't show the dialog.
20659 * A thought: SystemUI might also want to get told about this, the Power
20660 * dialog / global actions also might want different behaviors.
20662 private static boolean shouldShowDialogs(Configuration config) {
20663 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20664 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20665 && config.navigation == Configuration.NAVIGATION_NONAV);
20666 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20667 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20668 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20669 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20670 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20671 return inputMethodExists && uiModeSupportsDialogs;
20675 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20676 synchronized (this) {
20677 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20678 if (srec != null) {
20679 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20685 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20686 Intent resultData) {
20688 synchronized (this) {
20689 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20691 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20697 public int getLaunchedFromUid(IBinder activityToken) {
20698 ActivityRecord srec;
20699 synchronized (this) {
20700 srec = ActivityRecord.forTokenLocked(activityToken);
20702 if (srec == null) {
20705 return srec.launchedFromUid;
20708 public String getLaunchedFromPackage(IBinder activityToken) {
20709 ActivityRecord srec;
20710 synchronized (this) {
20711 srec = ActivityRecord.forTokenLocked(activityToken);
20713 if (srec == null) {
20716 return srec.launchedFromPackage;
20719 // =========================================================
20720 // LIFETIME MANAGEMENT
20721 // =========================================================
20723 // Returns whether the app is receiving broadcast.
20724 // If receiving, fetch all broadcast queues which the app is
20725 // the current [or imminent] receiver on.
20726 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20727 ArraySet<BroadcastQueue> receivingQueues) {
20728 if (!app.curReceivers.isEmpty()) {
20729 for (BroadcastRecord r : app.curReceivers) {
20730 receivingQueues.add(r.queue);
20735 // It's not the current receiver, but it might be starting up to become one
20736 for (BroadcastQueue queue : mBroadcastQueues) {
20737 final BroadcastRecord r = queue.mPendingBroadcast;
20738 if (r != null && r.curApp == app) {
20739 // found it; report which queue it's in
20740 receivingQueues.add(queue);
20744 return !receivingQueues.isEmpty();
20747 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20748 int targetUid, ComponentName targetComponent, String targetProcess) {
20749 if (!mTrackingAssociations) {
20752 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20753 = mAssociations.get(targetUid);
20754 if (components == null) {
20755 components = new ArrayMap<>();
20756 mAssociations.put(targetUid, components);
20758 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20759 if (sourceUids == null) {
20760 sourceUids = new SparseArray<>();
20761 components.put(targetComponent, sourceUids);
20763 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20764 if (sourceProcesses == null) {
20765 sourceProcesses = new ArrayMap<>();
20766 sourceUids.put(sourceUid, sourceProcesses);
20768 Association ass = sourceProcesses.get(sourceProcess);
20770 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20772 sourceProcesses.put(sourceProcess, ass);
20776 if (ass.mNesting == 1) {
20777 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20778 ass.mLastState = sourceState;
20783 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20784 ComponentName targetComponent) {
20785 if (!mTrackingAssociations) {
20788 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20789 = mAssociations.get(targetUid);
20790 if (components == null) {
20793 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20794 if (sourceUids == null) {
20797 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20798 if (sourceProcesses == null) {
20801 Association ass = sourceProcesses.get(sourceProcess);
20802 if (ass == null || ass.mNesting <= 0) {
20806 if (ass.mNesting == 0) {
20807 long uptime = SystemClock.uptimeMillis();
20808 ass.mTime += uptime - ass.mStartTime;
20809 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20810 += uptime - ass.mLastStateUptime;
20811 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20815 private void noteUidProcessState(final int uid, final int state) {
20816 mBatteryStatsService.noteUidProcessState(uid, state);
20817 if (mTrackingAssociations) {
20818 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20819 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20820 = mAssociations.valueAt(i1);
20821 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20822 SparseArray<ArrayMap<String, Association>> sourceUids
20823 = targetComponents.valueAt(i2);
20824 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20825 if (sourceProcesses != null) {
20826 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20827 Association ass = sourceProcesses.valueAt(i4);
20828 if (ass.mNesting >= 1) {
20829 // currently associated
20830 long uptime = SystemClock.uptimeMillis();
20831 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20832 += uptime - ass.mLastStateUptime;
20833 ass.mLastState = state;
20834 ass.mLastStateUptime = uptime;
20843 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20844 boolean doingAll, long now) {
20845 if (mAdjSeq == app.adjSeq) {
20846 // This adjustment has already been computed.
20847 return app.curRawAdj;
20850 if (app.thread == null) {
20851 app.adjSeq = mAdjSeq;
20852 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20853 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20854 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20857 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20858 app.adjSource = null;
20859 app.adjTarget = null;
20861 app.cached = false;
20863 final int activitiesSize = app.activities.size();
20865 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20866 // The max adjustment doesn't allow this app to be anything
20867 // below foreground, so it is not worth doing work for it.
20868 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20869 app.adjType = "fixed";
20870 app.adjSeq = mAdjSeq;
20871 app.curRawAdj = app.maxAdj;
20872 app.foregroundActivities = false;
20873 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20874 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20875 // System processes can do UI, and when they do we want to have
20876 // them trim their memory after the user leaves the UI. To
20877 // facilitate this, here we need to determine whether or not it
20878 // is currently showing UI.
20879 app.systemNoUi = true;
20880 if (app == TOP_APP) {
20881 app.systemNoUi = false;
20882 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20883 app.adjType = "pers-top-activity";
20884 } else if (app.hasTopUi) {
20885 app.systemNoUi = false;
20886 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20887 app.adjType = "pers-top-ui";
20888 } else if (activitiesSize > 0) {
20889 for (int j = 0; j < activitiesSize; j++) {
20890 final ActivityRecord r = app.activities.get(j);
20892 app.systemNoUi = false;
20896 if (!app.systemNoUi) {
20897 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20899 return (app.curAdj=app.maxAdj);
20902 app.systemNoUi = false;
20904 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20906 // Determine the importance of the process, starting with most
20907 // important to least, and assign an appropriate OOM adjustment.
20911 boolean foregroundActivities = false;
20912 mTmpBroadcastQueue.clear();
20913 if (app == TOP_APP) {
20914 // The last app on the list is the foreground app.
20915 adj = ProcessList.FOREGROUND_APP_ADJ;
20916 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20917 app.adjType = "top-activity";
20918 foregroundActivities = true;
20919 procState = PROCESS_STATE_CUR_TOP;
20920 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20921 } else if (app.instr != null) {
20922 // Don't want to kill running instrumentation.
20923 adj = ProcessList.FOREGROUND_APP_ADJ;
20924 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20925 app.adjType = "instrumentation";
20926 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20927 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20928 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20929 // An app that is currently receiving a broadcast also
20930 // counts as being in the foreground for OOM killer purposes.
20931 // It's placed in a sched group based on the nature of the
20932 // broadcast as reflected by which queue it's active in.
20933 adj = ProcessList.FOREGROUND_APP_ADJ;
20934 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20935 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20936 app.adjType = "broadcast";
20937 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20938 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20939 } else if (app.executingServices.size() > 0) {
20940 // An app that is currently executing a service callback also
20941 // counts as being in the foreground.
20942 adj = ProcessList.FOREGROUND_APP_ADJ;
20943 schedGroup = app.execServicesFg ?
20944 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20945 app.adjType = "exec-service";
20946 procState = ActivityManager.PROCESS_STATE_SERVICE;
20947 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20948 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20950 // As far as we know the process is empty. We may change our mind later.
20951 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20952 // At this point we don't actually know the adjustment. Use the cached adj
20953 // value that the caller wants us to.
20955 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20958 app.adjType = "cch-empty";
20959 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20962 // Examine all activities if not already foreground.
20963 if (!foregroundActivities && activitiesSize > 0) {
20964 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20965 for (int j = 0; j < activitiesSize; j++) {
20966 final ActivityRecord r = app.activities.get(j);
20967 if (r.app != app) {
20968 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20969 + " instead of expected " + app);
20970 if (r.app == null || (r.app.uid == app.uid)) {
20971 // Only fix things up when they look sane
20978 // App has a visible activity; only upgrade adjustment.
20979 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20980 adj = ProcessList.VISIBLE_APP_ADJ;
20981 app.adjType = "vis-activity";
20982 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20984 if (procState > PROCESS_STATE_CUR_TOP) {
20985 procState = PROCESS_STATE_CUR_TOP;
20986 app.adjType = "vis-activity";
20987 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20989 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20990 app.cached = false;
20992 foregroundActivities = true;
20993 final TaskRecord task = r.getTask();
20994 if (task != null && minLayer > 0) {
20995 final int layer = task.mLayerRank;
20996 if (layer >= 0 && minLayer > layer) {
21001 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21002 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21003 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21004 app.adjType = "pause-activity";
21005 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21007 if (procState > PROCESS_STATE_CUR_TOP) {
21008 procState = PROCESS_STATE_CUR_TOP;
21009 app.adjType = "pause-activity";
21010 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21012 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21013 app.cached = false;
21015 foregroundActivities = true;
21016 } else if (r.state == ActivityState.STOPPING) {
21017 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21018 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21019 app.adjType = "stop-activity";
21020 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21022 // For the process state, we will at this point consider the
21023 // process to be cached. It will be cached either as an activity
21024 // or empty depending on whether the activity is finishing. We do
21025 // this so that we can treat the process as cached for purposes of
21026 // memory trimming (determing current memory level, trim command to
21027 // send to process) since there can be an arbitrary number of stopping
21028 // processes and they should soon all go into the cached state.
21029 if (!r.finishing) {
21030 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21031 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21032 app.adjType = "stop-activity";
21033 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21036 app.cached = false;
21038 foregroundActivities = true;
21040 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21041 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21042 app.adjType = "cch-act";
21043 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21047 if (adj == ProcessList.VISIBLE_APP_ADJ) {
21052 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21053 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21054 if (app.foregroundServices) {
21055 // The user is aware of this app, so make it visible.
21056 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21057 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21058 app.cached = false;
21059 app.adjType = "fg-service";
21060 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21061 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21062 } else if (app.hasOverlayUi) {
21063 // The process is display an overlay UI.
21064 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21065 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21066 app.cached = false;
21067 app.adjType = "has-overlay-ui";
21068 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21069 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21073 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21074 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21075 if (app.forcingToImportant != null) {
21076 // This is currently used for toasts... they are not interactive, and
21077 // we don't want them to cause the app to become fully foreground (and
21078 // thus out of background check), so we yes the best background level we can.
21079 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21080 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21081 app.cached = false;
21082 app.adjType = "force-imp";
21083 app.adjSource = app.forcingToImportant;
21084 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21085 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21089 if (app == mHeavyWeightProcess) {
21090 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21091 // We don't want to kill the current heavy-weight process.
21092 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21093 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21094 app.cached = false;
21095 app.adjType = "heavy";
21096 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21098 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21099 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21100 app.adjType = "heavy";
21101 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21105 if (app == mHomeProcess) {
21106 if (adj > ProcessList.HOME_APP_ADJ) {
21107 // This process is hosting what we currently consider to be the
21108 // home app, so we don't want to let it go into the background.
21109 adj = ProcessList.HOME_APP_ADJ;
21110 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21111 app.cached = false;
21112 app.adjType = "home";
21113 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21115 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21116 procState = ActivityManager.PROCESS_STATE_HOME;
21117 app.adjType = "home";
21118 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21122 if (app == mPreviousProcess && app.activities.size() > 0) {
21123 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21124 // This was the previous process that showed UI to the user.
21125 // We want to try to keep it around more aggressively, to give
21126 // a good experience around switching between two apps.
21127 adj = ProcessList.PREVIOUS_APP_ADJ;
21128 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21129 app.cached = false;
21130 app.adjType = "previous";
21131 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21133 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21134 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21135 app.adjType = "previous";
21136 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21140 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21141 + " reason=" + app.adjType);
21143 // By default, we use the computed adjustment. It may be changed if
21144 // there are applications dependent on our services or providers, but
21145 // this gives us a baseline and makes sure we don't get into an
21146 // infinite recursion.
21147 app.adjSeq = mAdjSeq;
21148 app.curRawAdj = adj;
21149 app.hasStartedServices = false;
21151 if (mBackupTarget != null && app == mBackupTarget.app) {
21152 // If possible we want to avoid killing apps while they're being backed up
21153 if (adj > ProcessList.BACKUP_APP_ADJ) {
21154 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21155 adj = ProcessList.BACKUP_APP_ADJ;
21156 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21157 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21159 app.adjType = "backup";
21160 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21161 app.cached = false;
21163 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21164 procState = ActivityManager.PROCESS_STATE_BACKUP;
21165 app.adjType = "backup";
21166 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21170 boolean mayBeTop = false;
21171 String mayBeTopType = null;
21172 Object mayBeTopSource = null;
21173 Object mayBeTopTarget = null;
21175 for (int is = app.services.size()-1;
21176 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21177 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21178 || procState > ActivityManager.PROCESS_STATE_TOP);
21180 ServiceRecord s = app.services.valueAt(is);
21181 if (s.startRequested) {
21182 app.hasStartedServices = true;
21183 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21184 procState = ActivityManager.PROCESS_STATE_SERVICE;
21185 app.adjType = "started-services";
21186 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21188 if (app.hasShownUi && app != mHomeProcess) {
21189 // If this process has shown some UI, let it immediately
21190 // go to the LRU list because it may be pretty heavy with
21191 // UI stuff. We'll tag it with a label just to help
21192 // debug and understand what is going on.
21193 if (adj > ProcessList.SERVICE_ADJ) {
21194 app.adjType = "cch-started-ui-services";
21197 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21198 // This service has seen some activity within
21199 // recent memory, so we will keep its process ahead
21200 // of the background processes.
21201 if (adj > ProcessList.SERVICE_ADJ) {
21202 adj = ProcessList.SERVICE_ADJ;
21203 app.adjType = "started-services";
21204 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21205 app.cached = false;
21208 // If we have let the service slide into the background
21209 // state, still have some text describing what it is doing
21210 // even though the service no longer has an impact.
21211 if (adj > ProcessList.SERVICE_ADJ) {
21212 app.adjType = "cch-started-services";
21217 for (int conni = s.connections.size()-1;
21218 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21219 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21220 || procState > ActivityManager.PROCESS_STATE_TOP);
21222 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21224 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21225 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21226 || procState > ActivityManager.PROCESS_STATE_TOP);
21228 // XXX should compute this based on the max of
21229 // all connected clients.
21230 ConnectionRecord cr = clist.get(i);
21231 if (cr.binding.client == app) {
21232 // Binding to ourself is not interesting.
21236 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21237 ProcessRecord client = cr.binding.client;
21238 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21239 TOP_APP, doingAll, now);
21240 int clientProcState = client.curProcState;
21241 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21242 // If the other app is cached for any reason, for purposes here
21243 // we are going to consider it empty. The specific cached state
21244 // doesn't propagate except under certain conditions.
21245 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21247 String adjType = null;
21248 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21249 // Not doing bind OOM management, so treat
21250 // this guy more like a started service.
21251 if (app.hasShownUi && app != mHomeProcess) {
21252 // If this process has shown some UI, let it immediately
21253 // go to the LRU list because it may be pretty heavy with
21254 // UI stuff. We'll tag it with a label just to help
21255 // debug and understand what is going on.
21256 if (adj > clientAdj) {
21257 adjType = "cch-bound-ui-services";
21259 app.cached = false;
21261 clientProcState = procState;
21263 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21264 // This service has not seen activity within
21265 // recent memory, so allow it to drop to the
21266 // LRU list if there is no other reason to keep
21267 // it around. We'll also tag it with a label just
21268 // to help debug and undertand what is going on.
21269 if (adj > clientAdj) {
21270 adjType = "cch-bound-services";
21276 if (adj > clientAdj) {
21277 // If this process has recently shown UI, and
21278 // the process that is binding to it is less
21279 // important than being visible, then we don't
21280 // care about the binding as much as we care
21281 // about letting this process get into the LRU
21282 // list to be killed and restarted if needed for
21284 if (app.hasShownUi && app != mHomeProcess
21285 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21286 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21287 adjType = "cch-bound-ui-services";
21291 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21292 |Context.BIND_IMPORTANT)) != 0) {
21293 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21294 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21295 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21296 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21297 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21298 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21299 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21300 newAdj = clientAdj;
21302 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21303 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21308 if (!client.cached) {
21309 app.cached = false;
21311 if (adj > newAdj) {
21313 adjType = "service";
21317 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21318 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21319 // This will treat important bound services identically to
21320 // the top app, which may behave differently than generic
21321 // foreground work.
21322 if (client.curSchedGroup > schedGroup) {
21323 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21324 schedGroup = client.curSchedGroup;
21326 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21329 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21330 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21331 // Special handling of clients who are in the top state.
21332 // We *may* want to consider this process to be in the
21333 // top state as well, but only if there is not another
21334 // reason for it to be running. Being on the top is a
21335 // special state, meaning you are specifically running
21336 // for the current top app. If the process is already
21337 // running in the background for some other reason, it
21338 // is more important to continue considering it to be
21339 // in the background state.
21341 mayBeTopType = "service";
21342 mayBeTopSource = cr.binding.client;
21343 mayBeTopTarget = s.name;
21344 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21346 // Special handling for above-top states (persistent
21347 // processes). These should not bring the current process
21348 // into the top state, since they are not on top. Instead
21349 // give them the best state after that.
21350 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21352 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21353 } else if (mWakefulness
21354 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21355 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21358 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21361 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21365 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21366 if (clientProcState <
21367 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21369 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21372 if (clientProcState <
21373 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21375 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21378 if (procState > clientProcState) {
21379 procState = clientProcState;
21380 if (adjType == null) {
21381 adjType = "service";
21384 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21385 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21386 app.pendingUiClean = true;
21388 if (adjType != null) {
21389 app.adjType = adjType;
21390 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21391 .REASON_SERVICE_IN_USE;
21392 app.adjSource = cr.binding.client;
21393 app.adjSourceProcState = clientProcState;
21394 app.adjTarget = s.name;
21395 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21396 + ": " + app + ", due to " + cr.binding.client
21397 + " adj=" + adj + " procState=" + procState);
21400 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21401 app.treatLikeActivity = true;
21403 final ActivityRecord a = cr.activity;
21404 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21405 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21406 (a.visible || a.state == ActivityState.RESUMED ||
21407 a.state == ActivityState.PAUSING)) {
21408 adj = ProcessList.FOREGROUND_APP_ADJ;
21409 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21410 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21411 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21413 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21416 app.cached = false;
21417 app.adjType = "service";
21418 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21419 .REASON_SERVICE_IN_USE;
21421 app.adjSourceProcState = procState;
21422 app.adjTarget = s.name;
21423 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21431 for (int provi = app.pubProviders.size()-1;
21432 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21433 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21434 || procState > ActivityManager.PROCESS_STATE_TOP);
21436 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21437 for (int i = cpr.connections.size()-1;
21438 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21439 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21440 || procState > ActivityManager.PROCESS_STATE_TOP);
21442 ContentProviderConnection conn = cpr.connections.get(i);
21443 ProcessRecord client = conn.client;
21444 if (client == app) {
21445 // Being our own client is not interesting.
21448 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21449 int clientProcState = client.curProcState;
21450 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21451 // If the other app is cached for any reason, for purposes here
21452 // we are going to consider it empty.
21453 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21455 String adjType = null;
21456 if (adj > clientAdj) {
21457 if (app.hasShownUi && app != mHomeProcess
21458 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21459 adjType = "cch-ui-provider";
21461 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21462 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21463 adjType = "provider";
21465 app.cached &= client.cached;
21467 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21468 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21469 // Special handling of clients who are in the top state.
21470 // We *may* want to consider this process to be in the
21471 // top state as well, but only if there is not another
21472 // reason for it to be running. Being on the top is a
21473 // special state, meaning you are specifically running
21474 // for the current top app. If the process is already
21475 // running in the background for some other reason, it
21476 // is more important to continue considering it to be
21477 // in the background state.
21479 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21480 mayBeTopType = adjType = "provider-top";
21481 mayBeTopSource = client;
21482 mayBeTopTarget = cpr.name;
21484 // Special handling for above-top states (persistent
21485 // processes). These should not bring the current process
21486 // into the top state, since they are not on top. Instead
21487 // give them the best state after that.
21489 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21490 if (adjType == null) {
21491 adjType = "provider";
21495 if (procState > clientProcState) {
21496 procState = clientProcState;
21498 if (client.curSchedGroup > schedGroup) {
21499 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21501 if (adjType != null) {
21502 app.adjType = adjType;
21503 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21504 .REASON_PROVIDER_IN_USE;
21505 app.adjSource = client;
21506 app.adjSourceProcState = clientProcState;
21507 app.adjTarget = cpr.name;
21508 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21509 + ": " + app + ", due to " + client
21510 + " adj=" + adj + " procState=" + procState);
21513 // If the provider has external (non-framework) process
21514 // dependencies, ensure that its adjustment is at least
21515 // FOREGROUND_APP_ADJ.
21516 if (cpr.hasExternalProcessHandles()) {
21517 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21518 adj = ProcessList.FOREGROUND_APP_ADJ;
21519 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21520 app.cached = false;
21521 app.adjType = "ext-provider";
21522 app.adjTarget = cpr.name;
21523 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21525 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21526 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21531 if (app.lastProviderTime > 0 &&
21532 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21533 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21534 adj = ProcessList.PREVIOUS_APP_ADJ;
21535 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21536 app.cached = false;
21537 app.adjType = "recent-provider";
21538 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21540 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21541 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21542 app.adjType = "recent-provider";
21543 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21547 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21548 // A client of one of our services or providers is in the top state. We
21549 // *may* want to be in the top state, but not if we are already running in
21550 // the background for some other reason. For the decision here, we are going
21551 // to pick out a few specific states that we want to remain in when a client
21552 // is top (states that tend to be longer-term) and otherwise allow it to go
21553 // to the top state.
21554 switch (procState) {
21555 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21556 // Something else is keeping it at this level, just leave it.
21558 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21559 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21560 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21561 case ActivityManager.PROCESS_STATE_SERVICE:
21562 // These all are longer-term states, so pull them up to the top
21563 // of the background states, but not all the way to the top state.
21564 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21565 app.adjType = mayBeTopType;
21566 app.adjSource = mayBeTopSource;
21567 app.adjTarget = mayBeTopTarget;
21568 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21569 + ": " + app + ", due to " + mayBeTopSource
21570 + " adj=" + adj + " procState=" + procState);
21573 // Otherwise, top is a better choice, so take it.
21574 procState = ActivityManager.PROCESS_STATE_TOP;
21575 app.adjType = mayBeTopType;
21576 app.adjSource = mayBeTopSource;
21577 app.adjTarget = mayBeTopTarget;
21578 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21579 + ": " + app + ", due to " + mayBeTopSource
21580 + " adj=" + adj + " procState=" + procState);
21585 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21586 if (app.hasClientActivities) {
21587 // This is a cached process, but with client activities. Mark it so.
21588 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21589 app.adjType = "cch-client-act";
21590 } else if (app.treatLikeActivity) {
21591 // This is a cached process, but somebody wants us to treat it like it has
21592 // an activity, okay!
21593 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21594 app.adjType = "cch-as-act";
21598 if (adj == ProcessList.SERVICE_ADJ) {
21600 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21601 mNewNumServiceProcs++;
21602 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21603 if (!app.serviceb) {
21604 // This service isn't far enough down on the LRU list to
21605 // normally be a B service, but if we are low on RAM and it
21606 // is large we want to force it down since we would prefer to
21607 // keep launcher over it.
21608 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21609 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21610 app.serviceHighRam = true;
21611 app.serviceb = true;
21612 //Slog.i(TAG, "ADJ " + app + " high ram!");
21614 mNewNumAServiceProcs++;
21615 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21618 app.serviceHighRam = false;
21621 if (app.serviceb) {
21622 adj = ProcessList.SERVICE_B_ADJ;
21626 app.curRawAdj = adj;
21628 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21629 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21630 if (adj > app.maxAdj) {
21632 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21633 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21637 // Do final modification to adj. Everything we do between here and applying
21638 // the final setAdj must be done in this function, because we will also use
21639 // it when computing the final cached adj later. Note that we don't need to
21640 // worry about this for max adj above, since max adj will always be used to
21641 // keep it out of the cached vaues.
21642 app.curAdj = app.modifyRawOomAdj(adj);
21643 app.curSchedGroup = schedGroup;
21644 app.curProcState = procState;
21645 app.foregroundActivities = foregroundActivities;
21647 return app.curRawAdj;
21651 * Record new PSS sample for a process.
21653 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21655 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21657 proc.lastPssTime = now;
21658 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21659 if (DEBUG_PSS) Slog.d(TAG_PSS,
21660 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21661 + " state=" + ProcessList.makeProcStateString(procState));
21662 if (proc.initialIdlePss == 0) {
21663 proc.initialIdlePss = pss;
21665 proc.lastPss = pss;
21666 proc.lastSwapPss = swapPss;
21667 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21668 proc.lastCachedPss = pss;
21669 proc.lastCachedSwapPss = swapPss;
21672 final SparseArray<Pair<Long, String>> watchUids
21673 = mMemWatchProcesses.getMap().get(proc.processName);
21675 if (watchUids != null) {
21676 Pair<Long, String> val = watchUids.get(proc.uid);
21678 val = watchUids.get(0);
21684 if (check != null) {
21685 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21686 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21687 if (!isDebuggable) {
21688 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21689 isDebuggable = true;
21692 if (isDebuggable) {
21693 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21694 final ProcessRecord myProc = proc;
21695 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21696 mMemWatchDumpProcName = proc.processName;
21697 mMemWatchDumpFile = heapdumpFile.toString();
21698 mMemWatchDumpPid = proc.pid;
21699 mMemWatchDumpUid = proc.uid;
21700 BackgroundThread.getHandler().post(new Runnable() {
21702 public void run() {
21703 revokeUriPermission(ActivityThread.currentActivityThread()
21704 .getApplicationThread(),
21705 null, DumpHeapActivity.JAVA_URI,
21706 Intent.FLAG_GRANT_READ_URI_PERMISSION
21707 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21708 UserHandle.myUserId());
21709 ParcelFileDescriptor fd = null;
21711 heapdumpFile.delete();
21712 fd = ParcelFileDescriptor.open(heapdumpFile,
21713 ParcelFileDescriptor.MODE_CREATE |
21714 ParcelFileDescriptor.MODE_TRUNCATE |
21715 ParcelFileDescriptor.MODE_WRITE_ONLY |
21716 ParcelFileDescriptor.MODE_APPEND);
21717 IApplicationThread thread = myProc.thread;
21718 if (thread != null) {
21720 if (DEBUG_PSS) Slog.d(TAG_PSS,
21721 "Requesting dump heap from "
21722 + myProc + " to " + heapdumpFile);
21723 thread.dumpHeap(/* managed= */ true,
21724 /* mallocInfo= */ false, /* runGc= */ false,
21725 heapdumpFile.toString(), fd);
21726 } catch (RemoteException e) {
21729 } catch (FileNotFoundException e) {
21730 e.printStackTrace();
21735 } catch (IOException e) {
21742 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21743 + ", but debugging not enabled");
21750 * Schedule PSS collection of a process.
21752 void requestPssLocked(ProcessRecord proc, int procState) {
21753 if (mPendingPssProcesses.contains(proc)) {
21756 if (mPendingPssProcesses.size() == 0) {
21757 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21759 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21760 proc.pssProcState = procState;
21761 mPendingPssProcesses.add(proc);
21765 * Schedule PSS collection of all processes.
21767 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21769 if (now < (mLastFullPssTime +
21770 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21771 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21775 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21776 mLastFullPssTime = now;
21777 mFullPssPending = true;
21778 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21779 mPendingPssProcesses.clear();
21780 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21781 ProcessRecord app = mLruProcesses.get(i);
21782 if (app.thread == null
21783 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21786 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21787 app.pssProcState = app.setProcState;
21788 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21789 mTestPssMode, isSleepingLocked(), now);
21790 mPendingPssProcesses.add(app);
21793 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21796 public void setTestPssMode(boolean enabled) {
21797 synchronized (this) {
21798 mTestPssMode = enabled;
21800 // Whenever we enable the mode, we want to take a snapshot all of current
21801 // process mem use.
21802 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21808 * Ask a given process to GC right now.
21810 final void performAppGcLocked(ProcessRecord app) {
21812 app.lastRequestedGc = SystemClock.uptimeMillis();
21813 if (app.thread != null) {
21814 if (app.reportLowMemory) {
21815 app.reportLowMemory = false;
21816 app.thread.scheduleLowMemory();
21818 app.thread.processInBackground();
21821 } catch (Exception e) {
21827 * Returns true if things are idle enough to perform GCs.
21829 private final boolean canGcNowLocked() {
21830 boolean processingBroadcasts = false;
21831 for (BroadcastQueue q : mBroadcastQueues) {
21832 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21833 processingBroadcasts = true;
21836 return !processingBroadcasts
21837 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21841 * Perform GCs on all processes that are waiting for it, but only
21842 * if things are idle.
21844 final void performAppGcsLocked() {
21845 final int N = mProcessesToGc.size();
21849 if (canGcNowLocked()) {
21850 while (mProcessesToGc.size() > 0) {
21851 ProcessRecord proc = mProcessesToGc.remove(0);
21852 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21853 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21854 <= SystemClock.uptimeMillis()) {
21855 // To avoid spamming the system, we will GC processes one
21856 // at a time, waiting a few seconds between each.
21857 performAppGcLocked(proc);
21858 scheduleAppGcsLocked();
21861 // It hasn't been long enough since we last GCed this
21862 // process... put it in the list to wait for its time.
21863 addProcessToGcListLocked(proc);
21869 scheduleAppGcsLocked();
21874 * If all looks good, perform GCs on all processes waiting for them.
21876 final void performAppGcsIfAppropriateLocked() {
21877 if (canGcNowLocked()) {
21878 performAppGcsLocked();
21881 // Still not idle, wait some more.
21882 scheduleAppGcsLocked();
21886 * Schedule the execution of all pending app GCs.
21888 final void scheduleAppGcsLocked() {
21889 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21891 if (mProcessesToGc.size() > 0) {
21892 // Schedule a GC for the time to the next process.
21893 ProcessRecord proc = mProcessesToGc.get(0);
21894 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21896 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21897 long now = SystemClock.uptimeMillis();
21898 if (when < (now+mConstants.GC_TIMEOUT)) {
21899 when = now + mConstants.GC_TIMEOUT;
21901 mHandler.sendMessageAtTime(msg, when);
21906 * Add a process to the array of processes waiting to be GCed. Keeps the
21907 * list in sorted order by the last GC time. The process can't already be
21910 final void addProcessToGcListLocked(ProcessRecord proc) {
21911 boolean added = false;
21912 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21913 if (mProcessesToGc.get(i).lastRequestedGc <
21914 proc.lastRequestedGc) {
21916 mProcessesToGc.add(i+1, proc);
21921 mProcessesToGc.add(0, proc);
21926 * Set up to ask a process to GC itself. This will either do it
21927 * immediately, or put it on the list of processes to gc the next
21928 * time things are idle.
21930 final void scheduleAppGcLocked(ProcessRecord app) {
21931 long now = SystemClock.uptimeMillis();
21932 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21935 if (!mProcessesToGc.contains(app)) {
21936 addProcessToGcListLocked(app);
21937 scheduleAppGcsLocked();
21941 final void checkExcessivePowerUsageLocked() {
21942 updateCpuStatsNow();
21944 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21945 boolean doCpuKills = true;
21946 if (mLastPowerCheckUptime == 0) {
21947 doCpuKills = false;
21949 final long curUptime = SystemClock.uptimeMillis();
21950 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21951 mLastPowerCheckUptime = curUptime;
21952 int i = mLruProcesses.size();
21955 ProcessRecord app = mLruProcesses.get(i);
21956 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21957 if (app.lastCpuTime <= 0) {
21960 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21962 StringBuilder sb = new StringBuilder(128);
21963 sb.append("CPU for ");
21964 app.toShortString(sb);
21965 sb.append(": over ");
21966 TimeUtils.formatDuration(uptimeSince, sb);
21967 sb.append(" used ");
21968 TimeUtils.formatDuration(cputimeUsed, sb);
21970 sb.append((cputimeUsed*100)/uptimeSince);
21972 Slog.i(TAG_POWER, sb.toString());
21974 // If the process has used too much CPU over the last duration, the
21975 // user probably doesn't want this, so kill!
21976 if (doCpuKills && uptimeSince > 0) {
21977 // What is the limit for this process?
21979 long checkDur = curUptime - app.whenUnimportant;
21980 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21981 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21982 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21983 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21984 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21985 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21986 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21988 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21990 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21991 synchronized (stats) {
21992 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21993 uptimeSince, cputimeUsed);
21995 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21996 + " dur=" + checkDur + " limit=" + cpuLimit, true);
21997 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22000 app.lastCpuTime = app.curCpuTime;
22005 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22007 boolean success = true;
22009 if (app.curRawAdj != app.setRawAdj) {
22010 app.setRawAdj = app.curRawAdj;
22015 if (app.curAdj != app.setAdj) {
22016 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22017 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22018 String msg = "Set " + app.pid + " " + app.processName + " adj "
22019 + app.curAdj + ": " + app.adjType;
22020 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22022 app.setAdj = app.curAdj;
22023 app.verifiedAdj = ProcessList.INVALID_ADJ;
22026 if (app.setSchedGroup != app.curSchedGroup) {
22027 int oldSchedGroup = app.setSchedGroup;
22028 app.setSchedGroup = app.curSchedGroup;
22029 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22030 String msg = "Setting sched group of " + app.processName
22031 + " to " + app.curSchedGroup;
22032 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22034 if (app.waitingToKill != null && app.curReceivers.isEmpty()
22035 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22036 app.kill(app.waitingToKill, true);
22040 switch (app.curSchedGroup) {
22041 case ProcessList.SCHED_GROUP_BACKGROUND:
22042 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22044 case ProcessList.SCHED_GROUP_TOP_APP:
22045 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22046 processGroup = THREAD_GROUP_TOP_APP;
22049 processGroup = THREAD_GROUP_DEFAULT;
22052 long oldId = Binder.clearCallingIdentity();
22054 setProcessGroup(app.pid, processGroup);
22055 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22056 // do nothing if we already switched to RT
22057 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22058 mVrController.onTopProcChangedLocked(app);
22059 if (mUseFifoUiScheduling) {
22060 // Switch UI pipeline for app to SCHED_FIFO
22061 app.savedPriority = Process.getThreadPriority(app.pid);
22062 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22063 if (app.renderThreadTid != 0) {
22064 scheduleAsFifoPriority(app.renderThreadTid,
22065 /* suppressLogs */true);
22066 if (DEBUG_OOM_ADJ) {
22067 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22068 app.renderThreadTid + ") to FIFO");
22071 if (DEBUG_OOM_ADJ) {
22072 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22076 // Boost priority for top app UI and render threads
22077 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22078 if (app.renderThreadTid != 0) {
22080 setThreadPriority(app.renderThreadTid,
22081 TOP_APP_PRIORITY_BOOST);
22082 } catch (IllegalArgumentException e) {
22083 // thread died, ignore
22088 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22089 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22090 mVrController.onTopProcChangedLocked(app);
22091 if (mUseFifoUiScheduling) {
22093 // Reset UI pipeline to SCHED_OTHER
22094 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22095 setThreadPriority(app.pid, app.savedPriority);
22096 if (app.renderThreadTid != 0) {
22097 setThreadScheduler(app.renderThreadTid,
22099 setThreadPriority(app.renderThreadTid, -4);
22101 } catch (IllegalArgumentException e) {
22103 "Failed to set scheduling policy, thread does not exist:\n"
22105 } catch (SecurityException e) {
22106 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22109 // Reset priority for top app UI and render threads
22110 setThreadPriority(app.pid, 0);
22111 if (app.renderThreadTid != 0) {
22112 setThreadPriority(app.renderThreadTid, 0);
22116 } catch (Exception e) {
22118 Slog.w(TAG, "Failed setting process group of " + app.pid
22119 + " to " + app.curSchedGroup);
22120 Slog.w(TAG, "at location", e);
22123 Binder.restoreCallingIdentity(oldId);
22127 if (app.repForegroundActivities != app.foregroundActivities) {
22128 app.repForegroundActivities = app.foregroundActivities;
22129 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22131 if (app.repProcState != app.curProcState) {
22132 app.repProcState = app.curProcState;
22133 if (app.thread != null) {
22136 //RuntimeException h = new RuntimeException("here");
22137 Slog.i(TAG, "Sending new process state " + app.repProcState
22138 + " to " + app /*, h*/);
22140 app.thread.setProcessState(app.repProcState);
22141 } catch (RemoteException e) {
22145 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22146 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22147 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22148 // Experimental code to more aggressively collect pss while
22149 // running test... the problem is that this tends to collect
22150 // the data right when a process is transitioning between process
22151 // states, which well tend to give noisy data.
22152 long start = SystemClock.uptimeMillis();
22153 long pss = Debug.getPss(app.pid, mTmpLong, null);
22154 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22155 mPendingPssProcesses.remove(app);
22156 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22157 + " to " + app.curProcState + ": "
22158 + (SystemClock.uptimeMillis()-start) + "ms");
22160 app.lastStateTime = now;
22161 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22162 mTestPssMode, isSleepingLocked(), now);
22163 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22164 + ProcessList.makeProcStateString(app.setProcState) + " to "
22165 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22166 + (app.nextPssTime-now) + ": " + app);
22168 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22169 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22171 requestPssLocked(app, app.setProcState);
22172 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22173 mTestPssMode, isSleepingLocked(), now);
22174 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22175 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22177 if (app.setProcState != app.curProcState) {
22178 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22179 String msg = "Proc state change of " + app.processName
22180 + " to " + app.curProcState;
22181 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22183 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22184 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22185 if (setImportant && !curImportant) {
22186 // This app is no longer something we consider important enough to allow to
22187 // use arbitrary amounts of battery power. Note
22188 // its current CPU time to later know to kill it if
22189 // it is not behaving well.
22190 app.whenUnimportant = now;
22191 app.lastCpuTime = 0;
22193 // Inform UsageStats of important process state change
22194 // Must be called before updating setProcState
22195 maybeUpdateUsageStatsLocked(app, nowElapsed);
22197 app.setProcState = app.curProcState;
22198 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22199 app.notCachedSinceIdle = false;
22202 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22204 app.procStateChanged = true;
22206 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22207 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22208 // For apps that sit around for a long time in the interactive state, we need
22209 // to report this at least once a day so they don't go idle.
22210 maybeUpdateUsageStatsLocked(app, nowElapsed);
22213 if (changes != 0) {
22214 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22215 "Changes in " + app + ": " + changes);
22216 int i = mPendingProcessChanges.size()-1;
22217 ProcessChangeItem item = null;
22219 item = mPendingProcessChanges.get(i);
22220 if (item.pid == app.pid) {
22221 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22222 "Re-using existing item: " + item);
22228 // No existing item in pending changes; need a new one.
22229 final int NA = mAvailProcessChanges.size();
22231 item = mAvailProcessChanges.remove(NA-1);
22232 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22233 "Retrieving available item: " + item);
22235 item = new ProcessChangeItem();
22236 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22237 "Allocating new item: " + item);
22240 item.pid = app.pid;
22241 item.uid = app.info.uid;
22242 if (mPendingProcessChanges.size() == 0) {
22243 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22244 "*** Enqueueing dispatch processes changed!");
22245 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22247 mPendingProcessChanges.add(item);
22249 item.changes |= changes;
22250 item.foregroundActivities = app.repForegroundActivities;
22251 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22252 "Item " + Integer.toHexString(System.identityHashCode(item))
22253 + " " + app.toShortString() + ": changes=" + item.changes
22254 + " foreground=" + item.foregroundActivities
22255 + " type=" + app.adjType + " source=" + app.adjSource
22256 + " target=" + app.adjTarget);
22262 private boolean isEphemeralLocked(int uid) {
22263 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22264 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22267 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22272 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22273 final UidRecord.ChangeItem pendingChange;
22274 if (uidRec == null || uidRec.pendingChange == null) {
22275 if (mPendingUidChanges.size() == 0) {
22276 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22277 "*** Enqueueing dispatch uid changed!");
22278 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22280 final int NA = mAvailUidChanges.size();
22282 pendingChange = mAvailUidChanges.remove(NA-1);
22283 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22284 "Retrieving available item: " + pendingChange);
22286 pendingChange = new UidRecord.ChangeItem();
22287 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22288 "Allocating new item: " + pendingChange);
22290 if (uidRec != null) {
22291 uidRec.pendingChange = pendingChange;
22292 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22293 // If this uid is going away, and we haven't yet reported it is gone,
22295 change |= UidRecord.CHANGE_IDLE;
22297 } else if (uid < 0) {
22298 throw new IllegalArgumentException("No UidRecord or uid");
22300 pendingChange.uidRecord = uidRec;
22301 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22302 mPendingUidChanges.add(pendingChange);
22304 pendingChange = uidRec.pendingChange;
22305 // If there is no change in idle or active state, then keep whatever was pending.
22306 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22307 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22308 | UidRecord.CHANGE_ACTIVE));
22310 // If there is no change in cached or uncached state, then keep whatever was pending.
22311 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22312 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22313 | UidRecord.CHANGE_UNCACHED));
22315 // If this is a report of the UID being gone, then we shouldn't keep any previous
22316 // report of it being active or cached. (That is, a gone uid is never active,
22317 // and never cached.)
22318 if ((change & UidRecord.CHANGE_GONE) != 0) {
22319 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22320 if (!uidRec.idle) {
22321 // If this uid is going away, and we haven't yet reported it is gone,
22323 change |= UidRecord.CHANGE_IDLE;
22327 pendingChange.change = change;
22328 pendingChange.processState = uidRec != null
22329 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22330 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22331 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22332 if (uidRec != null) {
22333 uidRec.lastReportedChange = change;
22334 uidRec.updateLastDispatchedProcStateSeq(change);
22337 // Directly update the power manager, since we sit on top of it and it is critical
22338 // it be kept in sync (so wake locks will be held as soon as appropriate).
22339 if (mLocalPowerManager != null) {
22340 // TO DO: dispatch cached/uncached changes here, so we don't need to report
22341 // all proc state changes.
22342 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22343 mLocalPowerManager.uidActive(pendingChange.uid);
22345 if ((change & UidRecord.CHANGE_IDLE) != 0) {
22346 mLocalPowerManager.uidIdle(pendingChange.uid);
22348 if ((change & UidRecord.CHANGE_GONE) != 0) {
22349 mLocalPowerManager.uidGone(pendingChange.uid);
22351 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22352 pendingChange.processState);
22357 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22358 String authority) {
22359 if (app == null) return;
22360 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22361 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22362 if (userState == null) return;
22363 final long now = SystemClock.elapsedRealtime();
22364 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22365 if (lastReported == null || lastReported < now - 60 * 1000L) {
22366 if (mSystemReady) {
22367 // Cannot touch the user stats if not system ready
22368 mUsageStatsService.reportContentProviderUsage(
22369 authority, providerPkgName, app.userId);
22371 userState.mProviderLastReportedFg.put(authority, now);
22376 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22377 if (DEBUG_USAGE_STATS) {
22378 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22379 + "] state changes: old = " + app.setProcState + ", new = "
22380 + app.curProcState);
22382 if (mUsageStatsService == null) {
22385 boolean isInteraction;
22386 // To avoid some abuse patterns, we are going to be careful about what we consider
22387 // to be an app interaction. Being the top activity doesn't count while the display
22388 // is sleeping, nor do short foreground services.
22389 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22390 isInteraction = true;
22391 app.fgInteractionTime = 0;
22392 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22393 if (app.fgInteractionTime == 0) {
22394 app.fgInteractionTime = nowElapsed;
22395 isInteraction = false;
22397 isInteraction = nowElapsed > app.fgInteractionTime
22398 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22401 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22402 app.fgInteractionTime = 0;
22404 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22405 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22406 app.interactionEventTime = nowElapsed;
22407 String[] packages = app.getPackageList();
22408 if (packages != null) {
22409 for (int i = 0; i < packages.length; i++) {
22410 mUsageStatsService.reportEvent(packages[i], app.userId,
22411 UsageEvents.Event.SYSTEM_INTERACTION);
22415 app.reportedInteraction = isInteraction;
22416 if (!isInteraction) {
22417 app.interactionEventTime = 0;
22421 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22422 if (proc.thread != null) {
22423 if (proc.baseProcessTracker != null) {
22424 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22429 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22430 ProcessRecord TOP_APP, boolean doingAll, long now) {
22431 if (app.thread == null) {
22435 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22437 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22440 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22442 if (isForeground != proc.foregroundServices) {
22443 proc.foregroundServices = isForeground;
22444 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22446 if (isForeground) {
22447 if (curProcs == null) {
22448 curProcs = new ArrayList<ProcessRecord>();
22449 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22451 if (!curProcs.contains(proc)) {
22452 curProcs.add(proc);
22453 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22454 proc.info.packageName, proc.info.uid);
22457 if (curProcs != null) {
22458 if (curProcs.remove(proc)) {
22459 mBatteryStatsService.noteEvent(
22460 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22461 proc.info.packageName, proc.info.uid);
22462 if (curProcs.size() <= 0) {
22463 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22469 updateOomAdjLocked();
22474 private final ActivityRecord resumedAppLocked() {
22475 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22479 pkg = act.packageName;
22480 uid = act.info.applicationInfo.uid;
22485 // Has the UID or resumed package name changed?
22486 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22487 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22488 if (mCurResumedPackage != null) {
22489 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22490 mCurResumedPackage, mCurResumedUid);
22492 mCurResumedPackage = pkg;
22493 mCurResumedUid = uid;
22494 if (mCurResumedPackage != null) {
22495 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22496 mCurResumedPackage, mCurResumedUid);
22503 * Update OomAdj for a specific process.
22504 * @param app The process to update
22505 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22506 * if necessary, or skip.
22507 * @return whether updateOomAdjLocked(app) was successful.
22509 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22510 final ActivityRecord TOP_ACT = resumedAppLocked();
22511 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22512 final boolean wasCached = app.cached;
22516 // This is the desired cached adjusment we want to tell it to use.
22517 // If our app is currently cached, we know it, and that is it. Otherwise,
22518 // we don't know it yet, and it needs to now be cached we will then
22519 // need to do a complete oom adj.
22520 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22521 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22522 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22523 SystemClock.uptimeMillis());
22525 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22526 // Changed to/from cached state, so apps after it in the LRU
22527 // list may also be changed.
22528 updateOomAdjLocked();
22533 final void updateOomAdjLocked() {
22534 final ActivityRecord TOP_ACT = resumedAppLocked();
22535 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22536 final long now = SystemClock.uptimeMillis();
22537 final long nowElapsed = SystemClock.elapsedRealtime();
22538 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22539 final int N = mLruProcesses.size();
22542 RuntimeException e = new RuntimeException();
22543 e.fillInStackTrace();
22544 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22547 // Reset state in all uid records.
22548 for (int i=mActiveUids.size()-1; i>=0; i--) {
22549 final UidRecord uidRec = mActiveUids.valueAt(i);
22550 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22551 "Starting update of " + uidRec);
22555 mStackSupervisor.rankTaskLayersIfNeeded();
22558 mNewNumServiceProcs = 0;
22559 mNewNumAServiceProcs = 0;
22561 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22562 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22564 // Let's determine how many processes we have running vs.
22565 // how many slots we have for background processes; we may want
22566 // to put multiple processes in a slot of there are enough of
22568 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22569 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22570 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22571 if (numEmptyProcs > cachedProcessLimit) {
22572 // If there are more empty processes than our limit on cached
22573 // processes, then use the cached process limit for the factor.
22574 // This ensures that the really old empty processes get pushed
22575 // down to the bottom, so if we are running low on memory we will
22576 // have a better chance at keeping around more cached processes
22577 // instead of a gazillion empty processes.
22578 numEmptyProcs = cachedProcessLimit;
22580 int emptyFactor = numEmptyProcs/numSlots;
22581 if (emptyFactor < 1) emptyFactor = 1;
22582 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22583 if (cachedFactor < 1) cachedFactor = 1;
22584 int stepCached = 0;
22588 int numTrimming = 0;
22590 mNumNonCachedProcs = 0;
22591 mNumCachedHiddenProcs = 0;
22593 // First update the OOM adjustment for each of the
22594 // application processes based on their current state.
22595 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22596 int nextCachedAdj = curCachedAdj+1;
22597 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22598 int nextEmptyAdj = curEmptyAdj+2;
22599 for (int i=N-1; i>=0; i--) {
22600 ProcessRecord app = mLruProcesses.get(i);
22601 if (!app.killedByAm && app.thread != null) {
22602 app.procStateChanged = false;
22603 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22605 // If we haven't yet assigned the final cached adj
22606 // to the process, do that now.
22607 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22608 switch (app.curProcState) {
22609 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22610 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22611 // This process is a cached process holding activities...
22612 // assign it the next cached value for that type, and then
22613 // step that cached level.
22614 app.curRawAdj = curCachedAdj;
22615 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22616 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22617 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22619 if (curCachedAdj != nextCachedAdj) {
22621 if (stepCached >= cachedFactor) {
22623 curCachedAdj = nextCachedAdj;
22624 nextCachedAdj += 2;
22625 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22626 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22632 // For everything else, assign next empty cached process
22633 // level and bump that up. Note that this means that
22634 // long-running services that have dropped down to the
22635 // cached level will be treated as empty (since their process
22636 // state is still as a service), which is what we want.
22637 app.curRawAdj = curEmptyAdj;
22638 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22639 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22640 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22642 if (curEmptyAdj != nextEmptyAdj) {
22644 if (stepEmpty >= emptyFactor) {
22646 curEmptyAdj = nextEmptyAdj;
22648 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22649 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22657 applyOomAdjLocked(app, true, now, nowElapsed);
22659 // Count the number of process types.
22660 switch (app.curProcState) {
22661 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22662 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22663 mNumCachedHiddenProcs++;
22665 if (numCached > cachedProcessLimit) {
22666 app.kill("cached #" + numCached, true);
22669 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22670 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22671 && app.lastActivityTime < oldTime) {
22672 app.kill("empty for "
22673 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22674 / 1000) + "s", true);
22677 if (numEmpty > emptyProcessLimit) {
22678 app.kill("empty #" + numEmpty, true);
22683 mNumNonCachedProcs++;
22687 if (app.isolated && app.services.size() <= 0) {
22688 // If this is an isolated process, and there are no
22689 // services running in it, then the process is no longer
22690 // needed. We agressively kill these because we can by
22691 // definition not re-use the same process again, and it is
22692 // good to avoid having whatever code was running in them
22693 // left sitting around after no longer needed.
22694 app.kill("isolated not needed", true);
22696 // Keeping this process, update its uid.
22697 final UidRecord uidRec = app.uidRecord;
22698 if (uidRec != null) {
22699 uidRec.ephemeral = app.info.isInstantApp();
22700 if (uidRec.curProcState > app.curProcState) {
22701 uidRec.curProcState = app.curProcState;
22703 if (app.foregroundServices) {
22704 uidRec.foregroundServices = true;
22709 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22710 && !app.killedByAm) {
22716 incrementProcStateSeqAndNotifyAppsLocked();
22718 mNumServiceProcs = mNewNumServiceProcs;
22720 // Now determine the memory trimming level of background processes.
22721 // Unfortunately we need to start at the back of the list to do this
22722 // properly. We only do this if the number of background apps we
22723 // are managing to keep around is less than half the maximum we desire;
22724 // if we are keeping a good number around, we'll let them use whatever
22725 // memory they want.
22726 final int numCachedAndEmpty = numCached + numEmpty;
22728 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22729 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22730 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22731 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22732 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22733 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22735 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22738 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22740 // We always allow the memory level to go up (better). We only allow it to go
22741 // down if we are in a state where that is allowed, *and* the total number of processes
22742 // has gone down since last time.
22743 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22744 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22745 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22746 if (memFactor > mLastMemoryLevel) {
22747 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22748 memFactor = mLastMemoryLevel;
22749 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22752 if (memFactor != mLastMemoryLevel) {
22753 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22755 mLastMemoryLevel = memFactor;
22756 mLastNumProcesses = mLruProcesses.size();
22757 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22758 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22759 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22760 if (mLowRamStartTime == 0) {
22761 mLowRamStartTime = now;
22765 switch (memFactor) {
22766 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22767 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22769 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22770 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22773 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22776 int factor = numTrimming/3;
22778 if (mHomeProcess != null) minFactor++;
22779 if (mPreviousProcess != null) minFactor++;
22780 if (factor < minFactor) factor = minFactor;
22781 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22782 for (int i=N-1; i>=0; i--) {
22783 ProcessRecord app = mLruProcesses.get(i);
22784 if (allChanged || app.procStateChanged) {
22785 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22786 app.procStateChanged = false;
22788 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22789 && !app.killedByAm) {
22790 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22792 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22793 "Trimming memory of " + app.processName + " to " + curLevel);
22794 app.thread.scheduleTrimMemory(curLevel);
22795 } catch (RemoteException e) {
22798 // For now we won't do this; our memory trimming seems
22799 // to be good enough at this point that destroying
22800 // activities causes more harm than good.
22801 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22802 && app != mHomeProcess && app != mPreviousProcess) {
22803 // Need to do this on its own message because the stack may not
22804 // be in a consistent state at this point.
22805 // For these apps we will also finish their activities
22806 // to help them free memory.
22807 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22811 app.trimMemoryLevel = curLevel;
22813 if (step >= factor) {
22815 switch (curLevel) {
22816 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22817 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22819 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22820 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22824 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22825 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22826 && app.thread != null) {
22828 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22829 "Trimming memory of heavy-weight " + app.processName
22830 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22831 app.thread.scheduleTrimMemory(
22832 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22833 } catch (RemoteException e) {
22836 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22838 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22839 || app.systemNoUi) && app.pendingUiClean) {
22840 // If this application is now in the background and it
22841 // had done UI, then give it the special trim level to
22842 // have it free UI resources.
22843 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22844 if (app.trimMemoryLevel < level && app.thread != null) {
22846 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22847 "Trimming memory of bg-ui " + app.processName
22849 app.thread.scheduleTrimMemory(level);
22850 } catch (RemoteException e) {
22853 app.pendingUiClean = false;
22855 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22857 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22858 "Trimming memory of fg " + app.processName
22859 + " to " + fgTrimLevel);
22860 app.thread.scheduleTrimMemory(fgTrimLevel);
22861 } catch (RemoteException e) {
22864 app.trimMemoryLevel = fgTrimLevel;
22868 if (mLowRamStartTime != 0) {
22869 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22870 mLowRamStartTime = 0;
22872 for (int i=N-1; i>=0; i--) {
22873 ProcessRecord app = mLruProcesses.get(i);
22874 if (allChanged || app.procStateChanged) {
22875 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22876 app.procStateChanged = false;
22878 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22879 || app.systemNoUi) && app.pendingUiClean) {
22880 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22881 && app.thread != null) {
22883 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22884 "Trimming memory of ui hidden " + app.processName
22885 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22886 app.thread.scheduleTrimMemory(
22887 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22888 } catch (RemoteException e) {
22891 app.pendingUiClean = false;
22893 app.trimMemoryLevel = 0;
22897 if (mAlwaysFinishActivities) {
22898 // Need to do this on its own message because the stack may not
22899 // be in a consistent state at this point.
22900 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22904 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22907 ArrayList<UidRecord> becameIdle = null;
22909 // Update from any uid changes.
22910 if (mLocalPowerManager != null) {
22911 mLocalPowerManager.startUidChanges();
22913 for (int i=mActiveUids.size()-1; i>=0; i--) {
22914 final UidRecord uidRec = mActiveUids.valueAt(i);
22915 int uidChange = UidRecord.CHANGE_PROCSTATE;
22916 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22917 && (uidRec.setProcState != uidRec.curProcState
22918 || uidRec.setWhitelist != uidRec.curWhitelist)) {
22919 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22920 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22921 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22922 + " to " + uidRec.curWhitelist);
22923 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22924 && !uidRec.curWhitelist) {
22925 // UID is now in the background (and not on the temp whitelist). Was it
22926 // previously in the foreground (or on the temp whitelist)?
22927 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22928 || uidRec.setWhitelist) {
22929 uidRec.lastBackgroundTime = nowElapsed;
22930 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22931 // Note: the background settle time is in elapsed realtime, while
22932 // the handler time base is uptime. All this means is that we may
22933 // stop background uids later than we had intended, but that only
22934 // happens because the device was sleeping so we are okay anyway.
22935 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22936 mConstants.BACKGROUND_SETTLE_TIME);
22939 if (uidRec.idle && !uidRec.setIdle) {
22940 uidChange = UidRecord.CHANGE_IDLE;
22941 if (becameIdle == null) {
22942 becameIdle = new ArrayList<>();
22944 becameIdle.add(uidRec);
22948 uidChange = UidRecord.CHANGE_ACTIVE;
22949 EventLogTags.writeAmUidActive(uidRec.uid);
22950 uidRec.idle = false;
22952 uidRec.lastBackgroundTime = 0;
22954 final boolean wasCached = uidRec.setProcState
22955 > ActivityManager.PROCESS_STATE_RECEIVER;
22956 final boolean isCached = uidRec.curProcState
22957 > ActivityManager.PROCESS_STATE_RECEIVER;
22958 if (wasCached != isCached ||
22959 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22960 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22962 uidRec.setProcState = uidRec.curProcState;
22963 uidRec.setWhitelist = uidRec.curWhitelist;
22964 uidRec.setIdle = uidRec.idle;
22965 enqueueUidChangeLocked(uidRec, -1, uidChange);
22966 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22967 if (uidRec.foregroundServices) {
22968 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22972 if (mLocalPowerManager != null) {
22973 mLocalPowerManager.finishUidChanges();
22976 if (becameIdle != null) {
22977 // If we have any new uids that became idle this time, we need to make sure
22978 // they aren't left with running services.
22979 for (int i = becameIdle.size() - 1; i >= 0; i--) {
22980 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22984 if (mProcessStats.shouldWriteNowLocked(now)) {
22985 mHandler.post(new Runnable() {
22986 @Override public void run() {
22987 synchronized (ActivityManagerService.this) {
22988 mProcessStats.writeStateAsyncLocked();
22994 if (DEBUG_OOM_ADJ) {
22995 final long duration = SystemClock.uptimeMillis() - now;
22997 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22998 new RuntimeException("here").fillInStackTrace());
23000 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23006 public void makePackageIdle(String packageName, int userId) {
23007 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23008 != PackageManager.PERMISSION_GRANTED) {
23009 String msg = "Permission Denial: makePackageIdle() from pid="
23010 + Binder.getCallingPid()
23011 + ", uid=" + Binder.getCallingUid()
23012 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23014 throw new SecurityException(msg);
23016 final int callingPid = Binder.getCallingPid();
23017 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23018 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23019 long callingId = Binder.clearCallingIdentity();
23020 synchronized(this) {
23022 IPackageManager pm = AppGlobals.getPackageManager();
23025 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23026 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23027 } catch (RemoteException e) {
23029 if (pkgUid == -1) {
23030 throw new IllegalArgumentException("Unknown package name " + packageName);
23033 if (mLocalPowerManager != null) {
23034 mLocalPowerManager.startUidChanges();
23036 final int appId = UserHandle.getAppId(pkgUid);
23037 final int N = mActiveUids.size();
23038 for (int i=N-1; i>=0; i--) {
23039 final UidRecord uidRec = mActiveUids.valueAt(i);
23040 final long bgTime = uidRec.lastBackgroundTime;
23041 if (bgTime > 0 && !uidRec.idle) {
23042 if (UserHandle.getAppId(uidRec.uid) == appId) {
23043 if (userId == UserHandle.USER_ALL ||
23044 userId == UserHandle.getUserId(uidRec.uid)) {
23045 EventLogTags.writeAmUidIdle(uidRec.uid);
23046 uidRec.idle = true;
23047 uidRec.setIdle = true;
23048 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23049 + " from package " + packageName + " user " + userId);
23050 doStopUidLocked(uidRec.uid, uidRec);
23056 if (mLocalPowerManager != null) {
23057 mLocalPowerManager.finishUidChanges();
23059 Binder.restoreCallingIdentity(callingId);
23064 final void idleUids() {
23065 synchronized (this) {
23066 final int N = mActiveUids.size();
23070 final long nowElapsed = SystemClock.elapsedRealtime();
23071 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23073 if (mLocalPowerManager != null) {
23074 mLocalPowerManager.startUidChanges();
23076 for (int i=N-1; i>=0; i--) {
23077 final UidRecord uidRec = mActiveUids.valueAt(i);
23078 final long bgTime = uidRec.lastBackgroundTime;
23079 if (bgTime > 0 && !uidRec.idle) {
23080 if (bgTime <= maxBgTime) {
23081 EventLogTags.writeAmUidIdle(uidRec.uid);
23082 uidRec.idle = true;
23083 uidRec.setIdle = true;
23084 doStopUidLocked(uidRec.uid, uidRec);
23086 if (nextTime == 0 || nextTime > bgTime) {
23092 if (mLocalPowerManager != null) {
23093 mLocalPowerManager.finishUidChanges();
23095 if (nextTime > 0) {
23096 mHandler.removeMessages(IDLE_UIDS_MSG);
23097 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23098 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23104 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23105 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23106 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23110 void incrementProcStateSeqAndNotifyAppsLocked() {
23111 if (mWaitForNetworkTimeoutMs <= 0) {
23114 // Used for identifying which uids need to block for network.
23115 ArrayList<Integer> blockingUids = null;
23116 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23117 final UidRecord uidRec = mActiveUids.valueAt(i);
23118 // If the network is not restricted for uid, then nothing to do here.
23119 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23122 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23125 // If process state is not changed, then there's nothing to do.
23126 if (uidRec.setProcState == uidRec.curProcState) {
23129 final int blockState = getBlockStateForUid(uidRec);
23130 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23131 // there's nothing the app needs to do in this scenario.
23132 if (blockState == NETWORK_STATE_NO_CHANGE) {
23135 synchronized (uidRec.networkStateLock) {
23136 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23137 if (blockState == NETWORK_STATE_BLOCK) {
23138 if (blockingUids == null) {
23139 blockingUids = new ArrayList<>();
23141 blockingUids.add(uidRec.uid);
23143 if (DEBUG_NETWORK) {
23144 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23145 + " threads for uid: " + uidRec);
23147 if (uidRec.waitingForNetwork) {
23148 uidRec.networkStateLock.notifyAll();
23154 // There are no uids that need to block, so nothing more to do.
23155 if (blockingUids == null) {
23159 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23160 final ProcessRecord app = mLruProcesses.get(i);
23161 if (!blockingUids.contains(app.uid)) {
23164 if (!app.killedByAm && app.thread != null) {
23165 final UidRecord uidRec = mActiveUids.get(app.uid);
23167 if (DEBUG_NETWORK) {
23168 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23171 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23172 } catch (RemoteException ignored) {
23179 * Checks if the uid is coming from background to foreground or vice versa and returns
23180 * appropriate block state based on this.
23182 * @return blockState based on whether the uid is coming from background to foreground or
23183 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23184 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23185 * {@link #NETWORK_STATE_NO_CHANGE}.
23188 int getBlockStateForUid(UidRecord uidRec) {
23189 // Denotes whether uid's process state is currently allowed network access.
23190 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23191 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23192 // Denotes whether uid's process state was previously allowed network access.
23193 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23194 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23196 // When the uid is coming to foreground, AMS should inform the app thread that it should
23197 // block for the network rules to get updated before launching an activity.
23198 if (!wasAllowed && isAllowed) {
23199 return NETWORK_STATE_BLOCK;
23201 // When the uid is going to background, AMS should inform the app thread that if an
23202 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23203 if (wasAllowed && !isAllowed) {
23204 return NETWORK_STATE_UNBLOCK;
23206 return NETWORK_STATE_NO_CHANGE;
23209 final void runInBackgroundDisabled(int uid) {
23210 synchronized (this) {
23211 UidRecord uidRec = mActiveUids.get(uid);
23212 if (uidRec != null) {
23213 // This uid is actually running... should it be considered background now?
23215 doStopUidLocked(uidRec.uid, uidRec);
23218 // This uid isn't actually running... still send a report about it being "stopped".
23219 doStopUidLocked(uid, null);
23224 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23225 mServices.stopInBackgroundLocked(uid);
23226 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23230 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23232 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23233 long duration, String tag) {
23234 if (DEBUG_WHITELISTS) {
23235 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23236 + targetUid + ", " + duration + ")");
23239 synchronized (mPidsSelfLocked) {
23240 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23242 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23246 if (!pr.whitelistManager) {
23247 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23248 != PackageManager.PERMISSION_GRANTED) {
23249 if (DEBUG_WHITELISTS) {
23250 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23251 + ": pid " + callerPid + " is not allowed");
23258 tempWhitelistUidLocked(targetUid, duration, tag);
23262 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23264 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23265 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23266 setUidTempWhitelistStateLocked(targetUid, true);
23267 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23270 void pushTempWhitelist() {
23272 final PendingTempWhitelist[] list;
23274 // First copy out the pending changes... we need to leave them in the map for now,
23275 // in case someone needs to check what is coming up while we don't have the lock held.
23276 synchronized(this) {
23277 N = mPendingTempWhitelist.size();
23278 list = new PendingTempWhitelist[N];
23279 for (int i = 0; i < N; i++) {
23280 list[i] = mPendingTempWhitelist.valueAt(i);
23284 // Now safely dispatch changes to device idle controller.
23285 for (int i = 0; i < N; i++) {
23286 PendingTempWhitelist ptw = list[i];
23287 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23288 ptw.duration, true, ptw.tag);
23291 // And now we can safely remove them from the map.
23292 synchronized(this) {
23293 for (int i = 0; i < N; i++) {
23294 PendingTempWhitelist ptw = list[i];
23295 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23296 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23297 mPendingTempWhitelist.removeAt(index);
23303 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23304 boolean changed = false;
23305 for (int i=mActiveUids.size()-1; i>=0; i--) {
23306 final UidRecord uidRec = mActiveUids.valueAt(i);
23307 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23308 uidRec.curWhitelist = onWhitelist;
23313 updateOomAdjLocked();
23317 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23318 boolean changed = false;
23319 final UidRecord uidRec = mActiveUids.get(uid);
23320 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23321 uidRec.curWhitelist = onWhitelist;
23322 updateOomAdjLocked();
23326 final void trimApplications() {
23327 synchronized (this) {
23330 // First remove any unused application processes whose package
23331 // has been removed.
23332 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23333 final ProcessRecord app = mRemovedProcesses.get(i);
23334 if (app.activities.size() == 0
23335 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23337 TAG, "Exiting empty application process "
23338 + app.toShortString() + " ("
23339 + (app.thread != null ? app.thread.asBinder() : null)
23341 if (app.pid > 0 && app.pid != MY_PID) {
23342 app.kill("empty", false);
23345 app.thread.scheduleExit();
23346 } catch (Exception e) {
23347 // Ignore exceptions.
23350 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23351 mRemovedProcesses.remove(i);
23353 if (app.persistent) {
23354 addAppLocked(app.info, null, false, null /* ABI override */);
23359 // Now update the oom adj for all processes.
23360 updateOomAdjLocked();
23364 /** This method sends the specified signal to each of the persistent apps */
23365 public void signalPersistentProcesses(int sig) throws RemoteException {
23366 if (sig != SIGNAL_USR1) {
23367 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23370 synchronized (this) {
23371 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23372 != PackageManager.PERMISSION_GRANTED) {
23373 throw new SecurityException("Requires permission "
23374 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23377 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23378 ProcessRecord r = mLruProcesses.get(i);
23379 if (r.thread != null && r.persistent) {
23380 sendSignal(r.pid, sig);
23386 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23387 if (proc == null || proc == mProfileProc) {
23388 proc = mProfileProc;
23389 profileType = mProfileType;
23390 clearProfilerLocked();
23392 if (proc == null) {
23396 proc.thread.profilerControl(false, null, profileType);
23397 } catch (RemoteException e) {
23398 throw new IllegalStateException("Process disappeared");
23402 private void clearProfilerLocked() {
23403 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23405 mProfilerInfo.profileFd.close();
23406 } catch (IOException e) {
23409 mProfileApp = null;
23410 mProfileProc = null;
23411 mProfilerInfo = null;
23414 public boolean profileControl(String process, int userId, boolean start,
23415 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23418 synchronized (this) {
23419 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23420 // its own permission.
23421 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23422 != PackageManager.PERMISSION_GRANTED) {
23423 throw new SecurityException("Requires permission "
23424 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23427 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23428 throw new IllegalArgumentException("null profile info or fd");
23431 ProcessRecord proc = null;
23432 if (process != null) {
23433 proc = findProcessLocked(process, userId, "profileControl");
23436 if (start && (proc == null || proc.thread == null)) {
23437 throw new IllegalArgumentException("Unknown process: " + process);
23441 stopProfilerLocked(null, 0);
23442 setProfileApp(proc.info, proc.processName, profilerInfo);
23443 mProfileProc = proc;
23444 mProfileType = profileType;
23445 ParcelFileDescriptor fd = profilerInfo.profileFd;
23448 } catch (IOException e) {
23451 profilerInfo.profileFd = fd;
23452 proc.thread.profilerControl(start, profilerInfo, profileType);
23455 mProfilerInfo.profileFd.close();
23456 } catch (IOException e) {
23458 mProfilerInfo.profileFd = null;
23460 stopProfilerLocked(proc, profileType);
23461 if (profilerInfo != null && profilerInfo.profileFd != null) {
23463 profilerInfo.profileFd.close();
23464 } catch (IOException e) {
23471 } catch (RemoteException e) {
23472 throw new IllegalStateException("Process disappeared");
23474 if (profilerInfo != null && profilerInfo.profileFd != null) {
23476 profilerInfo.profileFd.close();
23477 } catch (IOException e) {
23483 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23484 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23485 userId, true, ALLOW_FULL_ONLY, callName, null);
23486 ProcessRecord proc = null;
23488 int pid = Integer.parseInt(process);
23489 synchronized (mPidsSelfLocked) {
23490 proc = mPidsSelfLocked.get(pid);
23492 } catch (NumberFormatException e) {
23495 if (proc == null) {
23496 ArrayMap<String, SparseArray<ProcessRecord>> all
23497 = mProcessNames.getMap();
23498 SparseArray<ProcessRecord> procs = all.get(process);
23499 if (procs != null && procs.size() > 0) {
23500 proc = procs.valueAt(0);
23501 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23502 for (int i=1; i<procs.size(); i++) {
23503 ProcessRecord thisProc = procs.valueAt(i);
23504 if (thisProc.userId == userId) {
23516 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23517 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23520 synchronized (this) {
23521 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23522 // its own permission (same as profileControl).
23523 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23524 != PackageManager.PERMISSION_GRANTED) {
23525 throw new SecurityException("Requires permission "
23526 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23530 throw new IllegalArgumentException("null fd");
23533 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23534 if (proc == null || proc.thread == null) {
23535 throw new IllegalArgumentException("Unknown process: " + process);
23538 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23539 if (!isDebuggable) {
23540 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23541 throw new SecurityException("Process not debuggable: " + proc);
23545 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23549 } catch (RemoteException e) {
23550 throw new IllegalStateException("Process disappeared");
23555 } catch (IOException e) {
23562 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23563 String reportPackage) {
23564 if (processName != null) {
23565 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23566 "setDumpHeapDebugLimit()");
23568 synchronized (mPidsSelfLocked) {
23569 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23570 if (proc == null) {
23571 throw new SecurityException("No process found for calling pid "
23572 + Binder.getCallingPid());
23574 if (!Build.IS_DEBUGGABLE
23575 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23576 throw new SecurityException("Not running a debuggable build");
23578 processName = proc.processName;
23580 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23581 throw new SecurityException("Package " + reportPackage + " is not running in "
23586 synchronized (this) {
23587 if (maxMemSize > 0) {
23588 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23591 mMemWatchProcesses.remove(processName, uid);
23593 mMemWatchProcesses.getMap().remove(processName);
23600 public void dumpHeapFinished(String path) {
23601 synchronized (this) {
23602 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23603 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23604 + " does not match last pid " + mMemWatchDumpPid);
23607 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23608 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23609 + " does not match last path " + mMemWatchDumpFile);
23612 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23613 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23615 // Forced gc to clean up the remnant hprof fd.
23616 Runtime.getRuntime().gc();
23620 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23621 public void monitor() {
23622 synchronized (this) { }
23625 void onCoreSettingsChange(Bundle settings) {
23626 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23627 ProcessRecord processRecord = mLruProcesses.get(i);
23629 if (processRecord.thread != null) {
23630 processRecord.thread.setCoreSettings(settings);
23632 } catch (RemoteException re) {
23638 // Multi-user methods
23641 * Start user, if its not already running, but don't bring it to foreground.
23644 public boolean startUserInBackground(final int userId) {
23645 return mUserController.startUser(userId, /* foreground */ false);
23649 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23650 return mUserController.unlockUser(userId, token, secret, listener);
23654 public boolean switchUser(final int targetUserId) {
23655 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23657 UserInfo targetUserInfo;
23658 synchronized (this) {
23659 currentUserId = mUserController.getCurrentUserIdLocked();
23660 targetUserInfo = mUserController.getUserInfo(targetUserId);
23661 if (targetUserId == currentUserId) {
23662 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23665 if (targetUserInfo == null) {
23666 Slog.w(TAG, "No user info for user #" + targetUserId);
23669 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23670 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23671 + " when device is in demo mode");
23674 if (!targetUserInfo.supportsSwitchTo()) {
23675 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23678 if (targetUserInfo.isManagedProfile()) {
23679 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23682 mUserController.setTargetUserIdLocked(targetUserId);
23684 if (mUserController.mUserSwitchUiEnabled) {
23685 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23686 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23687 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23688 mUiHandler.sendMessage(mHandler.obtainMessage(
23689 START_USER_SWITCH_UI_MSG, userNames));
23691 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23692 mHandler.sendMessage(mHandler.obtainMessage(
23693 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23698 void scheduleStartProfilesLocked() {
23699 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23700 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23701 DateUtils.SECOND_IN_MILLIS);
23706 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23707 return mUserController.stopUser(userId, force, callback);
23711 public UserInfo getCurrentUser() {
23712 return mUserController.getCurrentUser();
23715 String getStartedUserState(int userId) {
23716 synchronized (this) {
23717 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23718 return UserState.stateToString(userState.state);
23723 public boolean isUserRunning(int userId, int flags) {
23724 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23725 && checkCallingPermission(INTERACT_ACROSS_USERS)
23726 != PackageManager.PERMISSION_GRANTED) {
23727 String msg = "Permission Denial: isUserRunning() from pid="
23728 + Binder.getCallingPid()
23729 + ", uid=" + Binder.getCallingUid()
23730 + " requires " + INTERACT_ACROSS_USERS;
23732 throw new SecurityException(msg);
23734 synchronized (this) {
23735 return mUserController.isUserRunningLocked(userId, flags);
23740 public int[] getRunningUserIds() {
23741 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23742 != PackageManager.PERMISSION_GRANTED) {
23743 String msg = "Permission Denial: isUserRunning() from pid="
23744 + Binder.getCallingPid()
23745 + ", uid=" + Binder.getCallingUid()
23746 + " requires " + INTERACT_ACROSS_USERS;
23748 throw new SecurityException(msg);
23750 synchronized (this) {
23751 return mUserController.getStartedUserArrayLocked();
23756 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23757 mUserController.registerUserSwitchObserver(observer, name);
23761 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23762 mUserController.unregisterUserSwitchObserver(observer);
23765 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23766 if (info == null) return null;
23767 ApplicationInfo newInfo = new ApplicationInfo(info);
23768 newInfo.initForUser(userId);
23772 public boolean isUserStopped(int userId) {
23773 synchronized (this) {
23774 return mUserController.getStartedUserStateLocked(userId) == null;
23778 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23780 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23784 ActivityInfo info = new ActivityInfo(aInfo);
23785 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23789 private boolean processSanityChecksLocked(ProcessRecord process) {
23790 if (process == null || process.thread == null) {
23794 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23795 if (!isDebuggable) {
23796 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23804 public boolean startBinderTracking() throws RemoteException {
23805 synchronized (this) {
23806 mBinderTransactionTrackingEnabled = true;
23807 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23808 // permission (same as profileControl).
23809 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23810 != PackageManager.PERMISSION_GRANTED) {
23811 throw new SecurityException("Requires permission "
23812 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23815 for (int i = 0; i < mLruProcesses.size(); i++) {
23816 ProcessRecord process = mLruProcesses.get(i);
23817 if (!processSanityChecksLocked(process)) {
23821 process.thread.startBinderTracking();
23822 } catch (RemoteException e) {
23823 Log.v(TAG, "Process disappared");
23830 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23832 synchronized (this) {
23833 mBinderTransactionTrackingEnabled = false;
23834 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23835 // permission (same as profileControl).
23836 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23837 != PackageManager.PERMISSION_GRANTED) {
23838 throw new SecurityException("Requires permission "
23839 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23843 throw new IllegalArgumentException("null fd");
23846 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23847 pw.println("Binder transaction traces for all processes.\n");
23848 for (ProcessRecord process : mLruProcesses) {
23849 if (!processSanityChecksLocked(process)) {
23853 pw.println("Traces for process: " + process.processName);
23856 TransferPipe tp = new TransferPipe();
23858 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23859 tp.go(fd.getFileDescriptor());
23863 } catch (IOException e) {
23864 pw.println("Failure while dumping IPC traces from " + process +
23865 ". Exception: " + e);
23867 } catch (RemoteException e) {
23868 pw.println("Got a RemoteException while dumping IPC traces from " +
23869 process + ". Exception: " + e);
23880 } catch (IOException e) {
23887 final class LocalService extends ActivityManagerInternal {
23889 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23890 int targetUserId) {
23891 synchronized (ActivityManagerService.this) {
23892 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23893 targetPkg, intent, null, targetUserId);
23898 public String checkContentProviderAccess(String authority, int userId) {
23899 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23903 public void onWakefulnessChanged(int wakefulness) {
23904 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23908 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23909 String processName, String abiOverride, int uid, Runnable crashHandler) {
23910 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23911 processName, abiOverride, uid, crashHandler);
23915 public SleepToken acquireSleepToken(String tag, int displayId) {
23916 Preconditions.checkNotNull(tag);
23917 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23921 public ComponentName getHomeActivityForUser(int userId) {
23922 synchronized (ActivityManagerService.this) {
23923 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23924 return homeActivity == null ? null : homeActivity.realActivity;
23929 public void onUserRemoved(int userId) {
23930 synchronized (ActivityManagerService.this) {
23931 ActivityManagerService.this.onUserStoppedLocked(userId);
23933 mBatteryStatsService.onUserRemoved(userId);
23937 public void onLocalVoiceInteractionStarted(IBinder activity,
23938 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23939 synchronized (ActivityManagerService.this) {
23940 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23941 voiceSession, voiceInteractor);
23946 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23947 synchronized (ActivityManagerService.this) {
23948 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23949 reasons, timestamp);
23954 public void notifyAppTransitionFinished() {
23955 synchronized (ActivityManagerService.this) {
23956 mStackSupervisor.notifyAppTransitionDone();
23961 public void notifyAppTransitionCancelled() {
23962 synchronized (ActivityManagerService.this) {
23963 mStackSupervisor.notifyAppTransitionDone();
23968 public List<IBinder> getTopVisibleActivities() {
23969 synchronized (ActivityManagerService.this) {
23970 return mStackSupervisor.getTopVisibleActivities();
23975 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23976 synchronized (ActivityManagerService.this) {
23977 mStackSupervisor.setDockedStackMinimized(minimized);
23982 public void killForegroundAppsForUser(int userHandle) {
23983 synchronized (ActivityManagerService.this) {
23984 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23985 final int NP = mProcessNames.getMap().size();
23986 for (int ip = 0; ip < NP; ip++) {
23987 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23988 final int NA = apps.size();
23989 for (int ia = 0; ia < NA; ia++) {
23990 final ProcessRecord app = apps.valueAt(ia);
23991 if (app.persistent) {
23992 // We don't kill persistent processes.
23997 } else if (app.userId == userHandle && app.foregroundActivities) {
23998 app.removed = true;
24004 final int N = procs.size();
24005 for (int i = 0; i < N; i++) {
24006 removeProcessLocked(procs.get(i), false, true, "kill all fg");
24012 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24014 if (!(target instanceof PendingIntentRecord)) {
24015 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24018 synchronized (ActivityManagerService.this) {
24019 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24024 public void setDeviceIdleWhitelist(int[] appids) {
24025 synchronized (ActivityManagerService.this) {
24026 mDeviceIdleWhitelist = appids;
24031 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24032 synchronized (ActivityManagerService.this) {
24033 mDeviceIdleTempWhitelist = appids;
24034 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24039 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24041 Preconditions.checkNotNull(values, "Configuration must not be null");
24042 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24043 synchronized (ActivityManagerService.this) {
24044 updateConfigurationLocked(values, null, false, true, userId,
24045 false /* deferResume */);
24050 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24052 Preconditions.checkNotNull(intents, "intents");
24053 final String[] resolvedTypes = new String[intents.length];
24054 for (int i = 0; i < intents.length; i++) {
24055 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24058 // UID of the package on user userId.
24059 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24060 // packageUid may not be initialized.
24061 int packageUid = 0;
24063 packageUid = AppGlobals.getPackageManager().getPackageUid(
24064 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24065 } catch (RemoteException e) {
24066 // Shouldn't happen.
24069 synchronized (ActivityManagerService.this) {
24070 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24071 /*resultTo*/ null, bOptions, userId);
24076 public int getUidProcessState(int uid) {
24077 return getUidState(uid);
24081 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24082 synchronized (ActivityManagerService.this) {
24084 // We might change the visibilities here, so prepare an empty app transition which
24085 // might be overridden later if we actually change visibilities.
24086 final boolean wasTransitionSet =
24087 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24088 if (!wasTransitionSet) {
24089 mWindowManager.prepareAppTransition(TRANSIT_NONE,
24090 false /* alwaysKeepCurrent */);
24092 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24094 // If there was a transition set already we don't want to interfere with it as we
24095 // might be starting it too early.
24096 if (!wasTransitionSet) {
24097 mWindowManager.executeAppTransition();
24100 if (callback != null) {
24106 public boolean isSystemReady() {
24107 // no need to synchronize(this) just to read & return the value
24108 return mSystemReady;
24112 public void notifyKeyguardTrustedChanged() {
24113 synchronized (ActivityManagerService.this) {
24114 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24115 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24121 * Sets if the given pid has an overlay UI or not.
24123 * @param pid The pid we are setting overlay UI for.
24124 * @param hasOverlayUi True if the process has overlay UI.
24125 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24128 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24129 synchronized (ActivityManagerService.this) {
24130 final ProcessRecord pr;
24131 synchronized (mPidsSelfLocked) {
24132 pr = mPidsSelfLocked.get(pid);
24134 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24138 if (pr.hasOverlayUi == hasOverlayUi) {
24141 pr.hasOverlayUi = hasOverlayUi;
24142 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24143 updateOomAdjLocked(pr, true);
24148 * Called after the network policy rules are updated by
24149 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24150 * and {@param procStateSeq}.
24153 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24154 if (DEBUG_NETWORK) {
24155 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24156 + uid + " seq: " + procStateSeq);
24159 synchronized (ActivityManagerService.this) {
24160 record = mActiveUids.get(uid);
24161 if (record == null) {
24162 if (DEBUG_NETWORK) {
24163 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24164 + " procStateSeq: " + procStateSeq);
24169 synchronized (record.networkStateLock) {
24170 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24171 if (DEBUG_NETWORK) {
24172 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24173 + " been handled for uid: " + uid);
24177 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24178 if (record.curProcStateSeq > procStateSeq) {
24179 if (DEBUG_NETWORK) {
24180 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24181 + ", curProcstateSeq: " + record.curProcStateSeq
24182 + ", procStateSeq: " + procStateSeq);
24186 if (record.waitingForNetwork) {
24187 if (DEBUG_NETWORK) {
24188 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24189 + ", procStateSeq: " + procStateSeq);
24191 record.networkStateLock.notifyAll();
24197 * Called after virtual display Id is updated by
24198 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24199 * {@param vrVr2dDisplayId}.
24202 public void setVr2dDisplayId(int vr2dDisplayId) {
24204 Slog.d(TAG, "setVr2dDisplayId called for: " +
24207 synchronized (ActivityManagerService.this) {
24208 mVr2dDisplayId = vr2dDisplayId;
24213 public void saveANRState(String reason) {
24214 synchronized (ActivityManagerService.this) {
24215 final StringWriter sw = new StringWriter();
24216 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24217 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24218 if (reason != null) {
24219 pw.println(" Reason: " + reason);
24222 mActivityStarter.dump(pw, " ", null);
24224 pw.println("-------------------------------------------------------------------------------");
24225 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24226 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24231 mLastANRState = sw.toString();
24236 public void clearSavedANRState() {
24237 synchronized (ActivityManagerService.this) {
24238 mLastANRState = null;
24243 public void setFocusedActivity(IBinder token) {
24244 synchronized (ActivityManagerService.this) {
24245 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24247 throw new IllegalArgumentException(
24248 "setFocusedActivity: No activity record matching token=" + token);
24250 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24251 r, "setFocusedActivity")) {
24252 mStackSupervisor.resumeFocusedStackTopActivityLocked();
24258 public void registerScreenObserver(ScreenObserver observer) {
24259 mScreenObservers.add(observer);
24264 * Called by app main thread to wait for the network policy rules to get updated.
24266 * @param procStateSeq The sequence number indicating the process state change that the main
24267 * thread is interested in.
24270 public void waitForNetworkStateUpdate(long procStateSeq) {
24271 final int callingUid = Binder.getCallingUid();
24272 if (DEBUG_NETWORK) {
24273 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24276 synchronized (this) {
24277 record = mActiveUids.get(callingUid);
24278 if (record == null) {
24282 synchronized (record.networkStateLock) {
24283 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24284 if (DEBUG_NETWORK) {
24285 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24286 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24287 + " lastProcStateSeqDispatchedToObservers: "
24288 + record.lastDispatchedProcStateSeq);
24292 if (record.curProcStateSeq > procStateSeq) {
24293 if (DEBUG_NETWORK) {
24294 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24295 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24296 + ", procStateSeq: " + procStateSeq);
24300 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24301 if (DEBUG_NETWORK) {
24302 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24303 + procStateSeq + ", so no need to wait. Uid: "
24304 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24305 + record.lastNetworkUpdatedProcStateSeq);
24310 if (DEBUG_NETWORK) {
24311 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24312 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24314 final long startTime = SystemClock.uptimeMillis();
24315 record.waitingForNetwork = true;
24316 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24317 record.waitingForNetwork = false;
24318 final long totalTime = SystemClock.uptimeMillis() - startTime;
24319 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24320 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24321 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24322 + procStateSeq + " UidRec: " + record
24323 + " validateUidRec: " + mValidateUids.get(callingUid));
24325 } catch (InterruptedException e) {
24326 Thread.currentThread().interrupt();
24331 public void waitForBroadcastIdle(PrintWriter pw) {
24332 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24334 boolean idle = true;
24335 synchronized (this) {
24336 for (BroadcastQueue queue : mBroadcastQueues) {
24337 if (!queue.isIdle()) {
24338 final String msg = "Waiting for queue " + queue + " to become idle...";
24348 final String msg = "All broadcast queues are idle!";
24354 SystemClock.sleep(1000);
24360 * Return the user id of the last resumed activity.
24363 public @UserIdInt int getLastResumedActivityUserId() {
24364 enforceCallingPermission(
24365 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24366 synchronized (this) {
24367 if (mLastResumedActivity == null) {
24368 return mUserController.getCurrentUserIdLocked();
24370 return mLastResumedActivity.userId;
24375 * An implementation of IAppTask, that allows an app to manage its own tasks via
24376 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24377 * only the process that calls getAppTasks() can call the AppTask methods.
24379 class AppTaskImpl extends IAppTask.Stub {
24380 private int mTaskId;
24381 private int mCallingUid;
24383 public AppTaskImpl(int taskId, int callingUid) {
24385 mCallingUid = callingUid;
24388 private void checkCaller() {
24389 if (mCallingUid != Binder.getCallingUid()) {
24390 throw new SecurityException("Caller " + mCallingUid
24391 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24396 public void finishAndRemoveTask() {
24399 synchronized (ActivityManagerService.this) {
24400 long origId = Binder.clearCallingIdentity();
24402 // We remove the task from recents to preserve backwards
24403 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24404 REMOVE_FROM_RECENTS)) {
24405 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24408 Binder.restoreCallingIdentity(origId);
24414 public ActivityManager.RecentTaskInfo getTaskInfo() {
24417 synchronized (ActivityManagerService.this) {
24418 long origId = Binder.clearCallingIdentity();
24420 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24422 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24424 return createRecentTaskInfoFromTaskRecord(tr);
24426 Binder.restoreCallingIdentity(origId);
24432 public void moveToFront() {
24434 // Will bring task to front if it already has a root activity.
24435 final long origId = Binder.clearCallingIdentity();
24437 synchronized (this) {
24438 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24441 Binder.restoreCallingIdentity(origId);
24446 public int startActivity(IBinder whoThread, String callingPackage,
24447 Intent intent, String resolvedType, Bundle bOptions) {
24450 int callingUser = UserHandle.getCallingUserId();
24452 IApplicationThread appThread;
24453 synchronized (ActivityManagerService.this) {
24454 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24456 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24458 appThread = IApplicationThread.Stub.asInterface(whoThread);
24459 if (appThread == null) {
24460 throw new IllegalArgumentException("Bad app thread " + appThread);
24463 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24464 resolvedType, null, null, null, null, 0, 0, null, null,
24465 null, bOptions, false, callingUser, tr, "AppTaskImpl");
24469 public void setExcludeFromRecents(boolean exclude) {
24472 synchronized (ActivityManagerService.this) {
24473 long origId = Binder.clearCallingIdentity();
24475 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24477 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24479 Intent intent = tr.getBaseIntent();
24481 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24483 intent.setFlags(intent.getFlags()
24484 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24487 Binder.restoreCallingIdentity(origId);
24494 * Kill processes for the user with id userId and that depend on the package named packageName
24497 public void killPackageDependents(String packageName, int userId) {
24498 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24499 if (packageName == null) {
24500 throw new NullPointerException(
24501 "Cannot kill the dependents of a package without its name.");
24504 long callingId = Binder.clearCallingIdentity();
24505 IPackageManager pm = AppGlobals.getPackageManager();
24508 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24509 } catch (RemoteException e) {
24511 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24512 throw new IllegalArgumentException(
24513 "Cannot kill dependents of non-existing package " + packageName);
24516 synchronized(this) {
24517 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24518 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24519 "dep: " + packageName);
24522 Binder.restoreCallingIdentity(callingId);
24527 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24528 throws RemoteException {
24529 final long callingId = Binder.clearCallingIdentity();
24531 mKeyguardController.dismissKeyguard(token, callback);
24533 Binder.restoreCallingIdentity(callingId);
24538 public int restartUserInBackground(final int userId) {
24539 return mUserController.restartUser(userId, /* foreground */ false);
24543 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24544 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24545 "scheduleApplicationInfoChanged()");
24547 synchronized (this) {
24548 final long origId = Binder.clearCallingIdentity();
24550 updateApplicationInfoLocked(packageNames, userId);
24552 Binder.restoreCallingIdentity(origId);
24557 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24558 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24559 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24560 final ProcessRecord app = mLruProcesses.get(i);
24561 if (app.thread == null) {
24565 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24569 final int packageCount = app.pkgList.size();
24570 for (int j = 0; j < packageCount; j++) {
24571 final String packageName = app.pkgList.keyAt(j);
24572 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24574 final ApplicationInfo ai = AppGlobals.getPackageManager()
24575 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24577 app.thread.scheduleApplicationInfoChanged(ai);
24579 } catch (RemoteException e) {
24580 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24581 packageName, app));
24589 * Attach an agent to the specified process (proces name or PID)
24591 public void attachAgent(String process, String path) {
24593 synchronized (this) {
24594 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24595 if (proc == null || proc.thread == null) {
24596 throw new IllegalArgumentException("Unknown process: " + process);
24599 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24600 if (!isDebuggable) {
24601 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24602 throw new SecurityException("Process not debuggable: " + proc);
24606 proc.thread.attachAgent(path);
24608 } catch (RemoteException e) {
24609 throw new IllegalStateException("Process disappeared");
24614 public static class Injector {
24615 private NetworkManagementInternal mNmi;
24617 public Context getContext() {
24621 public AppOpsService getAppOpsService(File file, Handler handler) {
24622 return new AppOpsService(file, handler);
24625 public Handler getUiHandler(ActivityManagerService service) {
24626 return service.new UiHandler();
24629 public boolean isNetworkRestrictedForUid(int uid) {
24630 if (ensureHasNetworkManagementInternal()) {
24631 return mNmi.isNetworkRestrictedForUid(uid);
24636 private boolean ensureHasNetworkManagementInternal() {
24637 if (mNmi == null) {
24638 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24640 return mNmi != null;
24645 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24646 throws RemoteException {
24647 synchronized (this) {
24648 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24652 final long origId = Binder.clearCallingIdentity();
24654 r.setShowWhenLocked(showWhenLocked);
24656 Binder.restoreCallingIdentity(origId);
24662 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24663 synchronized (this) {
24664 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24668 final long origId = Binder.clearCallingIdentity();
24670 r.setTurnScreenOn(turnScreenOn);
24672 Binder.restoreCallingIdentity(origId);