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 if (app.info.isAllowedToUseHiddenApi()) {
3881 // This app is allowed to use undocumented and private APIs. Set
3882 // up its runtime with the appropriate flag.
3883 runtimeFlags |= Zygote.DISABLE_HIDDEN_API_CHECKS;
3886 String invokeWith = null;
3887 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3888 // Debuggable apps may include a wrapper script with their library directory.
3889 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3890 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3892 if (new File(wrapperFileName).exists()) {
3893 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3896 StrictMode.setThreadPolicy(oldPolicy);
3900 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3901 if (requiredAbi == null) {
3902 requiredAbi = Build.SUPPORTED_ABIS[0];
3905 String instructionSet = null;
3906 if (app.info.primaryCpuAbi != null) {
3907 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3911 app.requiredAbi = requiredAbi;
3912 app.instructionSet = instructionSet;
3914 // the per-user SELinux context must be set
3915 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3916 Slog.wtf(TAG, "SELinux tag not defined",
3917 new IllegalStateException("SELinux tag not defined for "
3918 + app.info.packageName + " (uid " + app.uid + ")"));
3920 final String seInfo = app.info.seInfo
3921 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3922 // Start the process. It will either succeed and return a result containing
3923 // the PID of the new process, or else throw a RuntimeException.
3924 boolean isActivityProcess = (entryPoint == null);
3925 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3926 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3928 checkTime(startTime, "startProcess: asking zygote to start proc");
3929 ProcessStartResult startResult;
3930 if (hostingType.equals("webview_service")) {
3931 startResult = startWebView(entryPoint,
3932 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3933 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3934 app.info.dataDir, null, entryPointArgs);
3936 startResult = Process.start(entryPoint,
3937 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3938 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3939 app.info.dataDir, invokeWith, entryPointArgs);
3941 checkTime(startTime, "startProcess: returned from zygote!");
3942 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3944 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3945 checkTime(startTime, "startProcess: done updating battery stats");
3947 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3948 UserHandle.getUserId(uid), startResult.pid, uid,
3949 app.processName, hostingType,
3950 hostingNameStr != null ? hostingNameStr : "");
3953 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3954 seInfo, app.info.sourceDir, startResult.pid);
3955 } catch (RemoteException ex) {
3959 if (app.persistent) {
3960 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3963 checkTime(startTime, "startProcess: building log message");
3964 StringBuilder buf = mStringBuilder;
3966 buf.append("Start proc ");
3967 buf.append(startResult.pid);
3969 buf.append(app.processName);
3971 UserHandle.formatUid(buf, uid);
3972 if (!isActivityProcess) {
3974 buf.append(entryPoint);
3977 buf.append(" for ");
3978 buf.append(hostingType);
3979 if (hostingNameStr != null) {
3981 buf.append(hostingNameStr);
3983 Slog.i(TAG, buf.toString());
3984 app.setPid(startResult.pid);
3985 app.usingWrapper = startResult.usingWrapper;
3986 app.removed = false;
3988 app.killedByAm = false;
3989 checkTime(startTime, "startProcess: starting to update pids map");
3990 ProcessRecord oldApp;
3991 synchronized (mPidsSelfLocked) {
3992 oldApp = mPidsSelfLocked.get(startResult.pid);
3994 // If there is already an app occupying that pid that hasn't been cleaned up
3995 if (oldApp != null && !app.isolated) {
3996 // Clean up anything relating to this pid first
3997 Slog.w(TAG, "Reusing pid " + startResult.pid
3998 + " while app is still mapped to it");
3999 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4000 true /*replacingPid*/);
4002 synchronized (mPidsSelfLocked) {
4003 this.mPidsSelfLocked.put(startResult.pid, app);
4004 if (isActivityProcess) {
4005 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4007 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4008 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4011 checkTime(startTime, "startProcess: done updating pids map");
4012 } catch (RuntimeException e) {
4013 Slog.e(TAG, "Failure starting process " + app.processName, e);
4015 // Something went very wrong while trying to start this process; one
4016 // common case is when the package is frozen due to an active
4017 // upgrade. To recover, clean up any active bookkeeping related to
4018 // starting this process. (We already invoked this method once when
4019 // the package was initially frozen through KILL_APPLICATION_MSG, so
4020 // it doesn't hurt to use it again.)
4021 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4022 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4026 void updateUsageStats(ActivityRecord component, boolean resumed) {
4027 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4028 "updateUsageStats: comp=" + component + "res=" + resumed);
4029 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4031 if (mUsageStatsService != null) {
4032 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4033 UsageEvents.Event.MOVE_TO_FOREGROUND);
4035 synchronized (stats) {
4036 stats.noteActivityResumedLocked(component.app.uid);
4039 if (mUsageStatsService != null) {
4040 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4041 UsageEvents.Event.MOVE_TO_BACKGROUND);
4043 synchronized (stats) {
4044 stats.noteActivityPausedLocked(component.app.uid);
4049 Intent getHomeIntent() {
4050 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4051 intent.setComponent(mTopComponent);
4052 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4053 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4054 intent.addCategory(Intent.CATEGORY_HOME);
4059 boolean startHomeActivityLocked(int userId, String reason) {
4060 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4061 && mTopAction == null) {
4062 // We are running in factory test mode, but unable to find
4063 // the factory test app, so just sit around displaying the
4064 // error message and don't try to start anything.
4067 Intent intent = getHomeIntent();
4068 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4069 if (aInfo != null) {
4070 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4071 // Don't do this if the home app is currently being
4073 aInfo = new ActivityInfo(aInfo);
4074 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4075 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4076 aInfo.applicationInfo.uid, true);
4077 if (app == null || app.instr == null) {
4078 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4079 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4080 // For ANR debugging to verify if the user activity is the one that actually
4082 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4083 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4086 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4092 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4093 ActivityInfo ai = null;
4094 ComponentName comp = intent.getComponent();
4098 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4100 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4102 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4106 ai = info.activityInfo;
4109 } catch (RemoteException e) {
4117 * Starts the "new version setup screen" if appropriate.
4119 void startSetupActivityLocked() {
4120 // Only do this once per boot.
4121 if (mCheckedForSetup) {
4125 // We will show this screen if the current one is a different
4126 // version than the last one shown, and we are not running in
4127 // low-level factory test mode.
4128 final ContentResolver resolver = mContext.getContentResolver();
4129 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4130 Settings.Global.getInt(resolver,
4131 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4132 mCheckedForSetup = true;
4134 // See if we should be showing the platform update setup UI.
4135 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4136 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4137 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4138 if (!ris.isEmpty()) {
4139 final ResolveInfo ri = ris.get(0);
4140 String vers = ri.activityInfo.metaData != null
4141 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4143 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4144 vers = ri.activityInfo.applicationInfo.metaData.getString(
4145 Intent.METADATA_SETUP_VERSION);
4147 String lastVers = Settings.Secure.getString(
4148 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4149 if (vers != null && !vers.equals(lastVers)) {
4150 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4151 intent.setComponent(new ComponentName(
4152 ri.activityInfo.packageName, ri.activityInfo.name));
4153 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4154 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4155 null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4161 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4162 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4165 void enforceNotIsolatedCaller(String caller) {
4166 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4167 throw new SecurityException("Isolated process not allowed to call " + caller);
4171 void enforceShellRestriction(String restriction, int userHandle) {
4172 if (Binder.getCallingUid() == SHELL_UID) {
4173 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4174 throw new SecurityException("Shell does not have permission to access user "
4181 public int getFrontActivityScreenCompatMode() {
4182 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4183 synchronized (this) {
4184 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4189 public void setFrontActivityScreenCompatMode(int mode) {
4190 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4191 "setFrontActivityScreenCompatMode");
4192 synchronized (this) {
4193 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4198 public int getPackageScreenCompatMode(String packageName) {
4199 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4200 synchronized (this) {
4201 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4206 public void setPackageScreenCompatMode(String packageName, int mode) {
4207 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4208 "setPackageScreenCompatMode");
4209 synchronized (this) {
4210 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4215 public boolean getPackageAskScreenCompat(String packageName) {
4216 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4217 synchronized (this) {
4218 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4223 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4224 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4225 "setPackageAskScreenCompat");
4226 synchronized (this) {
4227 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4231 private boolean hasUsageStatsPermission(String callingPackage) {
4232 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4233 Binder.getCallingUid(), callingPackage);
4234 if (mode == AppOpsManager.MODE_DEFAULT) {
4235 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4236 == PackageManager.PERMISSION_GRANTED;
4238 return mode == AppOpsManager.MODE_ALLOWED;
4242 public int getPackageProcessState(String packageName, String callingPackage) {
4243 if (!hasUsageStatsPermission(callingPackage)) {
4244 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4245 "getPackageProcessState");
4248 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4249 synchronized (this) {
4250 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4251 final ProcessRecord proc = mLruProcesses.get(i);
4252 if (procState > proc.setProcState) {
4253 if (proc.pkgList.containsKey(packageName) ||
4254 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4255 procState = proc.setProcState;
4264 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4265 throws RemoteException {
4266 synchronized (this) {
4267 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4269 throw new IllegalArgumentException("Unknown process: " + process);
4271 if (app.thread == null) {
4272 throw new IllegalArgumentException("Process has no app thread");
4274 if (app.trimMemoryLevel >= level) {
4275 throw new IllegalArgumentException(
4276 "Unable to set a higher trim level than current level");
4278 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4279 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4280 throw new IllegalArgumentException("Unable to set a background trim level "
4281 + "on a foreground process");
4283 app.thread.scheduleTrimMemory(level);
4284 app.trimMemoryLevel = level;
4289 private void dispatchProcessesChanged() {
4291 synchronized (this) {
4292 N = mPendingProcessChanges.size();
4293 if (mActiveProcessChanges.length < N) {
4294 mActiveProcessChanges = new ProcessChangeItem[N];
4296 mPendingProcessChanges.toArray(mActiveProcessChanges);
4297 mPendingProcessChanges.clear();
4298 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4299 "*** Delivering " + N + " process changes");
4302 int i = mProcessObservers.beginBroadcast();
4305 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4306 if (observer != null) {
4308 for (int j=0; j<N; j++) {
4309 ProcessChangeItem item = mActiveProcessChanges[j];
4310 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4311 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4312 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4313 + item.uid + ": " + item.foregroundActivities);
4314 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4315 item.foregroundActivities);
4318 } catch (RemoteException e) {
4322 mProcessObservers.finishBroadcast();
4324 synchronized (this) {
4325 for (int j=0; j<N; j++) {
4326 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4331 private void dispatchProcessDied(int pid, int uid) {
4332 int i = mProcessObservers.beginBroadcast();
4335 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4336 if (observer != null) {
4338 observer.onProcessDied(pid, uid);
4339 } catch (RemoteException e) {
4343 mProcessObservers.finishBroadcast();
4347 void dispatchUidsChanged() {
4349 synchronized (this) {
4350 N = mPendingUidChanges.size();
4351 if (mActiveUidChanges.length < N) {
4352 mActiveUidChanges = new UidRecord.ChangeItem[N];
4354 for (int i=0; i<N; i++) {
4355 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4356 mActiveUidChanges[i] = change;
4357 if (change.uidRecord != null) {
4358 change.uidRecord.pendingChange = null;
4359 change.uidRecord = null;
4362 mPendingUidChanges.clear();
4363 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4364 "*** Delivering " + N + " uid changes");
4367 int i = mUidObservers.beginBroadcast();
4370 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4371 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4373 mUidObservers.finishBroadcast();
4375 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4376 for (int j = 0; j < N; ++j) {
4377 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4378 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4379 mValidateUids.remove(item.uid);
4381 UidRecord validateUid = mValidateUids.get(item.uid);
4382 if (validateUid == null) {
4383 validateUid = new UidRecord(item.uid);
4384 mValidateUids.put(item.uid, validateUid);
4386 if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4387 validateUid.idle = true;
4388 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4389 validateUid.idle = false;
4391 validateUid.curProcState = validateUid.setProcState = item.processState;
4392 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4397 synchronized (this) {
4398 for (int j = 0; j < N; j++) {
4399 mAvailUidChanges.add(mActiveUidChanges[j]);
4404 private void dispatchUidsChangedForObserver(IUidObserver observer,
4405 UidObserverRegistration reg, int changesSize) {
4406 if (observer == null) {
4410 for (int j = 0; j < changesSize; j++) {
4411 UidRecord.ChangeItem item = mActiveUidChanges[j];
4412 final int change = item.change;
4413 if (change == UidRecord.CHANGE_PROCSTATE &&
4414 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4415 // No-op common case: no significant change, the observer is not
4416 // interested in all proc state changes.
4419 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4420 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4421 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422 "UID idle uid=" + item.uid);
4423 observer.onUidIdle(item.uid, item.ephemeral);
4425 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4426 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4427 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4428 "UID active uid=" + item.uid);
4429 observer.onUidActive(item.uid);
4432 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4433 if ((change & UidRecord.CHANGE_CACHED) != 0) {
4434 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4435 "UID cached uid=" + item.uid);
4436 observer.onUidCachedChanged(item.uid, true);
4437 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4438 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4439 "UID active uid=" + item.uid);
4440 observer.onUidCachedChanged(item.uid, false);
4443 if ((change & UidRecord.CHANGE_GONE) != 0) {
4444 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4445 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4446 "UID gone uid=" + item.uid);
4447 observer.onUidGone(item.uid, item.ephemeral);
4449 if (reg.lastProcStates != null) {
4450 reg.lastProcStates.delete(item.uid);
4453 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4454 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4455 "UID CHANGED uid=" + item.uid
4456 + ": " + item.processState);
4457 boolean doReport = true;
4458 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4459 final int lastState = reg.lastProcStates.get(item.uid,
4460 ActivityManager.PROCESS_STATE_UNKNOWN);
4461 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4462 final boolean lastAboveCut = lastState <= reg.cutpoint;
4463 final boolean newAboveCut = item.processState <= reg.cutpoint;
4464 doReport = lastAboveCut != newAboveCut;
4466 doReport = item.processState
4467 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4471 if (reg.lastProcStates != null) {
4472 reg.lastProcStates.put(item.uid, item.processState);
4474 observer.onUidStateChanged(item.uid, item.processState,
4480 } catch (RemoteException e) {
4484 void dispatchOomAdjObserver(String msg) {
4485 OomAdjObserver observer;
4486 synchronized (this) {
4487 observer = mCurOomAdjObserver;
4490 if (observer != null) {
4491 observer.onOomAdjMessage(msg);
4495 void setOomAdjObserver(int uid, OomAdjObserver observer) {
4496 synchronized (this) {
4497 mCurOomAdjUid = uid;
4498 mCurOomAdjObserver = observer;
4502 void clearOomAdjObserver() {
4503 synchronized (this) {
4505 mCurOomAdjObserver = null;
4509 void reportOomAdjMessageLocked(String tag, String msg) {
4511 if (mCurOomAdjObserver != null) {
4512 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4517 public final int startActivity(IApplicationThread caller, String callingPackage,
4518 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4519 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4520 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4521 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4522 UserHandle.getCallingUserId());
4526 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4527 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4528 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4529 enforceNotIsolatedCaller("startActivity");
4530 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4531 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4532 // TODO: Switch to user app stacks here.
4533 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4534 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4535 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4539 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4540 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4541 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4544 // This is very dangerous -- it allows you to perform a start activity (including
4545 // permission grants) as any app that may launch one of your own activities. So
4546 // we will only allow this to be done from activities that are part of the core framework,
4547 // and then only when they are running as the system.
4548 final ActivityRecord sourceRecord;
4549 final int targetUid;
4550 final String targetPackage;
4551 synchronized (this) {
4552 if (resultTo == null) {
4553 throw new SecurityException("Must be called from an activity");
4555 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4556 if (sourceRecord == null) {
4557 throw new SecurityException("Called with bad activity token: " + resultTo);
4559 if (!sourceRecord.info.packageName.equals("android")) {
4560 throw new SecurityException(
4561 "Must be called from an activity that is declared in the android package");
4563 if (sourceRecord.app == null) {
4564 throw new SecurityException("Called without a process attached to activity");
4566 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4567 // This is still okay, as long as this activity is running under the
4568 // uid of the original calling activity.
4569 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4570 throw new SecurityException(
4571 "Calling activity in uid " + sourceRecord.app.uid
4572 + " must be system uid or original calling uid "
4573 + sourceRecord.launchedFromUid);
4576 if (ignoreTargetSecurity) {
4577 if (intent.getComponent() == null) {
4578 throw new SecurityException(
4579 "Component must be specified with ignoreTargetSecurity");
4581 if (intent.getSelector() != null) {
4582 throw new SecurityException(
4583 "Selector not allowed with ignoreTargetSecurity");
4586 targetUid = sourceRecord.launchedFromUid;
4587 targetPackage = sourceRecord.launchedFromPackage;
4590 if (userId == UserHandle.USER_NULL) {
4591 userId = UserHandle.getUserId(sourceRecord.app.uid);
4594 // TODO: Switch to user app stacks here.
4596 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4597 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4598 null, null, bOptions, ignoreTargetSecurity, userId, null,
4599 "startActivityAsCaller");
4601 } catch (SecurityException e) {
4602 // XXX need to figure out how to propagate to original app.
4603 // A SecurityException here is generally actually a fault of the original
4604 // calling activity (such as a fairly granting permissions), so propagate it
4607 StringBuilder msg = new StringBuilder();
4608 msg.append("While launching");
4609 msg.append(intent.toString());
4611 msg.append(e.getMessage());
4618 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4619 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4620 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4621 enforceNotIsolatedCaller("startActivityAndWait");
4622 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4623 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4624 WaitResult res = new WaitResult();
4625 // TODO: Switch to user app stacks here.
4626 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4627 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4628 bOptions, false, userId, null, "startActivityAndWait");
4633 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4634 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4635 int startFlags, Configuration config, Bundle bOptions, int userId) {
4636 enforceNotIsolatedCaller("startActivityWithConfig");
4637 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4638 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4639 // TODO: Switch to user app stacks here.
4640 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4641 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4642 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4647 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4648 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4649 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4650 throws TransactionTooLargeException {
4651 enforceNotIsolatedCaller("startActivityIntentSender");
4652 // Refuse possible leaked file descriptors
4653 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4654 throw new IllegalArgumentException("File descriptors passed in Intent");
4657 if (!(target instanceof PendingIntentRecord)) {
4658 throw new IllegalArgumentException("Bad PendingIntent object");
4661 PendingIntentRecord pir = (PendingIntentRecord)target;
4663 synchronized (this) {
4664 // If this is coming from the currently resumed activity, it is
4665 // effectively saying that app switches are allowed at this point.
4666 final ActivityStack stack = getFocusedStack();
4667 if (stack.mResumedActivity != null &&
4668 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4669 mAppSwitchesAllowedTime = 0;
4672 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4673 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4678 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4679 Intent intent, String resolvedType, IVoiceInteractionSession session,
4680 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4681 Bundle bOptions, int userId) {
4682 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4683 != PackageManager.PERMISSION_GRANTED) {
4684 String msg = "Permission Denial: startVoiceActivity() from pid="
4685 + Binder.getCallingPid()
4686 + ", uid=" + Binder.getCallingUid()
4687 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4689 throw new SecurityException(msg);
4691 if (session == null || interactor == null) {
4692 throw new NullPointerException("null session or interactor");
4694 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4695 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4696 // TODO: Switch to user app stacks here.
4697 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4698 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4699 null, bOptions, false, userId, null, "startVoiceActivity");
4703 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4704 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4705 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4706 != PackageManager.PERMISSION_GRANTED) {
4707 final String msg = "Permission Denial: startAssistantActivity() from pid="
4708 + Binder.getCallingPid()
4709 + ", uid=" + Binder.getCallingUid()
4710 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4712 throw new SecurityException(msg);
4714 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4715 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4716 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4717 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4718 userId, null, "startAssistantActivity");
4722 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4723 throws RemoteException {
4724 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4725 synchronized (this) {
4726 ActivityRecord activity = getFocusedStack().topActivity();
4727 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4728 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4730 if (mRunningVoice != null || activity.getTask().voiceSession != null
4731 || activity.voiceSession != null) {
4732 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4735 if (activity.pendingVoiceInteractionStart) {
4736 Slog.w(TAG, "Pending start of voice interaction already.");
4739 activity.pendingVoiceInteractionStart = true;
4741 LocalServices.getService(VoiceInteractionManagerInternal.class)
4742 .startLocalVoiceInteraction(callingActivity, options);
4746 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4747 LocalServices.getService(VoiceInteractionManagerInternal.class)
4748 .stopLocalVoiceInteraction(callingActivity);
4752 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4753 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4754 .supportsLocalVoiceInteraction();
4757 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4758 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4759 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4760 if (activityToCallback == null) return;
4761 activityToCallback.setVoiceSessionLocked(voiceSession);
4763 // Inform the activity
4765 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4767 long token = Binder.clearCallingIdentity();
4769 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4771 Binder.restoreCallingIdentity(token);
4773 // TODO: VI Should we cache the activity so that it's easier to find later
4774 // rather than scan through all the stacks and activities?
4775 } catch (RemoteException re) {
4776 activityToCallback.clearVoiceSessionLocked();
4777 // TODO: VI Should this terminate the voice session?
4782 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4783 synchronized (this) {
4784 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4786 mVoiceWakeLock.acquire();
4788 mVoiceWakeLock.release();
4795 public boolean startNextMatchingActivity(IBinder callingActivity,
4796 Intent intent, Bundle bOptions) {
4797 // Refuse possible leaked file descriptors
4798 if (intent != null && intent.hasFileDescriptors() == true) {
4799 throw new IllegalArgumentException("File descriptors passed in Intent");
4801 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4803 synchronized (this) {
4804 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4806 ActivityOptions.abort(options);
4809 if (r.app == null || r.app.thread == null) {
4810 // The caller is not running... d'oh!
4811 ActivityOptions.abort(options);
4814 intent = new Intent(intent);
4815 // The caller is not allowed to change the data.
4816 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4817 // And we are resetting to find the next component...
4818 intent.setComponent(null);
4820 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4822 ActivityInfo aInfo = null;
4824 List<ResolveInfo> resolves =
4825 AppGlobals.getPackageManager().queryIntentActivities(
4826 intent, r.resolvedType,
4827 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4828 UserHandle.getCallingUserId()).getList();
4830 // Look for the original activity in the list...
4831 final int N = resolves != null ? resolves.size() : 0;
4832 for (int i=0; i<N; i++) {
4833 ResolveInfo rInfo = resolves.get(i);
4834 if (rInfo.activityInfo.packageName.equals(r.packageName)
4835 && rInfo.activityInfo.name.equals(r.info.name)) {
4836 // We found the current one... the next matching is
4840 aInfo = resolves.get(i).activityInfo;
4843 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4844 + "/" + r.info.name);
4845 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4846 ? "null" : aInfo.packageName + "/" + aInfo.name));
4851 } catch (RemoteException e) {
4854 if (aInfo == null) {
4855 // Nobody who is next!
4856 ActivityOptions.abort(options);
4857 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4861 intent.setComponent(new ComponentName(
4862 aInfo.applicationInfo.packageName, aInfo.name));
4863 intent.setFlags(intent.getFlags()&~(
4864 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4865 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4866 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4867 Intent.FLAG_ACTIVITY_NEW_TASK));
4869 // Okay now we need to start the new activity, replacing the
4870 // currently running activity. This is a little tricky because
4871 // we want to start the new one as if the current one is finished,
4872 // but not finish the current one first so that there is no flicker.
4874 final boolean wasFinishing = r.finishing;
4877 // Propagate reply information over to the new activity.
4878 final ActivityRecord resultTo = r.resultTo;
4879 final String resultWho = r.resultWho;
4880 final int requestCode = r.requestCode;
4882 if (resultTo != null) {
4883 resultTo.removeResultsLocked(r, resultWho, requestCode);
4886 final long origId = Binder.clearCallingIdentity();
4887 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4888 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4889 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4890 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4891 false, false, null, null, "startNextMatchingActivity");
4892 Binder.restoreCallingIdentity(origId);
4894 r.finishing = wasFinishing;
4895 if (res != ActivityManager.START_SUCCESS) {
4903 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4904 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4905 String msg = "Permission Denial: startActivityFromRecents called without " +
4906 START_TASKS_FROM_RECENTS;
4908 throw new SecurityException(msg);
4910 final long origId = Binder.clearCallingIdentity();
4912 synchronized (this) {
4913 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4916 Binder.restoreCallingIdentity(origId);
4920 final int startActivityInPackage(int uid, String callingPackage,
4921 Intent intent, String resolvedType, IBinder resultTo,
4922 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4923 TaskRecord inTask, String reason) {
4925 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4926 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4928 // TODO: Switch to user app stacks here.
4929 return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4930 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4931 null, null, null, bOptions, false, userId, inTask, reason);
4935 public final int startActivities(IApplicationThread caller, String callingPackage,
4936 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4938 final String reason = "startActivities";
4939 enforceNotIsolatedCaller(reason);
4940 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4941 userId, false, ALLOW_FULL_ONLY, reason, null);
4942 // TODO: Switch to user app stacks here.
4943 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4944 resolvedTypes, resultTo, bOptions, userId, reason);
4948 final int startActivitiesInPackage(int uid, String callingPackage,
4949 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4950 Bundle bOptions, int userId) {
4952 final String reason = "startActivityInPackage";
4953 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4954 userId, false, ALLOW_FULL_ONLY, reason, null);
4955 // TODO: Switch to user app stacks here.
4956 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4957 resultTo, bOptions, userId, reason);
4962 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4963 synchronized (this) {
4964 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4968 r.reportFullyDrawnLocked(restoredFromBundle);
4973 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4974 synchronized (this) {
4975 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4979 final long origId = Binder.clearCallingIdentity();
4981 r.setRequestedOrientation(requestedOrientation);
4983 Binder.restoreCallingIdentity(origId);
4989 public int getRequestedOrientation(IBinder token) {
4990 synchronized (this) {
4991 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4993 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4995 return r.getRequestedOrientation();
5000 public final void requestActivityRelaunch(IBinder token) {
5001 synchronized(this) {
5002 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5006 final long origId = Binder.clearCallingIdentity();
5008 r.forceNewConfig = true;
5009 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5010 true /* preserveWindow */);
5012 Binder.restoreCallingIdentity(origId);
5018 * This is the internal entry point for handling Activity.finish().
5020 * @param token The Binder token referencing the Activity we want to finish.
5021 * @param resultCode Result code, if any, from this Activity.
5022 * @param resultData Result data (Intent), if any, from this Activity.
5023 * @param finishTask Whether to finish the task associated with this Activity.
5025 * @return Returns true if the activity successfully finished, or false if it is still running.
5028 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5030 // Refuse possible leaked file descriptors
5031 if (resultData != null && resultData.hasFileDescriptors() == true) {
5032 throw new IllegalArgumentException("File descriptors passed in Intent");
5035 synchronized(this) {
5036 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5040 // Keep track of the root activity of the task before we finish it
5041 TaskRecord tr = r.getTask();
5042 ActivityRecord rootR = tr.getRootActivity();
5043 if (rootR == null) {
5044 Slog.w(TAG, "Finishing task with all activities already finished");
5046 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5048 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5049 mStackSupervisor.isLastLockedTask(tr)) {
5050 Slog.i(TAG, "Not finishing task in lock task mode");
5051 mStackSupervisor.showLockTaskToast();
5054 if (mController != null) {
5055 // Find the first activity that is not finishing.
5056 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5058 // ask watcher if this is allowed
5059 boolean resumeOK = true;
5061 resumeOK = mController.activityResuming(next.packageName);
5062 } catch (RemoteException e) {
5064 Watchdog.getInstance().setActivityController(null);
5068 Slog.i(TAG, "Not finishing activity because controller resumed");
5073 final long origId = Binder.clearCallingIdentity();
5076 final boolean finishWithRootActivity =
5077 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5078 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5079 || (finishWithRootActivity && r == rootR)) {
5080 // If requested, remove the task that is associated to this activity only if it
5081 // was the root activity in the task. The result code and data is ignored
5082 // because we don't support returning them across task boundaries. Also, to
5083 // keep backwards compatibility we remove the task from recents when finishing
5084 // task with root activity.
5085 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5087 Slog.i(TAG, "Removing task failed to finish activity");
5090 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5091 resultData, "app-request", true);
5093 Slog.i(TAG, "Failed to finish by app-request");
5098 Binder.restoreCallingIdentity(origId);
5104 public final void finishHeavyWeightApp() {
5105 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5106 != PackageManager.PERMISSION_GRANTED) {
5107 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5108 + Binder.getCallingPid()
5109 + ", uid=" + Binder.getCallingUid()
5110 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5112 throw new SecurityException(msg);
5115 synchronized(this) {
5116 if (mHeavyWeightProcess == null) {
5120 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5121 for (int i = 0; i < activities.size(); i++) {
5122 ActivityRecord r = activities.get(i);
5123 if (!r.finishing && r.isInStackLocked()) {
5124 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5125 null, "finish-heavy", true);
5129 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5130 mHeavyWeightProcess.userId, 0));
5131 mHeavyWeightProcess = null;
5136 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5138 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5139 != PackageManager.PERMISSION_GRANTED) {
5140 String msg = "Permission Denial: crashApplication() from pid="
5141 + Binder.getCallingPid()
5142 + ", uid=" + Binder.getCallingUid()
5143 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5145 throw new SecurityException(msg);
5148 synchronized(this) {
5149 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5154 public final void finishSubActivity(IBinder token, String resultWho,
5156 synchronized(this) {
5157 final long origId = Binder.clearCallingIdentity();
5158 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5160 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5162 Binder.restoreCallingIdentity(origId);
5167 public boolean finishActivityAffinity(IBinder token) {
5168 synchronized(this) {
5169 final long origId = Binder.clearCallingIdentity();
5171 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5176 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5178 final TaskRecord task = r.getTask();
5179 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5180 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5181 mStackSupervisor.showLockTaskToast();
5184 return task.getStack().finishActivityAffinityLocked(r);
5186 Binder.restoreCallingIdentity(origId);
5192 public void finishVoiceTask(IVoiceInteractionSession session) {
5193 synchronized (this) {
5194 final long origId = Binder.clearCallingIdentity();
5196 // TODO: VI Consider treating local voice interactions and voice tasks
5198 mStackSupervisor.finishVoiceTask(session);
5200 Binder.restoreCallingIdentity(origId);
5207 public boolean releaseActivityInstance(IBinder token) {
5208 synchronized(this) {
5209 final long origId = Binder.clearCallingIdentity();
5211 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5215 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5217 Binder.restoreCallingIdentity(origId);
5223 public void releaseSomeActivities(IApplicationThread appInt) {
5224 synchronized(this) {
5225 final long origId = Binder.clearCallingIdentity();
5227 ProcessRecord app = getRecordForAppLocked(appInt);
5228 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5230 Binder.restoreCallingIdentity(origId);
5236 public boolean willActivityBeVisible(IBinder token) {
5237 synchronized(this) {
5238 ActivityStack stack = ActivityRecord.getStackLocked(token);
5239 if (stack != null) {
5240 return stack.willActivityBeVisibleLocked(token);
5247 public void overridePendingTransition(IBinder token, String packageName,
5248 int enterAnim, int exitAnim) {
5249 synchronized(this) {
5250 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5255 final long origId = Binder.clearCallingIdentity();
5257 if (self.state == ActivityState.RESUMED
5258 || self.state == ActivityState.PAUSING) {
5259 mWindowManager.overridePendingAppTransition(packageName,
5260 enterAnim, exitAnim, null);
5263 Binder.restoreCallingIdentity(origId);
5268 * Main function for removing an existing process from the activity manager
5269 * as a result of that process going away. Clears out all connections
5272 private final void handleAppDiedLocked(ProcessRecord app,
5273 boolean restarting, boolean allowRestart) {
5275 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5276 false /*replacingPid*/);
5277 if (!kept && !restarting) {
5278 removeLruProcessLocked(app);
5280 ProcessList.remove(pid);
5284 if (mProfileProc == app) {
5285 clearProfilerLocked();
5288 // Remove this application's activities from active lists.
5289 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5291 app.activities.clear();
5293 if (app.instr != null) {
5294 Slog.w(TAG, "Crash of app " + app.processName
5295 + " running instrumentation " + app.instr.mClass);
5296 Bundle info = new Bundle();
5297 info.putString("shortMsg", "Process crashed.");
5298 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5301 mWindowManager.deferSurfaceLayout();
5303 if (!restarting && hasVisibleActivities
5304 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5305 // If there was nothing to resume, and we are not already restarting this process, but
5306 // there is a visible activity that is hosted by the process... then make sure all
5307 // visible activities are running, taking care of restarting this process.
5308 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5311 mWindowManager.continueSurfaceLayout();
5315 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5316 final IBinder threadBinder = thread.asBinder();
5317 // Find the application record.
5318 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5319 final ProcessRecord rec = mLruProcesses.get(i);
5320 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5327 final ProcessRecord getRecordForAppLocked(
5328 IApplicationThread thread) {
5329 if (thread == null) {
5333 int appIndex = getLRURecordIndexForAppLocked(thread);
5334 if (appIndex >= 0) {
5335 return mLruProcesses.get(appIndex);
5338 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5339 // double-check that.
5340 final IBinder threadBinder = thread.asBinder();
5341 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5342 for (int i = pmap.size()-1; i >= 0; i--) {
5343 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5344 for (int j = procs.size()-1; j >= 0; j--) {
5345 final ProcessRecord proc = procs.valueAt(j);
5346 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5347 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5357 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5358 // If there are no longer any background processes running,
5359 // and the app that died was not running instrumentation,
5360 // then tell everyone we are now low on memory.
5361 boolean haveBg = false;
5362 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5363 ProcessRecord rec = mLruProcesses.get(i);
5364 if (rec.thread != null
5365 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5372 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5374 long now = SystemClock.uptimeMillis();
5375 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5378 mLastMemUsageReportTime = now;
5381 final ArrayList<ProcessMemInfo> memInfos
5382 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5383 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5384 long now = SystemClock.uptimeMillis();
5385 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5386 ProcessRecord rec = mLruProcesses.get(i);
5387 if (rec == dyingProc || rec.thread == null) {
5391 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5392 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5394 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5395 // The low memory report is overriding any current
5396 // state for a GC request. Make sure to do
5397 // heavy/important/visible/foreground processes first.
5398 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5399 rec.lastRequestedGc = 0;
5401 rec.lastRequestedGc = rec.lastLowMemory;
5403 rec.reportLowMemory = true;
5404 rec.lastLowMemory = now;
5405 mProcessesToGc.remove(rec);
5406 addProcessToGcListLocked(rec);
5410 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5411 mHandler.sendMessage(msg);
5413 scheduleAppGcsLocked();
5417 final void appDiedLocked(ProcessRecord app) {
5418 appDiedLocked(app, app.pid, app.thread, false);
5421 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5422 boolean fromBinderDied) {
5423 // First check if this ProcessRecord is actually active for the pid.
5424 synchronized (mPidsSelfLocked) {
5425 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5426 if (curProc != app) {
5427 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5432 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5433 synchronized (stats) {
5434 stats.noteProcessDiedLocked(app.info.uid, pid);
5438 if (!fromBinderDied) {
5439 killProcessQuiet(pid);
5441 killProcessGroup(app.uid, pid);
5445 // Clean up already done if the process has been re-started.
5446 if (app.pid == pid && app.thread != null &&
5447 app.thread.asBinder() == thread.asBinder()) {
5448 boolean doLowMem = app.instr == null;
5449 boolean doOomAdj = doLowMem;
5450 if (!app.killedByAm) {
5451 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5452 + ProcessList.makeOomAdjString(app.setAdj)
5453 + ProcessList.makeProcStateString(app.setProcState));
5454 mAllowLowerMemLevel = true;
5456 // Note that we always want to do oom adj to update our state with the
5457 // new number of procs.
5458 mAllowLowerMemLevel = false;
5461 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5462 app.setAdj, app.setProcState);
5463 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5464 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5465 handleAppDiedLocked(app, false, true);
5468 updateOomAdjLocked();
5471 doLowMemReportIfNeededLocked(app);
5473 } else if (app.pid != pid) {
5474 // A new process has already been started.
5475 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5476 + ") has died and restarted (pid " + app.pid + ").");
5477 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5478 } else if (DEBUG_PROCESSES) {
5479 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5480 + thread.asBinder());
5485 * If a stack trace dump file is configured, dump process stack traces.
5486 * @param clearTraces causes the dump file to be erased prior to the new
5487 * traces being written, if true; when false, the new traces will be
5488 * appended to any existing file content.
5489 * @param firstPids of dalvik VM processes to dump stack traces for first
5490 * @param lastPids of dalvik VM processes to dump stack traces for last
5491 * @param nativePids optional list of native pids to dump stack crawls
5493 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5494 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5495 ArrayList<Integer> nativePids) {
5496 ArrayList<Integer> extraPids = null;
5498 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5499 // of the top users at the time of the request.
5500 if (processCpuTracker != null) {
5501 processCpuTracker.init();
5504 } catch (InterruptedException ignored) {
5507 processCpuTracker.update();
5509 // We'll take the stack crawls of just the top apps using CPU.
5510 final int N = processCpuTracker.countWorkingStats();
5511 extraPids = new ArrayList<>();
5512 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5513 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5514 if (lastPids.indexOfKey(stats.pid) >= 0) {
5515 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5517 extraPids.add(stats.pid);
5518 } else if (DEBUG_ANR) {
5519 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5525 boolean useTombstonedForJavaTraces = false;
5528 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5529 if (tracesDirProp.isEmpty()) {
5530 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5531 // dumping scheme. All traces are written to a global trace file (usually
5532 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5533 // the file if requested.
5535 // This mode of operation will be removed in the near future.
5538 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5539 if (globalTracesPath.isEmpty()) {
5540 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5544 tracesFile = new File(globalTracesPath);
5546 if (clearTraces && tracesFile.exists()) {
5547 tracesFile.delete();
5550 tracesFile.createNewFile();
5551 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5552 } catch (IOException e) {
5553 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5557 File tracesDir = new File(tracesDirProp);
5558 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5559 // Each set of ANR traces is written to a separate file and dumpstate will process
5560 // all such files and add them to a captured bug report if they're recent enough.
5561 maybePruneOldTraces(tracesDir);
5563 // NOTE: We should consider creating the file in native code atomically once we've
5564 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5566 tracesFile = createAnrDumpFile(tracesDir);
5567 if (tracesFile == null) {
5571 useTombstonedForJavaTraces = true;
5574 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5575 useTombstonedForJavaTraces);
5579 @GuardedBy("ActivityManagerService.class")
5580 private static SimpleDateFormat sAnrFileDateFormat;
5582 private static synchronized File createAnrDumpFile(File tracesDir) {
5583 if (sAnrFileDateFormat == null) {
5584 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5587 final String formattedDate = sAnrFileDateFormat.format(new Date());
5588 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5591 if (anrFile.createNewFile()) {
5592 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5595 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5597 } catch (IOException ioe) {
5598 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5605 * Prune all trace files that are more than a day old.
5607 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5608 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5609 * since it's the system_server that creates trace files for most ANRs.
5611 private static void maybePruneOldTraces(File tracesDir) {
5612 final long now = System.currentTimeMillis();
5613 final File[] traceFiles = tracesDir.listFiles();
5615 if (traceFiles != null) {
5616 for (File file : traceFiles) {
5617 if ((now - file.lastModified()) > DAY_IN_MILLIS) {
5618 if (!file.delete()) {
5619 Slog.w(TAG, "Unable to prune stale trace file: " + file);
5627 * Legacy code, do not use. Existing users will be deleted.
5632 public static class DumpStackFileObserver extends FileObserver {
5633 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5634 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5636 private final String mTracesPath;
5637 private boolean mClosed;
5639 public DumpStackFileObserver(String tracesPath) {
5640 super(tracesPath, FileObserver.CLOSE_WRITE);
5641 mTracesPath = tracesPath;
5645 public synchronized void onEvent(int event, String path) {
5650 public long dumpWithTimeout(int pid, long timeout) {
5651 sendSignal(pid, SIGNAL_QUIT);
5652 final long start = SystemClock.elapsedRealtime();
5654 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5655 synchronized (this) {
5657 wait(waitTime); // Wait for traces file to be closed.
5658 } catch (InterruptedException e) {
5663 // This avoids a corner case of passing a negative time to the native
5664 // trace in case we've already hit the overall timeout.
5665 final long timeWaited = SystemClock.elapsedRealtime() - start;
5666 if (timeWaited >= timeout) {
5671 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5672 ". Attempting native stack collection.");
5674 final long nativeDumpTimeoutMs = Math.min(
5675 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5677 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5678 (int) (nativeDumpTimeoutMs / 1000));
5681 final long end = SystemClock.elapsedRealtime();
5684 return (end - start);
5689 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5690 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5691 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5692 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5695 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5696 final long timeStart = SystemClock.elapsedRealtime();
5697 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5698 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5699 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5702 return SystemClock.elapsedRealtime() - timeStart;
5705 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5706 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5707 boolean useTombstonedForJavaTraces) {
5709 // We don't need any sort of inotify based monitoring when we're dumping traces via
5710 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5711 // control of all writes to the file in question.
5712 final DumpStackFileObserver observer;
5713 if (useTombstonedForJavaTraces) {
5716 // Use a FileObserver to detect when traces finish writing.
5717 // The order of traces is considered important to maintain for legibility.
5718 observer = new DumpStackFileObserver(tracesFile);
5721 // We must complete all stack dumps within 20 seconds.
5722 long remainingTime = 20 * 1000;
5724 if (observer != null) {
5725 observer.startWatching();
5728 // First collect all of the stacks of the most important pids.
5729 if (firstPids != null) {
5730 int num = firstPids.size();
5731 for (int i = 0; i < num; i++) {
5732 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5733 + firstPids.get(i));
5734 final long timeTaken;
5735 if (useTombstonedForJavaTraces) {
5736 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5738 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5741 remainingTime -= timeTaken;
5742 if (remainingTime <= 0) {
5743 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5744 "); deadline exceeded.");
5749 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5754 // Next collect the stacks of the native pids
5755 if (nativePids != null) {
5756 for (int pid : nativePids) {
5757 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5758 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5760 final long start = SystemClock.elapsedRealtime();
5761 Debug.dumpNativeBacktraceToFileTimeout(
5762 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5763 final long timeTaken = SystemClock.elapsedRealtime() - start;
5765 remainingTime -= timeTaken;
5766 if (remainingTime <= 0) {
5767 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5768 "); deadline exceeded.");
5773 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5778 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5779 if (extraPids != null) {
5780 for (int pid : extraPids) {
5781 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5783 final long timeTaken;
5784 if (useTombstonedForJavaTraces) {
5785 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5787 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5790 remainingTime -= timeTaken;
5791 if (remainingTime <= 0) {
5792 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5793 "); deadline exceeded.");
5798 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5803 if (observer != null) {
5804 observer.stopWatching();
5809 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5810 if (true || Build.IS_USER) {
5813 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5814 if (tracesPath == null || tracesPath.length() == 0) {
5818 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5819 StrictMode.allowThreadDiskWrites();
5821 final File tracesFile = new File(tracesPath);
5822 final File tracesDir = tracesFile.getParentFile();
5823 final File tracesTmp = new File(tracesDir, "__tmp__");
5825 if (tracesFile.exists()) {
5827 tracesFile.renameTo(tracesTmp);
5829 StringBuilder sb = new StringBuilder();
5830 Time tobj = new Time();
5831 tobj.set(System.currentTimeMillis());
5832 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5834 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5835 sb.append(" since ");
5837 FileOutputStream fos = new FileOutputStream(tracesFile);
5838 fos.write(sb.toString().getBytes());
5840 fos.write("\n*** No application process!".getBytes());
5843 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5844 } catch (IOException e) {
5845 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5850 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5851 firstPids.add(app.pid);
5852 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5855 File lastTracesFile = null;
5856 File curTracesFile = null;
5857 for (int i=9; i>=0; i--) {
5858 String name = String.format(Locale.US, "slow%02d.txt", i);
5859 curTracesFile = new File(tracesDir, name);
5860 if (curTracesFile.exists()) {
5861 if (lastTracesFile != null) {
5862 curTracesFile.renameTo(lastTracesFile);
5864 curTracesFile.delete();
5867 lastTracesFile = curTracesFile;
5869 tracesFile.renameTo(curTracesFile);
5870 if (tracesTmp.exists()) {
5871 tracesTmp.renameTo(tracesFile);
5874 StrictMode.setThreadPolicy(oldPolicy);
5878 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5879 if (!mLaunchWarningShown) {
5880 mLaunchWarningShown = true;
5881 mUiHandler.post(new Runnable() {
5884 synchronized (ActivityManagerService.this) {
5885 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5887 mUiHandler.postDelayed(new Runnable() {
5890 synchronized (ActivityManagerService.this) {
5892 mLaunchWarningShown = false;
5903 public boolean clearApplicationUserData(final String packageName,
5904 final IPackageDataObserver observer, int userId) {
5905 enforceNotIsolatedCaller("clearApplicationUserData");
5906 int uid = Binder.getCallingUid();
5907 int pid = Binder.getCallingPid();
5908 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5909 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5911 final ApplicationInfo appInfo;
5912 final boolean isInstantApp;
5914 long callingId = Binder.clearCallingIdentity();
5916 IPackageManager pm = AppGlobals.getPackageManager();
5917 synchronized(this) {
5918 // Instant packages are not protected
5919 if (getPackageManagerInternalLocked().isPackageDataProtected(
5920 resolvedUserId, packageName)) {
5921 throw new SecurityException(
5922 "Cannot clear data for a protected package: " + packageName);
5925 ApplicationInfo applicationInfo = null;
5927 applicationInfo = pm.getApplicationInfo(packageName,
5928 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5929 } catch (RemoteException e) {
5932 appInfo = applicationInfo;
5934 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5936 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5937 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5938 throw new SecurityException("PID " + pid + " does not have permission "
5939 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5940 + " of package " + packageName);
5943 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5944 .hasInstantApplicationMetadata(packageName, resolvedUserId);
5945 final boolean isUninstalledAppWithoutInstantMetadata =
5946 (appInfo == null && !hasInstantMetadata);
5947 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5948 || hasInstantMetadata;
5949 final boolean canAccessInstantApps = checkComponentPermission(
5950 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5951 == PackageManager.PERMISSION_GRANTED;
5953 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5954 && !canAccessInstantApps)) {
5955 Slog.w(TAG, "Invalid packageName: " + packageName);
5956 if (observer != null) {
5958 observer.onRemoveCompleted(packageName, false);
5959 } catch (RemoteException e) {
5960 Slog.i(TAG, "Observer no longer exists.");
5966 if (appInfo != null) {
5967 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5968 // Remove all tasks match the cleared application package and user
5969 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5970 final TaskRecord tr = mRecentTasks.get(i);
5971 final String taskPackageName =
5972 tr.getBaseIntent().getComponent().getPackageName();
5973 if (tr.userId != resolvedUserId) continue;
5974 if (!taskPackageName.equals(packageName)) continue;
5975 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5976 REMOVE_FROM_RECENTS);
5981 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5983 public void onRemoveCompleted(String packageName, boolean succeeded)
5984 throws RemoteException {
5985 if (appInfo != null) {
5986 synchronized (ActivityManagerService.this) {
5987 finishForceStopPackageLocked(packageName, appInfo.uid);
5990 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5991 Uri.fromParts("package", packageName, null));
5992 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5993 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5994 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5996 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5997 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5998 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6001 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6002 null, null, null, null, false, false, resolvedUserId);
6005 if (observer != null) {
6006 observer.onRemoveCompleted(packageName, succeeded);
6012 // Clear application user data
6013 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6015 if (appInfo != null) {
6016 synchronized (this) {
6017 // Remove all permissions granted from/to this package
6018 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6021 // Reset notification settings.
6022 INotificationManager inm = NotificationManager.getService();
6023 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6025 } catch (RemoteException e) {
6028 Binder.restoreCallingIdentity(callingId);
6034 public void killBackgroundProcesses(final String packageName, int userId) {
6035 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6036 != PackageManager.PERMISSION_GRANTED &&
6037 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6038 != PackageManager.PERMISSION_GRANTED) {
6039 String msg = "Permission Denial: killBackgroundProcesses() from pid="
6040 + Binder.getCallingPid()
6041 + ", uid=" + Binder.getCallingUid()
6042 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6044 throw new SecurityException(msg);
6047 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6048 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6049 long callingId = Binder.clearCallingIdentity();
6051 IPackageManager pm = AppGlobals.getPackageManager();
6052 synchronized(this) {
6055 appId = UserHandle.getAppId(
6056 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6057 } catch (RemoteException e) {
6060 Slog.w(TAG, "Invalid packageName: " + packageName);
6063 killPackageProcessesLocked(packageName, appId, userId,
6064 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6067 Binder.restoreCallingIdentity(callingId);
6072 public void killAllBackgroundProcesses() {
6073 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6074 != PackageManager.PERMISSION_GRANTED) {
6075 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6076 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6077 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6079 throw new SecurityException(msg);
6082 final long callingId = Binder.clearCallingIdentity();
6084 synchronized (this) {
6085 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6086 final int NP = mProcessNames.getMap().size();
6087 for (int ip = 0; ip < NP; ip++) {
6088 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6089 final int NA = apps.size();
6090 for (int ia = 0; ia < NA; ia++) {
6091 final ProcessRecord app = apps.valueAt(ia);
6092 if (app.persistent) {
6093 // We don't kill persistent processes.
6098 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6105 final int N = procs.size();
6106 for (int i = 0; i < N; i++) {
6107 removeProcessLocked(procs.get(i), false, true, "kill all background");
6110 mAllowLowerMemLevel = true;
6112 updateOomAdjLocked();
6113 doLowMemReportIfNeededLocked(null);
6116 Binder.restoreCallingIdentity(callingId);
6121 * Kills all background processes, except those matching any of the
6122 * specified properties.
6124 * @param minTargetSdk the target SDK version at or above which to preserve
6125 * processes, or {@code -1} to ignore the target SDK
6126 * @param maxProcState the process state at or below which to preserve
6127 * processes, or {@code -1} to ignore the process state
6129 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6130 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6131 != PackageManager.PERMISSION_GRANTED) {
6132 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6133 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6134 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6136 throw new SecurityException(msg);
6139 final long callingId = Binder.clearCallingIdentity();
6141 synchronized (this) {
6142 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6143 final int NP = mProcessNames.getMap().size();
6144 for (int ip = 0; ip < NP; ip++) {
6145 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6146 final int NA = apps.size();
6147 for (int ia = 0; ia < NA; ia++) {
6148 final ProcessRecord app = apps.valueAt(ia);
6151 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6152 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6159 final int N = procs.size();
6160 for (int i = 0; i < N; i++) {
6161 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6165 Binder.restoreCallingIdentity(callingId);
6170 public void forceStopPackage(final String packageName, int userId) {
6171 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6172 != PackageManager.PERMISSION_GRANTED) {
6173 String msg = "Permission Denial: forceStopPackage() from pid="
6174 + Binder.getCallingPid()
6175 + ", uid=" + Binder.getCallingUid()
6176 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6178 throw new SecurityException(msg);
6180 final int callingPid = Binder.getCallingPid();
6181 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6182 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6183 long callingId = Binder.clearCallingIdentity();
6185 IPackageManager pm = AppGlobals.getPackageManager();
6186 synchronized(this) {
6187 int[] users = userId == UserHandle.USER_ALL
6188 ? mUserController.getUsers() : new int[] { userId };
6189 for (int user : users) {
6192 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6194 } catch (RemoteException e) {
6197 Slog.w(TAG, "Invalid packageName: " + packageName);
6201 pm.setPackageStoppedState(packageName, true, user);
6202 } catch (RemoteException e) {
6203 } catch (IllegalArgumentException e) {
6204 Slog.w(TAG, "Failed trying to unstop package "
6205 + packageName + ": " + e);
6207 if (mUserController.isUserRunningLocked(user, 0)) {
6208 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6209 finishForceStopPackageLocked(packageName, pkgUid);
6214 Binder.restoreCallingIdentity(callingId);
6219 public void addPackageDependency(String packageName) {
6220 synchronized (this) {
6221 int callingPid = Binder.getCallingPid();
6222 if (callingPid == myPid()) {
6227 synchronized (mPidsSelfLocked) {
6228 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6231 if (proc.pkgDeps == null) {
6232 proc.pkgDeps = new ArraySet<String>(1);
6234 proc.pkgDeps.add(packageName);
6240 * The pkg name and app id have to be specified.
6243 public void killApplication(String pkg, int appId, int userId, String reason) {
6247 // Make sure the uid is valid.
6249 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6252 int callerUid = Binder.getCallingUid();
6253 // Only the system server can kill an application
6254 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6255 // Post an aysnc message to kill the application
6256 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6259 Bundle bundle = new Bundle();
6260 bundle.putString("pkg", pkg);
6261 bundle.putString("reason", reason);
6263 mHandler.sendMessage(msg);
6265 throw new SecurityException(callerUid + " cannot kill pkg: " +
6271 public void closeSystemDialogs(String reason) {
6272 enforceNotIsolatedCaller("closeSystemDialogs");
6274 final int pid = Binder.getCallingPid();
6275 final int uid = Binder.getCallingUid();
6276 final long origId = Binder.clearCallingIdentity();
6278 synchronized (this) {
6279 // Only allow this from foreground processes, so that background
6280 // applications can't abuse it to prevent system UI from being shown.
6281 if (uid >= FIRST_APPLICATION_UID) {
6283 synchronized (mPidsSelfLocked) {
6284 proc = mPidsSelfLocked.get(pid);
6286 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6287 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6288 + " from background process " + proc);
6292 closeSystemDialogsLocked(reason);
6295 Binder.restoreCallingIdentity(origId);
6299 void closeSystemDialogsLocked(String reason) {
6300 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6301 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6302 | Intent.FLAG_RECEIVER_FOREGROUND);
6303 if (reason != null) {
6304 intent.putExtra("reason", reason);
6306 mWindowManager.closeSystemDialogs(reason);
6308 mStackSupervisor.closeSystemDialogsLocked();
6310 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6311 AppOpsManager.OP_NONE, null, false, false,
6312 -1, SYSTEM_UID, UserHandle.USER_ALL);
6316 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6317 enforceNotIsolatedCaller("getProcessMemoryInfo");
6318 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6319 for (int i=pids.length-1; i>=0; i--) {
6322 synchronized (this) {
6323 synchronized (mPidsSelfLocked) {
6324 proc = mPidsSelfLocked.get(pids[i]);
6325 oomAdj = proc != null ? proc.setAdj : 0;
6328 infos[i] = new Debug.MemoryInfo();
6329 Debug.getMemoryInfo(pids[i], infos[i]);
6331 synchronized (this) {
6332 if (proc.thread != null && proc.setAdj == oomAdj) {
6333 // Record this for posterity if the process has been stable.
6334 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6335 infos[i].getTotalUss(), false, proc.pkgList);
6344 public long[] getProcessPss(int[] pids) {
6345 enforceNotIsolatedCaller("getProcessPss");
6346 long[] pss = new long[pids.length];
6347 for (int i=pids.length-1; i>=0; i--) {
6350 synchronized (this) {
6351 synchronized (mPidsSelfLocked) {
6352 proc = mPidsSelfLocked.get(pids[i]);
6353 oomAdj = proc != null ? proc.setAdj : 0;
6356 long[] tmpUss = new long[1];
6357 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6359 synchronized (this) {
6360 if (proc.thread != null && proc.setAdj == oomAdj) {
6361 // Record this for posterity if the process has been stable.
6362 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6371 public void killApplicationProcess(String processName, int uid) {
6372 if (processName == null) {
6376 int callerUid = Binder.getCallingUid();
6377 // Only the system server can kill an application
6378 if (callerUid == SYSTEM_UID) {
6379 synchronized (this) {
6380 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6381 if (app != null && app.thread != null) {
6383 app.thread.scheduleSuicide();
6384 } catch (RemoteException e) {
6385 // If the other end already died, then our work here is done.
6388 Slog.w(TAG, "Process/uid not found attempting kill of "
6389 + processName + " / " + uid);
6393 throw new SecurityException(callerUid + " cannot kill app process: " +
6398 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6399 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6400 false, true, false, false, UserHandle.getUserId(uid), reason);
6403 private void finishForceStopPackageLocked(final String packageName, int uid) {
6404 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6405 Uri.fromParts("package", packageName, null));
6406 if (!mProcessesReady) {
6407 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6408 | Intent.FLAG_RECEIVER_FOREGROUND);
6410 intent.putExtra(Intent.EXTRA_UID, uid);
6411 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6412 broadcastIntentLocked(null, null, intent,
6413 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6414 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6418 private final boolean killPackageProcessesLocked(String packageName, int appId,
6419 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6420 boolean doit, boolean evenPersistent, String reason) {
6421 ArrayList<ProcessRecord> procs = new ArrayList<>();
6423 // Remove all processes this package may have touched: all with the
6424 // same UID (except for the system or root user), and all whose name
6425 // matches the package name.
6426 final int NP = mProcessNames.getMap().size();
6427 for (int ip=0; ip<NP; ip++) {
6428 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6429 final int NA = apps.size();
6430 for (int ia=0; ia<NA; ia++) {
6431 ProcessRecord app = apps.valueAt(ia);
6432 if (app.persistent && !evenPersistent) {
6433 // we don't kill persistent processes
6443 // Skip process if it doesn't meet our oom adj requirement.
6444 if (app.setAdj < minOomAdj) {
6448 // If no package is specified, we call all processes under the
6450 if (packageName == null) {
6451 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6454 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6457 // Package has been specified, we want to hit all processes
6458 // that match it. We need to qualify this by the processes
6459 // that are running under the specified app and user ID.
6461 final boolean isDep = app.pkgDeps != null
6462 && app.pkgDeps.contains(packageName);
6463 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6466 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6469 if (!app.pkgList.containsKey(packageName) && !isDep) {
6474 // Process has passed all conditions, kill it!
6483 int N = procs.size();
6484 for (int i=0; i<N; i++) {
6485 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6487 updateOomAdjLocked();
6491 private void cleanupDisabledPackageComponentsLocked(
6492 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6494 Set<String> disabledClasses = null;
6495 boolean packageDisabled = false;
6496 IPackageManager pm = AppGlobals.getPackageManager();
6498 if (changedClasses == null) {
6499 // Nothing changed...
6503 // Determine enable/disable state of the package and its components.
6504 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6505 for (int i = changedClasses.length - 1; i >= 0; i--) {
6506 final String changedClass = changedClasses[i];
6508 if (changedClass.equals(packageName)) {
6510 // Entire package setting changed
6511 enabled = pm.getApplicationEnabledSetting(packageName,
6512 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6513 } catch (Exception e) {
6514 // No such package/component; probably racing with uninstall. In any
6515 // event it means we have nothing further to do here.
6518 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6519 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6520 if (packageDisabled) {
6521 // Entire package is disabled.
6522 // No need to continue to check component states.
6523 disabledClasses = null;
6528 enabled = pm.getComponentEnabledSetting(
6529 new ComponentName(packageName, changedClass),
6530 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6531 } catch (Exception e) {
6532 // As above, probably racing with uninstall.
6535 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6536 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6537 if (disabledClasses == null) {
6538 disabledClasses = new ArraySet<>(changedClasses.length);
6540 disabledClasses.add(changedClass);
6545 if (!packageDisabled && disabledClasses == null) {
6546 // Nothing to do here...
6550 // Clean-up disabled activities.
6551 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6552 packageName, disabledClasses, true, false, userId) && mBooted) {
6553 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6554 mStackSupervisor.scheduleIdleLocked();
6557 // Clean-up disabled tasks
6558 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6560 // Clean-up disabled services.
6561 mServices.bringDownDisabledPackageServicesLocked(
6562 packageName, disabledClasses, userId, false, killProcess, true);
6564 // Clean-up disabled providers.
6565 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6566 mProviderMap.collectPackageProvidersLocked(
6567 packageName, disabledClasses, true, false, userId, providers);
6568 for (int i = providers.size() - 1; i >= 0; i--) {
6569 removeDyingProviderLocked(null, providers.get(i), true);
6572 // Clean-up disabled broadcast receivers.
6573 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6574 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6575 packageName, disabledClasses, userId, true);
6580 final boolean clearBroadcastQueueForUserLocked(int userId) {
6581 boolean didSomething = false;
6582 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6583 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6584 null, null, userId, true);
6586 return didSomething;
6589 final boolean forceStopPackageLocked(String packageName, int appId,
6590 boolean callerWillRestart, boolean purgeCache, boolean doit,
6591 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6594 if (userId == UserHandle.USER_ALL && packageName == null) {
6595 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6598 if (appId < 0 && packageName != null) {
6600 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6601 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6602 } catch (RemoteException e) {
6607 if (packageName != null) {
6608 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6609 + " user=" + userId + ": " + reason);
6611 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6614 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6617 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6618 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6619 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6621 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6623 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6624 packageName, null, doit, evenPersistent, userId)) {
6628 didSomething = true;
6631 if (mServices.bringDownDisabledPackageServicesLocked(
6632 packageName, null, userId, evenPersistent, true, doit)) {
6636 didSomething = true;
6639 if (packageName == null) {
6640 // Remove all sticky broadcasts from this user.
6641 mStickyBroadcasts.remove(userId);
6644 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6645 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6646 userId, providers)) {
6650 didSomething = true;
6652 for (i = providers.size() - 1; i >= 0; i--) {
6653 removeDyingProviderLocked(null, providers.get(i), true);
6656 // Remove transient permissions granted from/to this package/user
6657 removeUriPermissionsForPackageLocked(packageName, userId, false);
6660 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6661 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6662 packageName, null, userId, doit);
6666 if (packageName == null || uninstalling) {
6667 // Remove pending intents. For now we only do this when force
6668 // stopping users, because we have some problems when doing this
6669 // for packages -- app widgets are not currently cleaned up for
6670 // such packages, so they can be left with bad pending intents.
6671 if (mIntentSenderRecords.size() > 0) {
6672 Iterator<WeakReference<PendingIntentRecord>> it
6673 = mIntentSenderRecords.values().iterator();
6674 while (it.hasNext()) {
6675 WeakReference<PendingIntentRecord> wpir = it.next();
6680 PendingIntentRecord pir = wpir.get();
6685 if (packageName == null) {
6686 // Stopping user, remove all objects for the user.
6687 if (pir.key.userId != userId) {
6688 // Not the same user, skip it.
6692 if (UserHandle.getAppId(pir.uid) != appId) {
6693 // Different app id, skip it.
6696 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6697 // Different user, skip it.
6700 if (!pir.key.packageName.equals(packageName)) {
6701 // Different package, skip it.
6708 didSomething = true;
6710 makeIntentSenderCanceledLocked(pir);
6711 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6712 pir.key.activity.pendingResults.remove(pir.ref);
6719 if (purgeCache && packageName != null) {
6720 AttributeCache ac = AttributeCache.instance();
6722 ac.removePackage(packageName);
6726 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6727 mStackSupervisor.scheduleIdleLocked();
6731 return didSomething;
6734 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6735 return removeProcessNameLocked(name, uid, null);
6738 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6739 final ProcessRecord expecting) {
6740 ProcessRecord old = mProcessNames.get(name, uid);
6741 // Only actually remove when the currently recorded value matches the
6742 // record that we expected; if it doesn't match then we raced with a
6743 // newly created process and we don't want to destroy the new one.
6744 if ((expecting == null) || (old == expecting)) {
6745 mProcessNames.remove(name, uid);
6747 if (old != null && old.uidRecord != null) {
6748 old.uidRecord.numProcs--;
6749 if (old.uidRecord.numProcs == 0) {
6750 // No more processes using this uid, tell clients it is gone.
6751 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6752 "No more processes in " + old.uidRecord);
6753 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6754 EventLogTags.writeAmUidStopped(uid);
6755 mActiveUids.remove(uid);
6756 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6758 old.uidRecord = null;
6760 mIsolatedProcesses.remove(uid);
6764 private final void addProcessNameLocked(ProcessRecord proc) {
6765 // We shouldn't already have a process under this name, but just in case we
6766 // need to clean up whatever may be there now.
6767 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6768 if (old == proc && proc.persistent) {
6769 // We are re-adding a persistent process. Whatevs! Just leave it there.
6770 Slog.w(TAG, "Re-adding persistent process " + proc);
6771 } else if (old != null) {
6772 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6774 UidRecord uidRec = mActiveUids.get(proc.uid);
6775 if (uidRec == null) {
6776 uidRec = new UidRecord(proc.uid);
6777 // This is the first appearance of the uid, report it now!
6778 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6779 "Creating new process uid: " + uidRec);
6780 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6781 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6782 uidRec.setWhitelist = uidRec.curWhitelist = true;
6784 uidRec.updateHasInternetPermission();
6785 mActiveUids.put(proc.uid, uidRec);
6786 EventLogTags.writeAmUidRunning(uidRec.uid);
6787 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6789 proc.uidRecord = uidRec;
6791 // Reset render thread tid if it was already set, so new process can set it again.
6792 proc.renderThreadTid = 0;
6794 mProcessNames.put(proc.processName, proc.uid, proc);
6795 if (proc.isolated) {
6796 mIsolatedProcesses.put(proc.uid, proc);
6800 boolean removeProcessLocked(ProcessRecord app,
6801 boolean callerWillRestart, boolean allowRestart, String reason) {
6802 final String name = app.processName;
6803 final int uid = app.uid;
6804 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6805 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6807 ProcessRecord old = mProcessNames.get(name, uid);
6809 // This process is no longer active, so nothing to do.
6810 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6813 removeProcessNameLocked(name, uid);
6814 if (mHeavyWeightProcess == app) {
6815 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6816 mHeavyWeightProcess.userId, 0));
6817 mHeavyWeightProcess = null;
6819 boolean needRestart = false;
6820 if (app.pid > 0 && app.pid != MY_PID) {
6822 synchronized (mPidsSelfLocked) {
6823 mPidsSelfLocked.remove(pid);
6824 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6826 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6827 boolean willRestart = false;
6828 if (app.persistent && !app.isolated) {
6829 if (!callerWillRestart) {
6835 app.kill(reason, true);
6837 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6838 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6840 handleAppDiedLocked(app, willRestart, allowRestart);
6842 removeLruProcessLocked(app);
6843 addAppLocked(app.info, null, false, null /* ABI override */);
6846 mRemovedProcesses.add(app);
6852 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6853 cleanupAppInLaunchingProvidersLocked(app, true);
6854 removeProcessLocked(app, false, true, "timeout publishing content providers");
6857 private final void processStartTimedOutLocked(ProcessRecord app) {
6858 final int pid = app.pid;
6859 boolean gone = false;
6860 synchronized (mPidsSelfLocked) {
6861 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6862 if (knownApp != null && knownApp.thread == null) {
6863 mPidsSelfLocked.remove(pid);
6869 Slog.w(TAG, "Process " + app + " failed to attach");
6870 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6871 pid, app.uid, app.processName);
6872 removeProcessNameLocked(app.processName, app.uid);
6873 if (mHeavyWeightProcess == app) {
6874 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6875 mHeavyWeightProcess.userId, 0));
6876 mHeavyWeightProcess = null;
6878 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6879 // Take care of any launching providers waiting for this process.
6880 cleanupAppInLaunchingProvidersLocked(app, true);
6881 // Take care of any services that are waiting for the process.
6882 mServices.processStartTimedOutLocked(app);
6883 app.kill("start timeout", true);
6885 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6887 removeLruProcessLocked(app);
6888 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6889 Slog.w(TAG, "Unattached app died before backup, skipping");
6890 mHandler.post(new Runnable() {
6894 IBackupManager bm = IBackupManager.Stub.asInterface(
6895 ServiceManager.getService(Context.BACKUP_SERVICE));
6896 bm.agentDisconnected(app.info.packageName);
6897 } catch (RemoteException e) {
6898 // Can't happen; the backup manager is local
6903 if (isPendingBroadcastProcessLocked(pid)) {
6904 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6905 skipPendingBroadcastLocked(pid);
6908 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6912 private final boolean attachApplicationLocked(IApplicationThread thread,
6915 // Find the application record that is being attached... either via
6916 // the pid if we are running in multiple processes, or just pull the
6917 // next app record if we are emulating process with anonymous threads.
6919 long startTime = SystemClock.uptimeMillis();
6920 if (pid != MY_PID && pid >= 0) {
6921 synchronized (mPidsSelfLocked) {
6922 app = mPidsSelfLocked.get(pid);
6929 Slog.w(TAG, "No pending application record for pid " + pid
6930 + " (IApplicationThread " + thread + "); dropping process");
6931 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6932 if (pid > 0 && pid != MY_PID) {
6933 killProcessQuiet(pid);
6934 //TODO: killProcessGroup(app.info.uid, pid);
6937 thread.scheduleExit();
6938 } catch (Exception e) {
6939 // Ignore exceptions.
6945 // If this application record is still attached to a previous
6946 // process, clean it up now.
6947 if (app.thread != null) {
6948 handleAppDiedLocked(app, true, true);
6951 // Tell the process all about itself.
6953 if (DEBUG_ALL) Slog.v(
6954 TAG, "Binding process pid " + pid + " to record " + app);
6956 final String processName = app.processName;
6958 AppDeathRecipient adr = new AppDeathRecipient(
6960 thread.asBinder().linkToDeath(adr, 0);
6961 app.deathRecipient = adr;
6962 } catch (RemoteException e) {
6963 app.resetPackageList(mProcessStats);
6964 startProcessLocked(app, "link fail", processName);
6968 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6970 app.makeActive(thread, mProcessStats);
6971 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6972 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6973 app.forcingToImportant = null;
6974 updateProcessForegroundLocked(app, false, false);
6975 app.hasShownUi = false;
6976 app.debugging = false;
6978 app.killedByAm = false;
6982 // We carefully use the same state that PackageManager uses for
6983 // filtering, since we use this flag to decide if we need to install
6984 // providers when user is unlocked later
6985 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6987 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6989 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6990 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6992 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6993 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6995 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6998 checkTime(startTime, "attachApplicationLocked: before bindApplication");
7001 Slog.i(TAG, "Launching preboot mode app: " + app);
7004 if (DEBUG_ALL) Slog.v(
7005 TAG, "New app record " + app
7006 + " thread=" + thread.asBinder() + " pid=" + pid);
7008 int testMode = ApplicationThreadConstants.DEBUG_OFF;
7009 if (mDebugApp != null && mDebugApp.equals(processName)) {
7010 testMode = mWaitForDebugger
7011 ? ApplicationThreadConstants.DEBUG_WAIT
7012 : ApplicationThreadConstants.DEBUG_ON;
7013 app.debugging = true;
7014 if (mDebugTransient) {
7015 mDebugApp = mOrigDebugApp;
7016 mWaitForDebugger = mOrigWaitForDebugger;
7020 ProfilerInfo profilerInfo = null;
7021 String preBindAgent = null;
7022 if (mProfileApp != null && mProfileApp.equals(processName)) {
7024 if (mProfilerInfo != null) {
7025 // Send a profiler info object to the app if either a file is given, or
7026 // an agent should be loaded at bind-time.
7027 boolean needsInfo = mProfilerInfo.profileFile != null
7028 || mProfilerInfo.attachAgentDuringBind;
7029 profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7030 if (!mProfilerInfo.attachAgentDuringBind) {
7031 preBindAgent = mProfilerInfo.agent;
7034 } else if (app.instr != null && app.instr.mProfileFile != null) {
7035 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7039 boolean enableTrackAllocation = false;
7040 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7041 enableTrackAllocation = true;
7042 mTrackAllocationApp = null;
7045 // If the app is being launched for restore or full backup, set it up specially
7046 boolean isRestrictedBackupMode = false;
7047 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7048 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7049 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7050 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7051 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7054 if (app.instr != null) {
7055 notifyPackageUse(app.instr.mClass.getPackageName(),
7056 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7058 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7059 + processName + " with config " + getGlobalConfiguration());
7060 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7061 app.compat = compatibilityInfoForPackageLocked(appInfo);
7063 if (profilerInfo != null && profilerInfo.profileFd != null) {
7064 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7067 // We deprecated Build.SERIAL and it is not accessible to
7068 // apps that target the v2 security sandbox. Since access to
7069 // the serial is now behind a permission we push down the value.
7070 String buildSerial = appInfo.targetSandboxVersion < 2
7071 ? sTheRealBuildSerial : Build.UNKNOWN;
7073 // Check if this is a secondary process that should be incorporated into some
7074 // currently active instrumentation. (Note we do this AFTER all of the profiling
7075 // stuff above because profiling can currently happen only in the primary
7076 // instrumentation process.)
7077 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7078 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7079 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7080 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7081 if (aInstr.mTargetProcesses.length == 0) {
7082 // This is the wildcard mode, where every process brought up for
7083 // the target instrumentation should be included.
7084 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7086 aInstr.mRunningProcesses.add(app);
7089 for (String proc : aInstr.mTargetProcesses) {
7090 if (proc.equals(app.processName)) {
7092 aInstr.mRunningProcesses.add(app);
7101 // If we were asked to attach an agent on startup, do so now, before we're binding
7102 // application code.
7103 if (preBindAgent != null) {
7104 thread.attachAgent(preBindAgent);
7107 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7108 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7109 if (app.instr != null) {
7110 thread.bindApplication(processName, appInfo, providers,
7112 profilerInfo, app.instr.mArguments,
7114 app.instr.mUiAutomationConnection, testMode,
7115 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7116 isRestrictedBackupMode || !normalMode, app.persistent,
7117 new Configuration(getGlobalConfiguration()), app.compat,
7118 getCommonServicesLocked(app.isolated),
7119 mCoreSettingsObserver.getCoreSettingsLocked(),
7122 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7123 null, null, null, testMode,
7124 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7125 isRestrictedBackupMode || !normalMode, app.persistent,
7126 new Configuration(getGlobalConfiguration()), app.compat,
7127 getCommonServicesLocked(app.isolated),
7128 mCoreSettingsObserver.getCoreSettingsLocked(),
7132 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7133 updateLruProcessLocked(app, false, null);
7134 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7135 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7136 } catch (Exception e) {
7137 // todo: Yikes! What should we do? For now we will try to
7138 // start another process, but that could easily get us in
7139 // an infinite loop of restarting processes...
7140 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7142 app.resetPackageList(mProcessStats);
7143 app.unlinkDeathRecipient();
7144 startProcessLocked(app, "bind fail", processName);
7148 // Remove this record from the list of starting applications.
7149 mPersistentStartingProcesses.remove(app);
7150 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7151 "Attach application locked removing on hold: " + app);
7152 mProcessesOnHold.remove(app);
7154 boolean badApp = false;
7155 boolean didSomething = false;
7157 // See if the top visible activity is waiting to run in this process...
7160 if (mStackSupervisor.attachApplicationLocked(app)) {
7161 didSomething = true;
7163 } catch (Exception e) {
7164 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7169 // Find any services that should be running in this process...
7172 didSomething |= mServices.attachApplicationLocked(app, processName);
7173 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7174 } catch (Exception e) {
7175 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7180 // Check if a next-broadcast receiver is in this process...
7181 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7183 didSomething |= sendPendingBroadcastsLocked(app);
7184 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7185 } catch (Exception e) {
7186 // If the app died trying to launch the receiver we declare it 'bad'
7187 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7192 // Check whether the next backup agent is in this process...
7193 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7194 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7195 "New app is backup target, launching agent for " + app);
7196 notifyPackageUse(mBackupTarget.appInfo.packageName,
7197 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7199 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7200 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7201 mBackupTarget.backupMode);
7202 } catch (Exception e) {
7203 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7209 app.kill("error during init", true);
7210 handleAppDiedLocked(app, false, true);
7214 if (!didSomething) {
7215 updateOomAdjLocked();
7216 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7223 public final void attachApplication(IApplicationThread thread) {
7224 synchronized (this) {
7225 int callingPid = Binder.getCallingPid();
7226 final long origId = Binder.clearCallingIdentity();
7227 attachApplicationLocked(thread, callingPid);
7228 Binder.restoreCallingIdentity(origId);
7233 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7234 final long origId = Binder.clearCallingIdentity();
7235 synchronized (this) {
7236 ActivityStack stack = ActivityRecord.getStackLocked(token);
7237 if (stack != null) {
7239 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7240 false /* processPausingActivities */, config);
7241 if (stopProfiling) {
7242 if ((mProfileProc == r.app) && mProfilerInfo != null) {
7243 clearProfilerLocked();
7248 Binder.restoreCallingIdentity(origId);
7251 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7252 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7253 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7256 void enableScreenAfterBoot() {
7257 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7258 SystemClock.uptimeMillis());
7259 mWindowManager.enableScreenAfterBoot();
7261 synchronized (this) {
7262 updateEventDispatchingLocked();
7267 public void showBootMessage(final CharSequence msg, final boolean always) {
7268 if (Binder.getCallingUid() != myUid()) {
7269 throw new SecurityException();
7271 mWindowManager.showBootMessage(msg, always);
7275 public void keyguardGoingAway(int flags) {
7276 enforceNotIsolatedCaller("keyguardGoingAway");
7277 final long token = Binder.clearCallingIdentity();
7279 synchronized (this) {
7280 mKeyguardController.keyguardGoingAway(flags);
7283 Binder.restoreCallingIdentity(token);
7288 * @return whther the keyguard is currently locked.
7290 boolean isKeyguardLocked() {
7291 return mKeyguardController.isKeyguardLocked();
7294 final void finishBooting() {
7295 synchronized (this) {
7296 if (!mBootAnimationComplete) {
7297 mCallFinishBooting = true;
7300 mCallFinishBooting = false;
7303 ArraySet<String> completedIsas = new ArraySet<String>();
7304 for (String abi : Build.SUPPORTED_ABIS) {
7305 zygoteProcess.establishZygoteConnectionForAbi(abi);
7306 final String instructionSet = VMRuntime.getInstructionSet(abi);
7307 if (!completedIsas.contains(instructionSet)) {
7309 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7310 } catch (InstallerException e) {
7311 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7312 e.getMessage() +")");
7314 completedIsas.add(instructionSet);
7318 IntentFilter pkgFilter = new IntentFilter();
7319 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7320 pkgFilter.addDataScheme("package");
7321 mContext.registerReceiver(new BroadcastReceiver() {
7323 public void onReceive(Context context, Intent intent) {
7324 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7326 for (String pkg : pkgs) {
7327 synchronized (ActivityManagerService.this) {
7328 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7329 0, "query restart")) {
7330 setResultCode(Activity.RESULT_OK);
7339 IntentFilter dumpheapFilter = new IntentFilter();
7340 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7341 mContext.registerReceiver(new BroadcastReceiver() {
7343 public void onReceive(Context context, Intent intent) {
7344 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7345 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7347 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7352 // Let system services know.
7353 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7355 synchronized (this) {
7356 // Ensure that any processes we had put on hold are now started
7358 final int NP = mProcessesOnHold.size();
7360 ArrayList<ProcessRecord> procs =
7361 new ArrayList<ProcessRecord>(mProcessesOnHold);
7362 for (int ip=0; ip<NP; ip++) {
7363 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7365 startProcessLocked(procs.get(ip), "on-hold", null);
7369 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7370 // Start looking for apps that are abusing wake locks.
7371 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7372 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7373 // Tell anyone interested that we are done booting!
7374 SystemProperties.set("sys.boot_completed", "1");
7376 // And trigger dev.bootcomplete if we are not showing encryption progress
7377 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7378 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7379 SystemProperties.set("dev.bootcomplete", "1");
7381 mUserController.sendBootCompletedLocked(
7382 new IIntentReceiver.Stub() {
7384 public void performReceive(Intent intent, int resultCode,
7385 String data, Bundle extras, boolean ordered,
7386 boolean sticky, int sendingUser) {
7387 synchronized (ActivityManagerService.this) {
7388 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7393 scheduleStartProfilesLocked();
7399 public void bootAnimationComplete() {
7400 final boolean callFinishBooting;
7401 synchronized (this) {
7402 callFinishBooting = mCallFinishBooting;
7403 mBootAnimationComplete = true;
7405 if (callFinishBooting) {
7406 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7408 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7412 final void ensureBootCompleted() {
7414 boolean enableScreen;
7415 synchronized (this) {
7418 enableScreen = !mBooted;
7423 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7425 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7429 enableScreenAfterBoot();
7434 public final void activityResumed(IBinder token) {
7435 final long origId = Binder.clearCallingIdentity();
7436 synchronized(this) {
7437 ActivityRecord.activityResumedLocked(token);
7438 mWindowManager.notifyAppResumedFinished(token);
7440 Binder.restoreCallingIdentity(origId);
7444 public final void activityPaused(IBinder token) {
7445 final long origId = Binder.clearCallingIdentity();
7446 synchronized(this) {
7447 ActivityStack stack = ActivityRecord.getStackLocked(token);
7448 if (stack != null) {
7449 stack.activityPausedLocked(token, false);
7452 Binder.restoreCallingIdentity(origId);
7456 public final void activityStopped(IBinder token, Bundle icicle,
7457 PersistableBundle persistentState, CharSequence description) {
7458 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7460 // Refuse possible leaked file descriptors
7461 if (icicle != null && icicle.hasFileDescriptors()) {
7462 throw new IllegalArgumentException("File descriptors passed in Bundle");
7465 final long origId = Binder.clearCallingIdentity();
7467 synchronized (this) {
7468 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7470 r.activityStoppedLocked(icicle, persistentState, description);
7476 Binder.restoreCallingIdentity(origId);
7480 public final void activityDestroyed(IBinder token) {
7481 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7482 synchronized (this) {
7483 ActivityStack stack = ActivityRecord.getStackLocked(token);
7484 if (stack != null) {
7485 stack.activityDestroyedLocked(token, "activityDestroyed");
7491 public final void activityRelaunched(IBinder token) {
7492 final long origId = Binder.clearCallingIdentity();
7493 synchronized (this) {
7494 mStackSupervisor.activityRelaunchedLocked(token);
7496 Binder.restoreCallingIdentity(origId);
7500 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7501 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7502 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7503 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7504 synchronized (this) {
7505 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7506 if (record == null) {
7507 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7508 + "found for: " + token);
7510 record.setSizeConfigurations(horizontalSizeConfiguration,
7511 verticalSizeConfigurations, smallestSizeConfigurations);
7516 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7517 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7521 public final void notifyEnterAnimationComplete(IBinder token) {
7522 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7526 public String getCallingPackage(IBinder token) {
7527 synchronized (this) {
7528 ActivityRecord r = getCallingRecordLocked(token);
7529 return r != null ? r.info.packageName : null;
7534 public ComponentName getCallingActivity(IBinder token) {
7535 synchronized (this) {
7536 ActivityRecord r = getCallingRecordLocked(token);
7537 return r != null ? r.intent.getComponent() : null;
7541 private ActivityRecord getCallingRecordLocked(IBinder token) {
7542 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7550 public ComponentName getActivityClassForToken(IBinder token) {
7551 synchronized(this) {
7552 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7556 return r.intent.getComponent();
7561 public String getPackageForToken(IBinder token) {
7562 synchronized(this) {
7563 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7567 return r.packageName;
7572 public boolean isRootVoiceInteraction(IBinder token) {
7573 synchronized(this) {
7574 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7578 return r.rootVoiceInteraction;
7583 public IIntentSender getIntentSender(int type,
7584 String packageName, IBinder token, String resultWho,
7585 int requestCode, Intent[] intents, String[] resolvedTypes,
7586 int flags, Bundle bOptions, int userId) {
7587 enforceNotIsolatedCaller("getIntentSender");
7588 // Refuse possible leaked file descriptors
7589 if (intents != null) {
7590 if (intents.length < 1) {
7591 throw new IllegalArgumentException("Intents array length must be >= 1");
7593 for (int i=0; i<intents.length; i++) {
7594 Intent intent = intents[i];
7595 if (intent != null) {
7596 if (intent.hasFileDescriptors()) {
7597 throw new IllegalArgumentException("File descriptors passed in Intent");
7599 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7600 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7601 throw new IllegalArgumentException(
7602 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7604 intents[i] = new Intent(intent);
7607 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7608 throw new IllegalArgumentException(
7609 "Intent array length does not match resolvedTypes length");
7612 if (bOptions != null) {
7613 if (bOptions.hasFileDescriptors()) {
7614 throw new IllegalArgumentException("File descriptors passed in options");
7618 synchronized(this) {
7619 int callingUid = Binder.getCallingUid();
7620 int origUserId = userId;
7621 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7622 type == ActivityManager.INTENT_SENDER_BROADCAST,
7623 ALLOW_NON_FULL, "getIntentSender", null);
7624 if (origUserId == UserHandle.USER_CURRENT) {
7625 // We don't want to evaluate this until the pending intent is
7626 // actually executed. However, we do want to always do the
7627 // security checking for it above.
7628 userId = UserHandle.USER_CURRENT;
7631 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7632 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7633 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7634 if (!UserHandle.isSameApp(callingUid, uid)) {
7635 String msg = "Permission Denial: getIntentSender() from pid="
7636 + Binder.getCallingPid()
7637 + ", uid=" + Binder.getCallingUid()
7638 + ", (need uid=" + uid + ")"
7639 + " is not allowed to send as package " + packageName;
7641 throw new SecurityException(msg);
7645 return getIntentSenderLocked(type, packageName, callingUid, userId,
7646 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7648 } catch (RemoteException e) {
7649 throw new SecurityException(e);
7654 IIntentSender getIntentSenderLocked(int type, String packageName,
7655 int callingUid, int userId, IBinder token, String resultWho,
7656 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7658 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7659 ActivityRecord activity = null;
7660 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7661 activity = ActivityRecord.isInStackLocked(token);
7662 if (activity == null) {
7663 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7666 if (activity.finishing) {
7667 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7672 // We're going to be splicing together extras before sending, so we're
7673 // okay poking into any contained extras.
7674 if (intents != null) {
7675 for (int i = 0; i < intents.length; i++) {
7676 intents[i].setDefusable(true);
7679 Bundle.setDefusable(bOptions, true);
7681 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7682 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7683 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7684 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7685 |PendingIntent.FLAG_UPDATE_CURRENT);
7687 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7688 type, packageName, activity, resultWho,
7689 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7690 WeakReference<PendingIntentRecord> ref;
7691 ref = mIntentSenderRecords.get(key);
7692 PendingIntentRecord rec = ref != null ? ref.get() : null;
7694 if (!cancelCurrent) {
7695 if (updateCurrent) {
7696 if (rec.key.requestIntent != null) {
7697 rec.key.requestIntent.replaceExtras(intents != null ?
7698 intents[intents.length - 1] : null);
7700 if (intents != null) {
7701 intents[intents.length-1] = rec.key.requestIntent;
7702 rec.key.allIntents = intents;
7703 rec.key.allResolvedTypes = resolvedTypes;
7705 rec.key.allIntents = null;
7706 rec.key.allResolvedTypes = null;
7711 makeIntentSenderCanceledLocked(rec);
7712 mIntentSenderRecords.remove(key);
7717 rec = new PendingIntentRecord(this, key, callingUid);
7718 mIntentSenderRecords.put(key, rec.ref);
7719 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7720 if (activity.pendingResults == null) {
7721 activity.pendingResults
7722 = new HashSet<WeakReference<PendingIntentRecord>>();
7724 activity.pendingResults.add(rec.ref);
7730 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7731 Intent intent, String resolvedType,
7732 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7733 if (target instanceof PendingIntentRecord) {
7734 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7735 whitelistToken, finishedReceiver, requiredPermission, options);
7737 if (intent == null) {
7738 // Weird case: someone has given us their own custom IIntentSender, and now
7739 // they have someone else trying to send to it but of course this isn't
7740 // really a PendingIntent, so there is no base Intent, and the caller isn't
7741 // supplying an Intent... but we never want to dispatch a null Intent to
7742 // a receiver, so um... let's make something up.
7743 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7744 intent = new Intent(Intent.ACTION_MAIN);
7747 target.send(code, intent, resolvedType, whitelistToken, null,
7748 requiredPermission, options);
7749 } catch (RemoteException e) {
7751 // Platform code can rely on getting a result back when the send is done, but if
7752 // this intent sender is from outside of the system we can't rely on it doing that.
7753 // So instead we don't give it the result receiver, and instead just directly
7754 // report the finish immediately.
7755 if (finishedReceiver != null) {
7757 finishedReceiver.performReceive(intent, 0,
7758 null, null, false, false, UserHandle.getCallingUserId());
7759 } catch (RemoteException e) {
7767 public void cancelIntentSender(IIntentSender sender) {
7768 if (!(sender instanceof PendingIntentRecord)) {
7771 synchronized(this) {
7772 PendingIntentRecord rec = (PendingIntentRecord)sender;
7774 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7775 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7776 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7777 String msg = "Permission Denial: cancelIntentSender() from pid="
7778 + Binder.getCallingPid()
7779 + ", uid=" + Binder.getCallingUid()
7780 + " is not allowed to cancel package "
7781 + rec.key.packageName;
7783 throw new SecurityException(msg);
7785 } catch (RemoteException e) {
7786 throw new SecurityException(e);
7788 cancelIntentSenderLocked(rec, true);
7792 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7793 makeIntentSenderCanceledLocked(rec);
7794 mIntentSenderRecords.remove(rec.key);
7795 if (cleanActivity && rec.key.activity != null) {
7796 rec.key.activity.pendingResults.remove(rec.ref);
7800 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7801 rec.canceled = true;
7802 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7803 if (callbacks != null) {
7804 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7809 public String getPackageForIntentSender(IIntentSender pendingResult) {
7810 if (!(pendingResult instanceof PendingIntentRecord)) {
7814 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7815 return res.key.packageName;
7816 } catch (ClassCastException e) {
7822 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7823 if (!(sender instanceof PendingIntentRecord)) {
7826 synchronized(this) {
7827 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7832 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7833 IResultReceiver receiver) {
7834 if (!(sender instanceof PendingIntentRecord)) {
7837 synchronized(this) {
7838 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7843 public int getUidForIntentSender(IIntentSender sender) {
7844 if (sender instanceof PendingIntentRecord) {
7846 PendingIntentRecord res = (PendingIntentRecord)sender;
7848 } catch (ClassCastException e) {
7855 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7856 if (!(pendingResult instanceof PendingIntentRecord)) {
7860 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7861 if (res.key.allIntents == null) {
7864 for (int i=0; i<res.key.allIntents.length; i++) {
7865 Intent intent = res.key.allIntents[i];
7866 if (intent.getPackage() != null && intent.getComponent() != null) {
7871 } catch (ClassCastException e) {
7877 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7878 if (!(pendingResult instanceof PendingIntentRecord)) {
7882 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7883 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7887 } catch (ClassCastException e) {
7893 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7894 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7895 "getIntentForIntentSender()");
7896 if (!(pendingResult instanceof PendingIntentRecord)) {
7900 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7901 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7902 } catch (ClassCastException e) {
7908 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7909 if (!(pendingResult instanceof PendingIntentRecord)) {
7913 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7914 synchronized (this) {
7915 return getTagForIntentSenderLocked(res, prefix);
7917 } catch (ClassCastException e) {
7922 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7923 final Intent intent = res.key.requestIntent;
7924 if (intent != null) {
7925 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7926 || res.lastTagPrefix.equals(prefix))) {
7929 res.lastTagPrefix = prefix;
7930 final StringBuilder sb = new StringBuilder(128);
7931 if (prefix != null) {
7934 if (intent.getAction() != null) {
7935 sb.append(intent.getAction());
7936 } else if (intent.getComponent() != null) {
7937 intent.getComponent().appendShortString(sb);
7941 return res.lastTag = sb.toString();
7947 public void setProcessLimit(int max) {
7948 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7949 "setProcessLimit()");
7950 synchronized (this) {
7951 mConstants.setOverrideMaxCachedProcesses(max);
7957 public int getProcessLimit() {
7958 synchronized (this) {
7959 return mConstants.getOverrideMaxCachedProcesses();
7963 void importanceTokenDied(ImportanceToken token) {
7964 synchronized (ActivityManagerService.this) {
7965 synchronized (mPidsSelfLocked) {
7967 = mImportantProcesses.get(token.pid);
7971 mImportantProcesses.remove(token.pid);
7972 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7976 pr.forcingToImportant = null;
7977 updateProcessForegroundLocked(pr, false, false);
7979 updateOomAdjLocked();
7984 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7985 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7986 "setProcessImportant()");
7987 synchronized(this) {
7988 boolean changed = false;
7990 synchronized (mPidsSelfLocked) {
7991 ProcessRecord pr = mPidsSelfLocked.get(pid);
7992 if (pr == null && isForeground) {
7993 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7996 ImportanceToken oldToken = mImportantProcesses.get(pid);
7997 if (oldToken != null) {
7998 oldToken.token.unlinkToDeath(oldToken, 0);
7999 mImportantProcesses.remove(pid);
8001 pr.forcingToImportant = null;
8005 if (isForeground && token != null) {
8006 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8008 public void binderDied() {
8009 importanceTokenDied(this);
8013 token.linkToDeath(newToken, 0);
8014 mImportantProcesses.put(pid, newToken);
8015 pr.forcingToImportant = newToken;
8017 } catch (RemoteException e) {
8018 // If the process died while doing this, we will later
8019 // do the cleanup with the process death link.
8025 updateOomAdjLocked();
8031 public boolean isAppForeground(int uid) throws RemoteException {
8032 synchronized (this) {
8033 UidRecord uidRec = mActiveUids.get(uid);
8034 if (uidRec == null || uidRec.idle) {
8037 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8041 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8042 // be guarded by permission checking.
8043 int getUidState(int uid) {
8044 synchronized (this) {
8045 return getUidStateLocked(uid);
8049 int getUidStateLocked(int uid) {
8050 UidRecord uidRec = mActiveUids.get(uid);
8051 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8055 public boolean isInMultiWindowMode(IBinder token) {
8056 final long origId = Binder.clearCallingIdentity();
8058 synchronized(this) {
8059 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8063 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8064 return !r.getTask().mFullscreen;
8067 Binder.restoreCallingIdentity(origId);
8072 public boolean isInPictureInPictureMode(IBinder token) {
8073 final long origId = Binder.clearCallingIdentity();
8075 synchronized(this) {
8076 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8079 Binder.restoreCallingIdentity(origId);
8083 private boolean isInPictureInPictureMode(ActivityRecord r) {
8084 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8085 r.getStack().isInStackLocked(r) == null) {
8089 // If we are animating to fullscreen then we have already dispatched the PIP mode
8090 // changed, so we should reflect that check here as well.
8091 final PinnedActivityStack stack = r.getStack();
8092 final PinnedStackWindowController windowController = stack.getWindowContainerController();
8093 return !windowController.isAnimatingBoundsToFullscreen();
8097 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8098 final long origId = Binder.clearCallingIdentity();
8100 synchronized(this) {
8101 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8102 "enterPictureInPictureMode", token, params);
8104 // If the activity is already in picture in picture mode, then just return early
8105 if (isInPictureInPictureMode(r)) {
8109 // Activity supports picture-in-picture, now check that we can enter PiP at this
8111 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8112 false /* beforeStopping */)) {
8116 final Runnable enterPipRunnable = () -> {
8117 // Only update the saved args from the args that are set
8118 r.pictureInPictureArgs.copyOnlySet(params);
8119 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8120 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8121 // Adjust the source bounds by the insets for the transition down
8122 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8123 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8124 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8125 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8126 stack.setPictureInPictureAspectRatio(aspectRatio);
8127 stack.setPictureInPictureActions(actions);
8129 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8130 r.supportsEnterPipOnTaskSwitch);
8131 logPictureInPictureArgs(params);
8134 if (isKeyguardLocked()) {
8135 // If the keyguard is showing or occluded, then try and dismiss it before
8136 // entering picture-in-picture (this will prompt the user to authenticate if the
8137 // device is currently locked).
8139 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8141 public void onDismissError() throws RemoteException {
8146 public void onDismissSucceeded() throws RemoteException {
8147 mHandler.post(enterPipRunnable);
8151 public void onDismissCancelled() throws RemoteException {
8155 } catch (RemoteException e) {
8159 // Enter picture in picture immediately otherwise
8160 enterPipRunnable.run();
8165 Binder.restoreCallingIdentity(origId);
8170 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8171 final long origId = Binder.clearCallingIdentity();
8173 synchronized(this) {
8174 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8175 "setPictureInPictureParams", token, params);
8177 // Only update the saved args from the args that are set
8178 r.pictureInPictureArgs.copyOnlySet(params);
8179 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8180 // If the activity is already in picture-in-picture, update the pinned stack now
8181 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8182 // be used the next time the activity enters PiP
8183 final PinnedActivityStack stack = r.getStack();
8184 if (!stack.isAnimatingBoundsToFullscreen()) {
8185 stack.setPictureInPictureAspectRatio(
8186 r.pictureInPictureArgs.getAspectRatio());
8187 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8190 logPictureInPictureArgs(params);
8193 Binder.restoreCallingIdentity(origId);
8198 public int getMaxNumPictureInPictureActions(IBinder token) {
8199 // Currently, this is a static constant, but later, we may change this to be dependent on
8200 // the context of the activity
8204 private void logPictureInPictureArgs(PictureInPictureParams params) {
8205 if (params.hasSetActions()) {
8206 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8207 params.getActions().size());
8209 if (params.hasSetAspectRatio()) {
8210 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8211 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8212 MetricsLogger.action(lm);
8217 * Checks the state of the system and the activity associated with the given {@param token} to
8218 * verify that picture-in-picture is supported for that activity.
8220 * @return the activity record for the given {@param token} if all the checks pass.
8222 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8223 IBinder token, PictureInPictureParams params) {
8224 if (!mSupportsPictureInPicture) {
8225 throw new IllegalStateException(caller
8226 + ": Device doesn't support picture-in-picture mode.");
8229 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8231 throw new IllegalStateException(caller
8232 + ": Can't find activity for token=" + token);
8235 if (!r.supportsPictureInPicture()) {
8236 throw new IllegalStateException(caller
8237 + ": Current activity does not support picture-in-picture.");
8240 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8241 throw new IllegalStateException(caller
8242 + ": Activities on the home, assistant, or recents stack not supported");
8245 if (params.hasSetAspectRatio()
8246 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8247 params.getAspectRatio())) {
8248 final float minAspectRatio = mContext.getResources().getFloat(
8249 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8250 final float maxAspectRatio = mContext.getResources().getFloat(
8251 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8252 throw new IllegalArgumentException(String.format(caller
8253 + ": Aspect ratio is too extreme (must be between %f and %f).",
8254 minAspectRatio, maxAspectRatio));
8257 // Truncate the number of actions if necessary
8258 params.truncateActions(getMaxNumPictureInPictureActions(token));
8263 // =========================================================
8265 // =========================================================
8267 static class ProcessInfoService extends IProcessInfoService.Stub {
8268 final ActivityManagerService mActivityManagerService;
8269 ProcessInfoService(ActivityManagerService activityManagerService) {
8270 mActivityManagerService = activityManagerService;
8274 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8275 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8276 /*in*/ pids, /*out*/ states, null);
8280 public void getProcessStatesAndOomScoresFromPids(
8281 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8282 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8283 /*in*/ pids, /*out*/ states, /*out*/ scores);
8288 * For each PID in the given input array, write the current process state
8289 * for that process into the states array, or -1 to indicate that no
8290 * process with the given PID exists. If scores array is provided, write
8291 * the oom score for the process into the scores array, with INVALID_ADJ
8292 * indicating the PID doesn't exist.
8294 public void getProcessStatesAndOomScoresForPIDs(
8295 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8296 if (scores != null) {
8297 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8298 "getProcessStatesAndOomScoresForPIDs()");
8302 throw new NullPointerException("pids");
8303 } else if (states == null) {
8304 throw new NullPointerException("states");
8305 } else if (pids.length != states.length) {
8306 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8307 } else if (scores != null && pids.length != scores.length) {
8308 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8311 synchronized (mPidsSelfLocked) {
8312 for (int i = 0; i < pids.length; i++) {
8313 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8314 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8316 if (scores != null) {
8317 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8323 // =========================================================
8325 // =========================================================
8327 static class PermissionController extends IPermissionController.Stub {
8328 ActivityManagerService mActivityManagerService;
8329 PermissionController(ActivityManagerService activityManagerService) {
8330 mActivityManagerService = activityManagerService;
8334 public boolean checkPermission(String permission, int pid, int uid) {
8335 return mActivityManagerService.checkPermission(permission, pid,
8336 uid) == PackageManager.PERMISSION_GRANTED;
8340 public String[] getPackagesForUid(int uid) {
8341 return mActivityManagerService.mContext.getPackageManager()
8342 .getPackagesForUid(uid);
8346 public boolean isRuntimePermission(String permission) {
8348 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8349 .getPermissionInfo(permission, 0);
8350 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8351 == PermissionInfo.PROTECTION_DANGEROUS;
8352 } catch (NameNotFoundException nnfe) {
8353 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8359 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8361 public int checkComponentPermission(String permission, int pid, int uid,
8362 int owningUid, boolean exported) {
8363 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8364 owningUid, exported);
8368 public Object getAMSLock() {
8369 return ActivityManagerService.this;
8374 * This can be called with or without the global lock held.
8376 int checkComponentPermission(String permission, int pid, int uid,
8377 int owningUid, boolean exported) {
8378 if (pid == MY_PID) {
8379 return PackageManager.PERMISSION_GRANTED;
8381 return ActivityManager.checkComponentPermission(permission, uid,
8382 owningUid, exported);
8386 * As the only public entry point for permissions checking, this method
8387 * can enforce the semantic that requesting a check on a null global
8388 * permission is automatically denied. (Internally a null permission
8389 * string is used when calling {@link #checkComponentPermission} in cases
8390 * when only uid-based security is needed.)
8392 * This can be called with or without the global lock held.
8395 public int checkPermission(String permission, int pid, int uid) {
8396 if (permission == null) {
8397 return PackageManager.PERMISSION_DENIED;
8399 return checkComponentPermission(permission, pid, uid, -1, true);
8403 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8404 if (permission == null) {
8405 return PackageManager.PERMISSION_DENIED;
8408 // We might be performing an operation on behalf of an indirect binder
8409 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8410 // client identity accordingly before proceeding.
8411 Identity tlsIdentity = sCallerIdentity.get();
8412 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8413 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8414 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8415 uid = tlsIdentity.uid;
8416 pid = tlsIdentity.pid;
8419 return checkComponentPermission(permission, pid, uid, -1, true);
8423 * Binder IPC calls go through the public entry point.
8424 * This can be called with or without the global lock held.
8426 int checkCallingPermission(String permission) {
8427 return checkPermission(permission,
8428 Binder.getCallingPid(),
8429 UserHandle.getAppId(Binder.getCallingUid()));
8433 * This can be called with or without the global lock held.
8435 void enforceCallingPermission(String permission, String func) {
8436 if (checkCallingPermission(permission)
8437 == PackageManager.PERMISSION_GRANTED) {
8441 String msg = "Permission Denial: " + func + " from pid="
8442 + Binder.getCallingPid()
8443 + ", uid=" + Binder.getCallingUid()
8444 + " requires " + permission;
8446 throw new SecurityException(msg);
8450 * Determine if UID is holding permissions required to access {@link Uri} in
8451 * the given {@link ProviderInfo}. Final permission checking is always done
8452 * in {@link ContentProvider}.
8454 private final boolean checkHoldingPermissionsLocked(
8455 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8456 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8457 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8458 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8459 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8460 != PERMISSION_GRANTED) {
8464 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8467 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8468 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8469 if (pi.applicationInfo.uid == uid) {
8471 } else if (!pi.exported) {
8475 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8476 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8478 // check if target holds top-level <provider> permissions
8479 if (!readMet && pi.readPermission != null && considerUidPermissions
8480 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8483 if (!writeMet && pi.writePermission != null && considerUidPermissions
8484 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8488 // track if unprotected read/write is allowed; any denied
8489 // <path-permission> below removes this ability
8490 boolean allowDefaultRead = pi.readPermission == null;
8491 boolean allowDefaultWrite = pi.writePermission == null;
8493 // check if target holds any <path-permission> that match uri
8494 final PathPermission[] pps = pi.pathPermissions;
8496 final String path = grantUri.uri.getPath();
8498 while (i > 0 && (!readMet || !writeMet)) {
8500 PathPermission pp = pps[i];
8501 if (pp.match(path)) {
8503 final String pprperm = pp.getReadPermission();
8504 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8505 "Checking read perm for " + pprperm + " for " + pp.getPath()
8506 + ": match=" + pp.match(path)
8507 + " check=" + pm.checkUidPermission(pprperm, uid));
8508 if (pprperm != null) {
8509 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8510 == PERMISSION_GRANTED) {
8513 allowDefaultRead = false;
8518 final String ppwperm = pp.getWritePermission();
8519 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8520 "Checking write perm " + ppwperm + " for " + pp.getPath()
8521 + ": match=" + pp.match(path)
8522 + " check=" + pm.checkUidPermission(ppwperm, uid));
8523 if (ppwperm != null) {
8524 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8525 == PERMISSION_GRANTED) {
8528 allowDefaultWrite = false;
8536 // grant unprotected <provider> read/write, if not blocked by
8537 // <path-permission> above
8538 if (allowDefaultRead) readMet = true;
8539 if (allowDefaultWrite) writeMet = true;
8541 } catch (RemoteException e) {
8545 return readMet && writeMet;
8548 public boolean isAppStartModeDisabled(int uid, String packageName) {
8549 synchronized (this) {
8550 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8551 == ActivityManager.APP_START_MODE_DISABLED;
8555 // Unified app-op and target sdk check
8556 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8557 // Apps that target O+ are always subject to background check
8558 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8559 if (DEBUG_BACKGROUND_CHECK) {
8560 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8562 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8564 // ...and legacy apps get an AppOp check
8565 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8567 if (DEBUG_BACKGROUND_CHECK) {
8568 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8571 case AppOpsManager.MODE_ALLOWED:
8572 return ActivityManager.APP_START_MODE_NORMAL;
8573 case AppOpsManager.MODE_IGNORED:
8574 return ActivityManager.APP_START_MODE_DELAYED;
8576 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8580 // Service launch is available to apps with run-in-background exemptions but
8581 // some other background operations are not. If we're doing a check
8582 // of service-launch policy, allow those callers to proceed unrestricted.
8583 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8585 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8586 if (DEBUG_BACKGROUND_CHECK) {
8587 Slog.i(TAG, "App " + uid + "/" + packageName
8588 + " is persistent; not restricted in background");
8590 return ActivityManager.APP_START_MODE_NORMAL;
8593 // Non-persistent but background whitelisted?
8594 if (uidOnBackgroundWhitelist(uid)) {
8595 if (DEBUG_BACKGROUND_CHECK) {
8596 Slog.i(TAG, "App " + uid + "/" + packageName
8597 + " on background whitelist; not restricted in background");
8599 return ActivityManager.APP_START_MODE_NORMAL;
8602 // Is this app on the battery whitelist?
8603 if (isOnDeviceIdleWhitelistLocked(uid)) {
8604 if (DEBUG_BACKGROUND_CHECK) {
8605 Slog.i(TAG, "App " + uid + "/" + packageName
8606 + " on idle whitelist; not restricted in background");
8608 return ActivityManager.APP_START_MODE_NORMAL;
8611 // None of the service-policy criteria apply, so we apply the common criteria
8612 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8615 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8616 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8617 UidRecord uidRec = mActiveUids.get(uid);
8618 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8619 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8620 + (uidRec != null ? uidRec.idle : false));
8621 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8623 if (uidRec == null) {
8624 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8625 UserHandle.getUserId(uid), packageName);
8627 ephemeral = uidRec.ephemeral;
8631 // We are hard-core about ephemeral apps not running in the background.
8632 return ActivityManager.APP_START_MODE_DISABLED;
8635 // The caller is only interested in whether app starts are completely
8636 // disabled for the given package (that is, it is an instant app). So
8637 // we don't need to go further, which is all just seeing if we should
8638 // apply a "delayed" mode for a regular app.
8639 return ActivityManager.APP_START_MODE_NORMAL;
8641 final int startMode = (alwaysRestrict)
8642 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8643 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8645 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8646 + " pkg=" + packageName + " startMode=" + startMode
8647 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8648 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8649 // This is an old app that has been forced into a "compatible as possible"
8650 // mode of background check. To increase compatibility, we will allow other
8651 // foreground apps to cause its services to start.
8652 if (callingPid >= 0) {
8654 synchronized (mPidsSelfLocked) {
8655 proc = mPidsSelfLocked.get(callingPid);
8658 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8659 // Whoever is instigating this is in the foreground, so we will allow it
8661 return ActivityManager.APP_START_MODE_NORMAL;
8668 return ActivityManager.APP_START_MODE_NORMAL;
8671 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8672 final int appId = UserHandle.getAppId(uid);
8673 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8674 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8675 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8678 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8679 ProviderInfo pi = null;
8680 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8685 pi = AppGlobals.getPackageManager().resolveContentProvider(
8686 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8688 } catch (RemoteException ex) {
8694 void grantEphemeralAccessLocked(int userId, Intent intent,
8695 int targetAppId, int ephemeralAppId) {
8696 getPackageManagerInternalLocked().
8697 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8700 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8701 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8702 if (targetUris != null) {
8703 return targetUris.get(grantUri);
8708 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8709 String targetPkg, int targetUid, GrantUri grantUri) {
8710 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8711 if (targetUris == null) {
8712 targetUris = Maps.newArrayMap();
8713 mGrantedUriPermissions.put(targetUid, targetUris);
8716 UriPermission perm = targetUris.get(grantUri);
8718 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8719 targetUris.put(grantUri, perm);
8725 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8726 final int modeFlags) {
8727 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8728 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8729 : UriPermission.STRENGTH_OWNED;
8731 // Root gets to do everything.
8736 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8737 if (perms == null) return false;
8739 // First look for exact match
8740 final UriPermission exactPerm = perms.get(grantUri);
8741 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8745 // No exact match, look for prefixes
8746 final int N = perms.size();
8747 for (int i = 0; i < N; i++) {
8748 final UriPermission perm = perms.valueAt(i);
8749 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8750 && perm.getStrength(modeFlags) >= minStrength) {
8759 * @param uri This uri must NOT contain an embedded userId.
8760 * @param userId The userId in which the uri is to be resolved.
8763 public int checkUriPermission(Uri uri, int pid, int uid,
8764 final int modeFlags, int userId, IBinder callerToken) {
8765 enforceNotIsolatedCaller("checkUriPermission");
8767 // Another redirected-binder-call permissions check as in
8768 // {@link checkPermissionWithToken}.
8769 Identity tlsIdentity = sCallerIdentity.get();
8770 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8771 uid = tlsIdentity.uid;
8772 pid = tlsIdentity.pid;
8775 // Our own process gets to do everything.
8776 if (pid == MY_PID) {
8777 return PackageManager.PERMISSION_GRANTED;
8779 synchronized (this) {
8780 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8781 ? PackageManager.PERMISSION_GRANTED
8782 : PackageManager.PERMISSION_DENIED;
8787 * Check if the targetPkg can be granted permission to access uri by
8788 * the callingUid using the given modeFlags. Throws a security exception
8789 * if callingUid is not allowed to do this. Returns the uid of the target
8790 * if the URI permission grant should be performed; returns -1 if it is not
8791 * needed (for example targetPkg already has permission to access the URI).
8792 * If you already know the uid of the target, you can supply it in
8793 * lastTargetUid else set that to -1.
8795 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8796 final int modeFlags, int lastTargetUid) {
8797 if (!Intent.isAccessUriMode(modeFlags)) {
8801 if (targetPkg != null) {
8802 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8803 "Checking grant " + targetPkg + " permission to " + grantUri);
8806 final IPackageManager pm = AppGlobals.getPackageManager();
8808 // If this is not a content: uri, we can't do anything with it.
8809 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8810 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8811 "Can't grant URI permission for non-content URI: " + grantUri);
8815 // Bail early if system is trying to hand out permissions directly; it
8816 // must always grant permissions on behalf of someone explicit.
8817 final int callingAppId = UserHandle.getAppId(callingUid);
8818 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8819 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8820 // Exempted authority for cropping user photos in Settings app
8822 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8823 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8828 final String authority = grantUri.uri.getAuthority();
8829 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8830 MATCH_DEBUG_TRIAGED_MISSING);
8832 Slog.w(TAG, "No content provider found for permission check: " +
8833 grantUri.uri.toSafeString());
8837 int targetUid = lastTargetUid;
8838 if (targetUid < 0 && targetPkg != null) {
8840 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8841 UserHandle.getUserId(callingUid));
8842 if (targetUid < 0) {
8843 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8844 "Can't grant URI permission no uid for: " + targetPkg);
8847 } catch (RemoteException ex) {
8852 // If we're extending a persistable grant, then we always need to create
8853 // the grant data structure so that take/release APIs work
8854 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8858 if (targetUid >= 0) {
8859 // First... does the target actually need this permission?
8860 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8861 // No need to grant the target this permission.
8862 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8863 "Target " + targetPkg + " already has full permission to " + grantUri);
8867 // First... there is no target package, so can anyone access it?
8868 boolean allowed = pi.exported;
8869 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8870 if (pi.readPermission != null) {
8874 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8875 if (pi.writePermission != null) {
8884 /* There is a special cross user grant if:
8885 * - The target is on another user.
8886 * - Apps on the current user can access the uri without any uid permissions.
8887 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8888 * grant uri permissions.
8890 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8891 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8892 modeFlags, false /*without considering the uid permissions*/);
8894 // Second... is the provider allowing granting of URI permissions?
8895 if (!specialCrossUserGrant) {
8896 if (!pi.grantUriPermissions) {
8897 throw new SecurityException("Provider " + pi.packageName
8899 + " does not allow granting of Uri permissions (uri "
8902 if (pi.uriPermissionPatterns != null) {
8903 final int N = pi.uriPermissionPatterns.length;
8904 boolean allowed = false;
8905 for (int i=0; i<N; i++) {
8906 if (pi.uriPermissionPatterns[i] != null
8907 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8913 throw new SecurityException("Provider " + pi.packageName
8915 + " does not allow granting of permission to path of Uri "
8921 // Third... does the caller itself have permission to access
8923 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8924 // Require they hold a strong enough Uri permission
8925 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8926 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8927 throw new SecurityException(
8928 "UID " + callingUid + " does not have permission to " + grantUri
8929 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8930 + "or related APIs");
8932 throw new SecurityException(
8933 "UID " + callingUid + " does not have permission to " + grantUri);
8941 * @param uri This uri must NOT contain an embedded userId.
8942 * @param userId The userId in which the uri is to be resolved.
8945 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8946 final int modeFlags, int userId) {
8947 enforceNotIsolatedCaller("checkGrantUriPermission");
8948 synchronized(this) {
8949 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8950 new GrantUri(userId, uri, false), modeFlags, -1);
8954 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8955 final int modeFlags, UriPermissionOwner owner) {
8956 if (!Intent.isAccessUriMode(modeFlags)) {
8960 // So here we are: the caller has the assumed permission
8961 // to the uri, and the target doesn't. Let's now give this to
8964 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8965 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8967 final String authority = grantUri.uri.getAuthority();
8968 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8969 MATCH_DEBUG_TRIAGED_MISSING);
8971 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8975 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8976 grantUri.prefix = true;
8978 final UriPermission perm = findOrCreateUriPermissionLocked(
8979 pi.packageName, targetPkg, targetUid, grantUri);
8980 perm.grantModes(modeFlags, owner);
8983 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8984 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8985 if (targetPkg == null) {
8986 throw new NullPointerException("targetPkg");
8989 final IPackageManager pm = AppGlobals.getPackageManager();
8991 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8992 } catch (RemoteException ex) {
8996 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8998 if (targetUid < 0) {
9002 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9006 static class NeededUriGrants extends ArrayList<GrantUri> {
9007 final String targetPkg;
9008 final int targetUid;
9011 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9012 this.targetPkg = targetPkg;
9013 this.targetUid = targetUid;
9019 * Like checkGrantUriPermissionLocked, but takes an Intent.
9021 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9022 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9023 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9024 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9025 + " clip=" + (intent != null ? intent.getClipData() : null)
9026 + " from " + intent + "; flags=0x"
9027 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9029 if (targetPkg == null) {
9030 throw new NullPointerException("targetPkg");
9033 if (intent == null) {
9036 Uri data = intent.getData();
9037 ClipData clip = intent.getClipData();
9038 if (data == null && clip == null) {
9041 // Default userId for uris in the intent (if they don't specify it themselves)
9042 int contentUserHint = intent.getContentUserHint();
9043 if (contentUserHint == UserHandle.USER_CURRENT) {
9044 contentUserHint = UserHandle.getUserId(callingUid);
9046 final IPackageManager pm = AppGlobals.getPackageManager();
9048 if (needed != null) {
9049 targetUid = needed.targetUid;
9052 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9054 } catch (RemoteException ex) {
9057 if (targetUid < 0) {
9058 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9059 "Can't grant URI permission no uid for: " + targetPkg
9060 + " on user " + targetUserId);
9065 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9066 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9068 if (targetUid > 0) {
9069 if (needed == null) {
9070 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9072 needed.add(grantUri);
9076 for (int i=0; i<clip.getItemCount(); i++) {
9077 Uri uri = clip.getItemAt(i).getUri();
9079 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9080 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9082 if (targetUid > 0) {
9083 if (needed == null) {
9084 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9086 needed.add(grantUri);
9089 Intent clipIntent = clip.getItemAt(i).getIntent();
9090 if (clipIntent != null) {
9091 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9092 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9093 if (newNeeded != null) {
9105 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9107 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9108 UriPermissionOwner owner) {
9109 if (needed != null) {
9110 for (int i=0; i<needed.size(); i++) {
9111 GrantUri grantUri = needed.get(i);
9112 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9113 grantUri, needed.flags, owner);
9118 void grantUriPermissionFromIntentLocked(int callingUid,
9119 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9120 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9121 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9122 if (needed == null) {
9126 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9130 * @param uri This uri must NOT contain an embedded userId.
9131 * @param userId The userId in which the uri is to be resolved.
9134 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9135 final int modeFlags, int userId) {
9136 enforceNotIsolatedCaller("grantUriPermission");
9137 GrantUri grantUri = new GrantUri(userId, uri, false);
9138 synchronized(this) {
9139 final ProcessRecord r = getRecordForAppLocked(caller);
9141 throw new SecurityException("Unable to find app for caller "
9143 + " when granting permission to uri " + grantUri);
9145 if (targetPkg == null) {
9146 throw new IllegalArgumentException("null target");
9148 if (grantUri == null) {
9149 throw new IllegalArgumentException("null uri");
9152 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9153 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9154 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9155 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9157 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9158 UserHandle.getUserId(r.uid));
9162 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9163 if (perm.modeFlags == 0) {
9164 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9166 if (perms != null) {
9167 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9168 "Removing " + perm.targetUid + " permission to " + perm.uri);
9170 perms.remove(perm.uri);
9171 if (perms.isEmpty()) {
9172 mGrantedUriPermissions.remove(perm.targetUid);
9178 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9179 final int modeFlags) {
9180 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9181 "Revoking all granted permissions to " + grantUri);
9183 final IPackageManager pm = AppGlobals.getPackageManager();
9184 final String authority = grantUri.uri.getAuthority();
9185 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9186 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9188 Slog.w(TAG, "No content provider found for permission revoke: "
9189 + grantUri.toSafeString());
9193 // Does the caller have this permission on the URI?
9194 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9195 // If they don't have direct access to the URI, then revoke any
9196 // ownerless URI permissions that have been granted to them.
9197 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9198 if (perms != null) {
9199 boolean persistChanged = false;
9200 for (int i = perms.size()-1; i >= 0; i--) {
9201 final UriPermission perm = perms.valueAt(i);
9202 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9205 if (perm.uri.sourceUserId == grantUri.sourceUserId
9206 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9207 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9208 "Revoking non-owned " + perm.targetUid
9209 + " permission to " + perm.uri);
9210 persistChanged |= perm.revokeModes(
9211 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9212 if (perm.modeFlags == 0) {
9217 if (perms.isEmpty()) {
9218 mGrantedUriPermissions.remove(callingUid);
9220 if (persistChanged) {
9221 schedulePersistUriGrants();
9227 boolean persistChanged = false;
9229 // Go through all of the permissions and remove any that match.
9230 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9231 final int targetUid = mGrantedUriPermissions.keyAt(i);
9232 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9234 for (int j = perms.size()-1; j >= 0; j--) {
9235 final UriPermission perm = perms.valueAt(j);
9236 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9239 if (perm.uri.sourceUserId == grantUri.sourceUserId
9240 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9241 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9242 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9243 persistChanged |= perm.revokeModes(
9244 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9245 targetPackage == null);
9246 if (perm.modeFlags == 0) {
9252 if (perms.isEmpty()) {
9253 mGrantedUriPermissions.removeAt(i);
9257 if (persistChanged) {
9258 schedulePersistUriGrants();
9263 * @param uri This uri must NOT contain an embedded userId.
9264 * @param userId The userId in which the uri is to be resolved.
9267 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9268 final int modeFlags, int userId) {
9269 enforceNotIsolatedCaller("revokeUriPermission");
9270 synchronized(this) {
9271 final ProcessRecord r = getRecordForAppLocked(caller);
9273 throw new SecurityException("Unable to find app for caller "
9275 + " when revoking permission to uri " + uri);
9278 Slog.w(TAG, "revokeUriPermission: null uri");
9282 if (!Intent.isAccessUriMode(modeFlags)) {
9286 final String authority = uri.getAuthority();
9287 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9288 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9290 Slog.w(TAG, "No content provider found for permission revoke: "
9291 + uri.toSafeString());
9295 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9301 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9304 * @param packageName Package name to match, or {@code null} to apply to all
9306 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9308 * @param persistable If persistable grants should be removed.
9310 private void removeUriPermissionsForPackageLocked(
9311 String packageName, int userHandle, boolean persistable) {
9312 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9313 throw new IllegalArgumentException("Must narrow by either package or user");
9316 boolean persistChanged = false;
9318 int N = mGrantedUriPermissions.size();
9319 for (int i = 0; i < N; i++) {
9320 final int targetUid = mGrantedUriPermissions.keyAt(i);
9321 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9323 // Only inspect grants matching user
9324 if (userHandle == UserHandle.USER_ALL
9325 || userHandle == UserHandle.getUserId(targetUid)) {
9326 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9327 final UriPermission perm = it.next();
9329 // Only inspect grants matching package
9330 if (packageName == null || perm.sourcePkg.equals(packageName)
9331 || perm.targetPkg.equals(packageName)) {
9332 // Hacky solution as part of fixing a security bug; ignore
9333 // grants associated with DownloadManager so we don't have
9334 // to immediately launch it to regrant the permissions
9335 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9336 && !persistable) continue;
9338 persistChanged |= perm.revokeModes(persistable
9339 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9341 // Only remove when no modes remain; any persisted grants
9342 // will keep this alive.
9343 if (perm.modeFlags == 0) {
9349 if (perms.isEmpty()) {
9350 mGrantedUriPermissions.remove(targetUid);
9357 if (persistChanged) {
9358 schedulePersistUriGrants();
9363 public IBinder newUriPermissionOwner(String name) {
9364 enforceNotIsolatedCaller("newUriPermissionOwner");
9365 synchronized(this) {
9366 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9367 return owner.getExternalTokenLocked();
9372 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9373 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9374 synchronized(this) {
9375 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9377 throw new IllegalArgumentException("Activity does not exist; token="
9380 return r.getUriPermissionsLocked().getExternalTokenLocked();
9384 * @param uri This uri must NOT contain an embedded userId.
9385 * @param sourceUserId The userId in which the uri is to be resolved.
9386 * @param targetUserId The userId of the app that receives the grant.
9389 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9390 final int modeFlags, int sourceUserId, int targetUserId) {
9391 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9392 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9393 "grantUriPermissionFromOwner", null);
9394 synchronized(this) {
9395 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9396 if (owner == null) {
9397 throw new IllegalArgumentException("Unknown owner: " + token);
9399 if (fromUid != Binder.getCallingUid()) {
9400 if (Binder.getCallingUid() != myUid()) {
9401 // Only system code can grant URI permissions on behalf
9403 throw new SecurityException("nice try");
9406 if (targetPkg == null) {
9407 throw new IllegalArgumentException("null target");
9410 throw new IllegalArgumentException("null uri");
9413 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9414 modeFlags, owner, targetUserId);
9419 * @param uri This uri must NOT contain an embedded userId.
9420 * @param userId The userId in which the uri is to be resolved.
9423 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9424 synchronized(this) {
9425 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9426 if (owner == null) {
9427 throw new IllegalArgumentException("Unknown owner: " + token);
9431 owner.removeUriPermissionsLocked(mode);
9433 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9434 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9439 private void schedulePersistUriGrants() {
9440 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9441 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9442 10 * DateUtils.SECOND_IN_MILLIS);
9446 private void writeGrantedUriPermissions() {
9447 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9449 // Snapshot permissions so we can persist without lock
9450 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9451 synchronized (this) {
9452 final int size = mGrantedUriPermissions.size();
9453 for (int i = 0; i < size; i++) {
9454 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9455 for (UriPermission perm : perms.values()) {
9456 if (perm.persistedModeFlags != 0) {
9457 persist.add(perm.snapshot());
9463 FileOutputStream fos = null;
9465 fos = mGrantFile.startWrite();
9467 XmlSerializer out = new FastXmlSerializer();
9468 out.setOutput(fos, StandardCharsets.UTF_8.name());
9469 out.startDocument(null, true);
9470 out.startTag(null, TAG_URI_GRANTS);
9471 for (UriPermission.Snapshot perm : persist) {
9472 out.startTag(null, TAG_URI_GRANT);
9473 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9474 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9475 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9476 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9477 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9478 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9479 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9480 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9481 out.endTag(null, TAG_URI_GRANT);
9483 out.endTag(null, TAG_URI_GRANTS);
9486 mGrantFile.finishWrite(fos);
9487 } catch (IOException e) {
9489 mGrantFile.failWrite(fos);
9494 private void readGrantedUriPermissionsLocked() {
9495 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9497 final long now = System.currentTimeMillis();
9499 FileInputStream fis = null;
9501 fis = mGrantFile.openRead();
9502 final XmlPullParser in = Xml.newPullParser();
9503 in.setInput(fis, StandardCharsets.UTF_8.name());
9506 while ((type = in.next()) != END_DOCUMENT) {
9507 final String tag = in.getName();
9508 if (type == START_TAG) {
9509 if (TAG_URI_GRANT.equals(tag)) {
9510 final int sourceUserId;
9511 final int targetUserId;
9512 final int userHandle = readIntAttribute(in,
9513 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9514 if (userHandle != UserHandle.USER_NULL) {
9515 // For backwards compatibility.
9516 sourceUserId = userHandle;
9517 targetUserId = userHandle;
9519 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9520 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9522 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9523 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9524 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9525 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9526 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9527 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9529 // Sanity check that provider still belongs to source package
9530 // Both direct boot aware and unaware packages are fine as we
9531 // will do filtering at query time to avoid multiple parsing.
9532 final ProviderInfo pi = getProviderInfoLocked(
9533 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9534 | MATCH_DIRECT_BOOT_UNAWARE);
9535 if (pi != null && sourcePkg.equals(pi.packageName)) {
9538 targetUid = AppGlobals.getPackageManager().getPackageUid(
9539 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9540 } catch (RemoteException e) {
9542 if (targetUid != -1) {
9543 final UriPermission perm = findOrCreateUriPermissionLocked(
9544 sourcePkg, targetPkg, targetUid,
9545 new GrantUri(sourceUserId, uri, prefix));
9546 perm.initPersistedModes(modeFlags, createdTime);
9549 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9550 + " but instead found " + pi);
9555 } catch (FileNotFoundException e) {
9556 // Missing grants is okay
9557 } catch (IOException e) {
9558 Slog.wtf(TAG, "Failed reading Uri grants", e);
9559 } catch (XmlPullParserException e) {
9560 Slog.wtf(TAG, "Failed reading Uri grants", e);
9562 IoUtils.closeQuietly(fis);
9567 * @param uri This uri must NOT contain an embedded userId.
9568 * @param userId The userId in which the uri is to be resolved.
9571 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9572 enforceNotIsolatedCaller("takePersistableUriPermission");
9574 Preconditions.checkFlagsArgument(modeFlags,
9575 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9577 synchronized (this) {
9578 final int callingUid = Binder.getCallingUid();
9579 boolean persistChanged = false;
9580 GrantUri grantUri = new GrantUri(userId, uri, false);
9582 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9583 new GrantUri(userId, uri, false));
9584 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9585 new GrantUri(userId, uri, true));
9587 final boolean exactValid = (exactPerm != null)
9588 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9589 final boolean prefixValid = (prefixPerm != null)
9590 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9592 if (!(exactValid || prefixValid)) {
9593 throw new SecurityException("No persistable permission grants found for UID "
9594 + callingUid + " and Uri " + grantUri.toSafeString());
9598 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9601 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9604 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9606 if (persistChanged) {
9607 schedulePersistUriGrants();
9613 * @param uri This uri must NOT contain an embedded userId.
9614 * @param userId The userId in which the uri is to be resolved.
9617 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9618 enforceNotIsolatedCaller("releasePersistableUriPermission");
9620 Preconditions.checkFlagsArgument(modeFlags,
9621 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9623 synchronized (this) {
9624 final int callingUid = Binder.getCallingUid();
9625 boolean persistChanged = false;
9627 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9628 new GrantUri(userId, uri, false));
9629 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9630 new GrantUri(userId, uri, true));
9631 if (exactPerm == null && prefixPerm == null) {
9632 throw new SecurityException("No permission grants found for UID " + callingUid
9633 + " and Uri " + uri.toSafeString());
9636 if (exactPerm != null) {
9637 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9638 removeUriPermissionIfNeededLocked(exactPerm);
9640 if (prefixPerm != null) {
9641 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9642 removeUriPermissionIfNeededLocked(prefixPerm);
9645 if (persistChanged) {
9646 schedulePersistUriGrants();
9652 * Prune any older {@link UriPermission} for the given UID until outstanding
9653 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9655 * @return if any mutations occured that require persisting.
9657 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9658 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9659 if (perms == null) return false;
9660 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9662 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9663 for (UriPermission perm : perms.values()) {
9664 if (perm.persistedModeFlags != 0) {
9665 persisted.add(perm);
9669 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9670 if (trimCount <= 0) return false;
9672 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9673 for (int i = 0; i < trimCount; i++) {
9674 final UriPermission perm = persisted.get(i);
9676 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9677 "Trimming grant created at " + perm.persistedCreateTime);
9679 perm.releasePersistableModes(~0);
9680 removeUriPermissionIfNeededLocked(perm);
9687 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9688 String packageName, boolean incoming) {
9689 enforceNotIsolatedCaller("getPersistedUriPermissions");
9690 Preconditions.checkNotNull(packageName, "packageName");
9692 final int callingUid = Binder.getCallingUid();
9693 final int callingUserId = UserHandle.getUserId(callingUid);
9694 final IPackageManager pm = AppGlobals.getPackageManager();
9696 final int packageUid = pm.getPackageUid(packageName,
9697 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9698 if (packageUid != callingUid) {
9699 throw new SecurityException(
9700 "Package " + packageName + " does not belong to calling UID " + callingUid);
9702 } catch (RemoteException e) {
9703 throw new SecurityException("Failed to verify package name ownership");
9706 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9707 synchronized (this) {
9709 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9711 if (perms == null) {
9712 Slog.w(TAG, "No permission grants found for " + packageName);
9714 for (UriPermission perm : perms.values()) {
9715 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9716 result.add(perm.buildPersistedPublicApiObject());
9721 final int size = mGrantedUriPermissions.size();
9722 for (int i = 0; i < size; i++) {
9723 final ArrayMap<GrantUri, UriPermission> perms =
9724 mGrantedUriPermissions.valueAt(i);
9725 for (UriPermission perm : perms.values()) {
9726 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9727 result.add(perm.buildPersistedPublicApiObject());
9733 return new ParceledListSlice<android.content.UriPermission>(result);
9737 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9738 String packageName, int userId) {
9739 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9740 "getGrantedUriPermissions");
9742 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9743 synchronized (this) {
9744 final int size = mGrantedUriPermissions.size();
9745 for (int i = 0; i < size; i++) {
9746 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9747 for (UriPermission perm : perms.values()) {
9748 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9749 && perm.persistedModeFlags != 0) {
9750 result.add(perm.buildPersistedPublicApiObject());
9755 return new ParceledListSlice<android.content.UriPermission>(result);
9759 public void clearGrantedUriPermissions(String packageName, int userId) {
9760 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9761 "clearGrantedUriPermissions");
9762 removeUriPermissionsForPackageLocked(packageName, userId, true);
9766 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9767 synchronized (this) {
9769 who != null ? getRecordForAppLocked(who) : null;
9770 if (app == null) return;
9772 Message msg = Message.obtain();
9773 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9775 msg.arg1 = waiting ? 1 : 0;
9776 mUiHandler.sendMessage(msg);
9781 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9782 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9783 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9784 outInfo.availMem = getFreeMemory();
9785 outInfo.totalMem = getTotalMemory();
9786 outInfo.threshold = homeAppMem;
9787 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9788 outInfo.hiddenAppThreshold = cachedAppMem;
9789 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9790 ProcessList.SERVICE_ADJ);
9791 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9792 ProcessList.VISIBLE_APP_ADJ);
9793 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9794 ProcessList.FOREGROUND_APP_ADJ);
9797 // =========================================================
9799 // =========================================================
9802 public List<IBinder> getAppTasks(String callingPackage) {
9803 int callingUid = Binder.getCallingUid();
9804 long ident = Binder.clearCallingIdentity();
9806 synchronized(this) {
9807 ArrayList<IBinder> list = new ArrayList<IBinder>();
9809 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9811 final int N = mRecentTasks.size();
9812 for (int i = 0; i < N; i++) {
9813 TaskRecord tr = mRecentTasks.get(i);
9814 // Skip tasks that do not match the caller. We don't need to verify
9815 // callingPackage, because we are also limiting to callingUid and know
9816 // that will limit to the correct security sandbox.
9817 if (tr.effectiveUid != callingUid) {
9820 Intent intent = tr.getBaseIntent();
9821 if (intent == null ||
9822 !callingPackage.equals(intent.getComponent().getPackageName())) {
9825 ActivityManager.RecentTaskInfo taskInfo =
9826 createRecentTaskInfoFromTaskRecord(tr);
9827 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9828 list.add(taskImpl.asBinder());
9831 Binder.restoreCallingIdentity(ident);
9838 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9839 final int callingUid = Binder.getCallingUid();
9840 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9842 synchronized(this) {
9843 if (DEBUG_ALL) Slog.v(
9844 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9846 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9849 // TODO: Improve with MRU list from all ActivityStacks.
9850 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9857 * Creates a new RecentTaskInfo from a TaskRecord.
9859 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9860 // Update the task description to reflect any changes in the task stack
9861 tr.updateTaskDescription();
9863 // Compose the recent task info
9864 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9865 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9866 rti.persistentId = tr.taskId;
9867 rti.baseIntent = new Intent(tr.getBaseIntent());
9868 rti.origActivity = tr.origActivity;
9869 rti.realActivity = tr.realActivity;
9870 rti.description = tr.lastDescription;
9871 rti.stackId = tr.getStackId();
9872 rti.userId = tr.userId;
9873 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9874 rti.firstActiveTime = tr.firstActiveTime;
9875 rti.lastActiveTime = tr.lastActiveTime;
9876 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9877 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9878 rti.numActivities = 0;
9879 if (tr.mBounds != null) {
9880 rti.bounds = new Rect(tr.mBounds);
9882 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9883 rti.resizeMode = tr.mResizeMode;
9885 ActivityRecord base = null;
9886 ActivityRecord top = null;
9889 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9890 tmp = tr.mActivities.get(i);
9891 if (tmp.finishing) {
9895 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9898 rti.numActivities++;
9901 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9902 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9907 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9908 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9909 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9911 if (checkPermission(android.Manifest.permission.GET_TASKS,
9912 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9913 // Temporary compatibility: some existing apps on the system image may
9914 // still be requesting the old permission and not switched to the new
9915 // one; if so, we'll still allow them full access. This means we need
9916 // to see if they are holding the old permission and are a system app.
9918 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9920 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9921 + " is using old GET_TASKS but privileged; allowing");
9923 } catch (RemoteException e) {
9928 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9929 + " does not hold REAL_GET_TASKS; limiting output");
9935 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9937 final int callingUid = Binder.getCallingUid();
9938 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9939 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9941 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9942 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9943 synchronized (this) {
9944 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9946 final boolean detailed = checkCallingPermission(
9947 android.Manifest.permission.GET_DETAILED_TASKS)
9948 == PackageManager.PERMISSION_GRANTED;
9950 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9951 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9952 return ParceledListSlice.emptyList();
9954 mRecentTasks.loadUserRecentsLocked(userId);
9956 final int recentsCount = mRecentTasks.size();
9957 ArrayList<ActivityManager.RecentTaskInfo> res =
9958 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9960 final Set<Integer> includedUsers;
9961 if (includeProfiles) {
9962 includedUsers = mUserController.getProfileIds(userId);
9964 includedUsers = new HashSet<>();
9966 includedUsers.add(Integer.valueOf(userId));
9968 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9969 TaskRecord tr = mRecentTasks.get(i);
9970 // Only add calling user or related users recent tasks
9971 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9972 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9976 if (tr.realActivitySuspended) {
9977 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9981 // Return the entry if desired by the caller. We always return
9982 // the first entry, because callers always expect this to be the
9983 // foreground app. We may filter others if the caller has
9984 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9985 // we should exclude the entry.
9989 || (tr.intent == null)
9990 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9993 // If the caller doesn't have the GET_TASKS permission, then only
9994 // allow them to see a small subset of tasks -- their own and home.
9995 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9996 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
10000 final ActivityStack stack = tr.getStack();
10001 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
10002 if (stack != null && stack.isHomeOrRecentsStack()) {
10003 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10004 "Skipping, home or recents stack task: " + tr);
10008 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10009 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10010 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10011 "Skipping, top task in docked stack: " + tr);
10015 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10016 if (stack != null && stack.isPinnedStack()) {
10017 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10018 "Skipping, pinned stack task: " + tr);
10022 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10023 // Don't include auto remove tasks that are finished or finishing.
10024 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10025 "Skipping, auto-remove without activity: " + tr);
10028 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10029 && !tr.isAvailable) {
10030 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10031 "Skipping, unavail real act: " + tr);
10035 if (!tr.mUserSetupComplete) {
10036 // Don't include task launched while user is not done setting-up.
10037 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10038 "Skipping, user setup not complete: " + tr);
10042 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10044 rti.baseIntent.replaceExtras((Bundle)null);
10051 return new ParceledListSlice<>(res);
10056 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10057 synchronized (this) {
10058 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10059 "getTaskThumbnail()");
10060 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10061 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10063 return tr.getTaskThumbnailLocked();
10070 public ActivityManager.TaskDescription getTaskDescription(int id) {
10071 synchronized (this) {
10072 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10073 "getTaskDescription()");
10074 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10075 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10077 return tr.lastTaskDescription;
10084 public int addAppTask(IBinder activityToken, Intent intent,
10085 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10086 final int callingUid = Binder.getCallingUid();
10087 final long callingIdent = Binder.clearCallingIdentity();
10090 synchronized (this) {
10091 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10093 throw new IllegalArgumentException("Activity does not exist; token="
10096 ComponentName comp = intent.getComponent();
10097 if (comp == null) {
10098 throw new IllegalArgumentException("Intent " + intent
10099 + " must specify explicit component");
10101 if (thumbnail.getWidth() != mThumbnailWidth
10102 || thumbnail.getHeight() != mThumbnailHeight) {
10103 throw new IllegalArgumentException("Bad thumbnail size: got "
10104 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10105 + mThumbnailWidth + "x" + mThumbnailHeight);
10107 if (intent.getSelector() != null) {
10108 intent.setSelector(null);
10110 if (intent.getSourceBounds() != null) {
10111 intent.setSourceBounds(null);
10113 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10114 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10115 // The caller has added this as an auto-remove task... that makes no
10116 // sense, so turn off auto-remove.
10117 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10120 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10121 mLastAddedTaskActivity = null;
10123 ActivityInfo ainfo = mLastAddedTaskActivity;
10124 if (ainfo == null) {
10125 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10126 comp, 0, UserHandle.getUserId(callingUid));
10127 if (ainfo.applicationInfo.uid != callingUid) {
10128 throw new SecurityException(
10129 "Can't add task for another application: target uid="
10130 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10134 TaskRecord task = new TaskRecord(this,
10135 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10136 ainfo, intent, description, new TaskThumbnailInfo());
10138 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10139 if (trimIdx >= 0) {
10140 // If this would have caused a trim, then we'll abort because that
10141 // means it would be added at the end of the list but then just removed.
10142 return INVALID_TASK_ID;
10145 final int N = mRecentTasks.size();
10146 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10147 final TaskRecord tr = mRecentTasks.remove(N - 1);
10148 tr.removedFromRecents();
10151 task.inRecents = true;
10152 mRecentTasks.add(task);
10153 r.getStack().addTask(task, false, "addAppTask");
10155 task.setLastThumbnailLocked(thumbnail);
10156 task.freeLastThumbnail();
10157 return task.taskId;
10160 Binder.restoreCallingIdentity(callingIdent);
10165 public Point getAppTaskThumbnailSize() {
10166 synchronized (this) {
10167 return new Point(mThumbnailWidth, mThumbnailHeight);
10172 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10173 synchronized (this) {
10174 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10176 r.setTaskDescription(td);
10177 final TaskRecord task = r.getTask();
10178 task.updateTaskDescription();
10179 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10185 public void setTaskResizeable(int taskId, int resizeableMode) {
10186 synchronized (this) {
10187 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10188 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10189 if (task == null) {
10190 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10193 task.setResizeMode(resizeableMode);
10198 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10199 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10200 long ident = Binder.clearCallingIdentity();
10202 synchronized (this) {
10203 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10204 if (task == null) {
10205 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10208 // Place the task in the right stack if it isn't there already based on
10209 // the requested bounds.
10210 // The stack transition logic is:
10211 // - a null bounds on a freeform task moves that task to fullscreen
10212 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10213 // that task to freeform
10214 // - otherwise the task is not moved
10215 int stackId = task.getStackId();
10216 if (!StackId.isTaskResizeAllowed(stackId)) {
10217 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10219 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10220 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10221 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10222 stackId = FREEFORM_WORKSPACE_STACK_ID;
10225 // Reparent the task to the right stack if necessary
10226 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10227 if (stackId != task.getStackId()) {
10228 // Defer resume until the task is resized below
10229 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10230 DEFER_RESUME, "resizeTask");
10231 preserveWindow = false;
10234 // After reparenting (which only resizes the task to the stack bounds), resize the
10235 // task to the actual bounds provided
10236 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10239 Binder.restoreCallingIdentity(ident);
10244 public Rect getTaskBounds(int taskId) {
10245 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10246 long ident = Binder.clearCallingIdentity();
10247 Rect rect = new Rect();
10249 synchronized (this) {
10250 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10251 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10252 if (task == null) {
10253 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10256 if (task.getStack() != null) {
10257 // Return the bounds from window manager since it will be adjusted for various
10258 // things like the presense of a docked stack for tasks that aren't resizeable.
10259 task.getWindowContainerBounds(rect);
10261 // Task isn't in window manager yet since it isn't associated with a stack.
10262 // Return the persist value from activity manager
10263 if (task.mBounds != null) {
10264 rect.set(task.mBounds);
10265 } else if (task.mLastNonFullscreenBounds != null) {
10266 rect.set(task.mLastNonFullscreenBounds);
10271 Binder.restoreCallingIdentity(ident);
10277 public void cancelTaskWindowTransition(int taskId) {
10278 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10279 final long ident = Binder.clearCallingIdentity();
10281 synchronized (this) {
10282 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10283 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10284 if (task == null) {
10285 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10288 task.cancelWindowTransition();
10291 Binder.restoreCallingIdentity(ident);
10296 public void cancelTaskThumbnailTransition(int taskId) {
10297 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10298 final long ident = Binder.clearCallingIdentity();
10300 synchronized (this) {
10301 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10302 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10303 if (task == null) {
10304 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10307 task.cancelThumbnailTransition();
10310 Binder.restoreCallingIdentity(ident);
10315 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10316 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10317 final long ident = Binder.clearCallingIdentity();
10319 final TaskRecord task;
10320 synchronized (this) {
10321 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10322 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10323 if (task == null) {
10324 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10328 // Don't call this while holding the lock as this operation might hit the disk.
10329 return task.getSnapshot(reducedResolution);
10331 Binder.restoreCallingIdentity(ident);
10336 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10337 if (userId != UserHandle.getCallingUserId()) {
10338 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10339 "getTaskDescriptionIcon");
10341 final File passedIconFile = new File(filePath);
10342 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10343 passedIconFile.getName());
10344 if (!legitIconFile.getPath().equals(filePath)
10345 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10346 throw new IllegalArgumentException("Bad file path: " + filePath
10347 + " passed for userId " + userId);
10349 return mRecentTasks.getTaskDescriptionIcon(filePath);
10353 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10354 throws RemoteException {
10355 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10356 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10357 activityOptions.getCustomInPlaceResId() == 0) {
10358 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10359 "with valid animation");
10361 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10362 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10363 activityOptions.getCustomInPlaceResId());
10364 mWindowManager.executeAppTransition();
10367 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10368 // Remove all tasks with activities in the specified package from the list of recent tasks
10369 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10370 TaskRecord tr = mRecentTasks.get(i);
10371 if (tr.userId != userId) continue;
10373 ComponentName cn = tr.intent.getComponent();
10374 if (cn != null && cn.getPackageName().equals(packageName)) {
10375 // If the package name matches, remove the task.
10376 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10381 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10384 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10385 TaskRecord tr = mRecentTasks.get(i);
10386 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10390 ComponentName cn = tr.intent.getComponent();
10391 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10392 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10393 if (sameComponent) {
10394 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10400 public void removeStack(int stackId) {
10401 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10402 if (StackId.isHomeOrRecentsStack(stackId)) {
10403 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10406 synchronized (this) {
10407 final long ident = Binder.clearCallingIdentity();
10409 mStackSupervisor.removeStackLocked(stackId);
10411 Binder.restoreCallingIdentity(ident);
10417 public void moveStackToDisplay(int stackId, int displayId) {
10418 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10420 synchronized (this) {
10421 final long ident = Binder.clearCallingIdentity();
10423 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10424 + " to displayId=" + displayId);
10425 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10427 Binder.restoreCallingIdentity(ident);
10433 public boolean removeTask(int taskId) {
10434 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10435 synchronized (this) {
10436 final long ident = Binder.clearCallingIdentity();
10438 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10440 Binder.restoreCallingIdentity(ident);
10446 * TODO: Add mController hook
10449 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10450 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10452 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10453 synchronized(this) {
10454 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10458 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10459 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10461 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10462 Binder.getCallingUid(), -1, -1, "Task to front")) {
10463 ActivityOptions.abort(options);
10466 final long origId = Binder.clearCallingIdentity();
10468 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10469 if (task == null) {
10470 Slog.d(TAG, "Could not find task for id: "+ taskId);
10473 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10474 mStackSupervisor.showLockTaskToast();
10475 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10478 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10479 if (prev != null) {
10480 task.setTaskToReturnTo(prev);
10482 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10483 false /* forceNonResizable */);
10485 final ActivityRecord topActivity = task.getTopActivity();
10486 if (topActivity != null) {
10488 // We are reshowing a task, use a starting window to hide the initial draw delay
10489 // so the transition can start earlier.
10490 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10491 true /* taskSwitch */, fromRecents);
10494 Binder.restoreCallingIdentity(origId);
10496 ActivityOptions.abort(options);
10500 * Attempts to move a task backwards in z-order (the order of activities within the task is
10503 * There are several possible results of this call:
10504 * - if the task is locked, then we will show the lock toast
10505 * - if there is a task behind the provided task, then that task is made visible and resumed as
10506 * this task is moved to the back
10507 * - otherwise, if there are no other tasks in the stack:
10508 * - if this task is in the pinned stack, then we remove the stack completely, which will
10509 * have the effect of moving the task to the top or bottom of the fullscreen stack
10510 * (depending on whether it is visible)
10511 * - otherwise, we simply return home and hide this task
10513 * @param token A reference to the activity we wish to move
10514 * @param nonRoot If false then this only works if the activity is the root
10515 * of a task; if true it will work for any activity in a task.
10516 * @return Returns true if the move completed, false if not.
10519 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10520 enforceNotIsolatedCaller("moveActivityTaskToBack");
10521 synchronized(this) {
10522 final long origId = Binder.clearCallingIdentity();
10524 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10525 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10526 if (task != null) {
10527 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10530 Binder.restoreCallingIdentity(origId);
10537 public void moveTaskBackwards(int task) {
10538 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10539 "moveTaskBackwards()");
10541 synchronized(this) {
10542 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10543 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10546 final long origId = Binder.clearCallingIdentity();
10547 moveTaskBackwardsLocked(task);
10548 Binder.restoreCallingIdentity(origId);
10552 private final void moveTaskBackwardsLocked(int task) {
10553 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10557 public int createStackOnDisplay(int displayId) throws RemoteException {
10558 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10559 synchronized (this) {
10560 final int stackId = mStackSupervisor.getNextStackId();
10561 final ActivityStack stack =
10562 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10563 if (stack == null) {
10564 return INVALID_STACK_ID;
10566 return stack.mStackId;
10571 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10572 synchronized (this) {
10573 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10574 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10575 return stack.mDisplayId;
10577 return DEFAULT_DISPLAY;
10582 public int getActivityStackId(IBinder token) throws RemoteException {
10583 synchronized (this) {
10584 ActivityStack stack = ActivityRecord.getStackLocked(token);
10585 if (stack == null) {
10586 return INVALID_STACK_ID;
10588 return stack.mStackId;
10593 public void exitFreeformMode(IBinder token) throws RemoteException {
10594 synchronized (this) {
10595 long ident = Binder.clearCallingIdentity();
10597 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10599 throw new IllegalArgumentException(
10600 "exitFreeformMode: No activity record matching token=" + token);
10603 final ActivityStack stack = r.getStack();
10604 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10605 throw new IllegalStateException(
10606 "exitFreeformMode: You can only go fullscreen from freeform.");
10609 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10610 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10611 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10613 Binder.restoreCallingIdentity(ident);
10619 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10620 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10621 if (StackId.isHomeOrRecentsStack(stackId)) {
10622 throw new IllegalArgumentException(
10623 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10625 synchronized (this) {
10626 long ident = Binder.clearCallingIdentity();
10628 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10629 if (task == null) {
10630 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10634 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10635 + " to stackId=" + stackId + " toTop=" + toTop);
10636 if (stackId == DOCKED_STACK_ID) {
10637 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10638 null /* initialBounds */);
10640 task.reparent(stackId, toTop,
10641 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10643 Binder.restoreCallingIdentity(ident);
10649 public void swapDockedAndFullscreenStack() throws RemoteException {
10650 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10651 synchronized (this) {
10652 long ident = Binder.clearCallingIdentity();
10654 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10655 FULLSCREEN_WORKSPACE_STACK_ID);
10656 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10658 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10659 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10661 if (topTask == null || tasks == null || tasks.size() == 0) {
10663 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10667 // TODO: App transition
10668 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10670 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10671 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10672 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10673 final int size = tasks.size();
10674 for (int i = 0; i < size; i++) {
10675 final int id = tasks.get(i).taskId;
10676 if (id == topTask.taskId) {
10680 // Defer the resume until after all the tasks have been moved
10681 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10682 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10683 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10686 // Because we deferred the resume to avoid conflicts with stack switches while
10687 // resuming, we need to do it after all the tasks are moved.
10688 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10689 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10691 mWindowManager.executeAppTransition();
10693 Binder.restoreCallingIdentity(ident);
10699 * Moves the input task to the docked stack.
10701 * @param taskId Id of task to move.
10702 * @param createMode The mode the docked stack should be created in if it doesn't exist
10704 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10706 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10707 * @param toTop If the task and stack should be moved to the top.
10708 * @param animate Whether we should play an animation for the moving the task
10709 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10710 * docked stack. Pass {@code null} to use default bounds.
10713 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10714 Rect initialBounds) {
10715 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10716 synchronized (this) {
10717 long ident = Binder.clearCallingIdentity();
10719 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10720 if (task == null) {
10721 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10725 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10726 + " to createMode=" + createMode + " toTop=" + toTop);
10727 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10729 // Defer resuming until we move the home stack to the front below
10730 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10731 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10732 "moveTaskToDockedStack");
10734 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10738 Binder.restoreCallingIdentity(ident);
10744 * Moves the top activity in the input stackId to the pinned stack.
10746 * @param stackId Id of stack to move the top activity to pinned stack.
10747 * @param bounds Bounds to use for pinned stack.
10749 * @return True if the top activity of the input stack was successfully moved to the pinned
10753 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10754 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10755 synchronized (this) {
10756 if (!mSupportsPictureInPicture) {
10757 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10758 + "Device doesn't support picture-in-picture mode");
10761 long ident = Binder.clearCallingIdentity();
10763 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10765 Binder.restoreCallingIdentity(ident);
10771 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10772 boolean preserveWindows, boolean animate, int animationDuration) {
10773 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10774 long ident = Binder.clearCallingIdentity();
10776 synchronized (this) {
10778 if (stackId == PINNED_STACK_ID) {
10779 final PinnedActivityStack pinnedStack =
10780 mStackSupervisor.getStack(PINNED_STACK_ID);
10781 if (pinnedStack != null) {
10782 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10783 destBounds, animationDuration, false /* fromFullscreen */);
10786 throw new IllegalArgumentException("Stack: " + stackId
10787 + " doesn't support animated resize.");
10790 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10791 null /* tempTaskInsetBounds */, preserveWindows,
10792 allowResizeInDockedMode, !DEFER_RESUME);
10796 Binder.restoreCallingIdentity(ident);
10801 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10802 Rect tempDockedTaskInsetBounds,
10803 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10804 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10805 "resizeDockedStack()");
10806 long ident = Binder.clearCallingIdentity();
10808 synchronized (this) {
10809 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10810 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10814 Binder.restoreCallingIdentity(ident);
10819 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10820 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10821 "resizePinnedStack()");
10822 final long ident = Binder.clearCallingIdentity();
10824 synchronized (this) {
10825 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10828 Binder.restoreCallingIdentity(ident);
10833 * Try to place task to provided position. The final position might be different depending on
10834 * current user and stacks state. The task will be moved to target stack if it's currently in
10838 public void positionTaskInStack(int taskId, int stackId, int position) {
10839 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10840 if (StackId.isHomeOrRecentsStack(stackId)) {
10841 throw new IllegalArgumentException(
10842 "positionTaskInStack: Attempt to change the position of task "
10843 + taskId + " in/to home/recents stack");
10845 synchronized (this) {
10846 long ident = Binder.clearCallingIdentity();
10848 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10849 + taskId + " in stackId=" + stackId + " at position=" + position);
10850 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10851 if (task == null) {
10852 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10856 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10859 // TODO: Have the callers of this API call a separate reparent method if that is
10860 // what they intended to do vs. having this method also do reparenting.
10861 if (task.getStack() == stack) {
10862 // Change position in current stack.
10863 stack.positionChildAt(task, position);
10865 // Reparent to new stack.
10866 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10867 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10870 Binder.restoreCallingIdentity(ident);
10876 public List<StackInfo> getAllStackInfos() {
10877 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10878 long ident = Binder.clearCallingIdentity();
10880 synchronized (this) {
10881 return mStackSupervisor.getAllStackInfosLocked();
10884 Binder.restoreCallingIdentity(ident);
10889 public StackInfo getStackInfo(int stackId) {
10890 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10891 long ident = Binder.clearCallingIdentity();
10893 synchronized (this) {
10894 return mStackSupervisor.getStackInfoLocked(stackId);
10897 Binder.restoreCallingIdentity(ident);
10902 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10903 synchronized(this) {
10904 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10909 public void updateDeviceOwner(String packageName) {
10910 final int callingUid = Binder.getCallingUid();
10911 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10912 throw new SecurityException("updateDeviceOwner called from non-system process");
10914 synchronized (this) {
10915 mDeviceOwnerName = packageName;
10920 public void updateLockTaskPackages(int userId, String[] packages) {
10921 final int callingUid = Binder.getCallingUid();
10922 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10923 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10924 "updateLockTaskPackages()");
10926 synchronized (this) {
10927 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10928 Arrays.toString(packages));
10929 mLockTaskPackages.put(userId, packages);
10930 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10935 void startLockTaskModeLocked(TaskRecord task) {
10936 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10937 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10941 // When a task is locked, dismiss the pinned stack if it exists
10942 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10944 if (pinnedStack != null) {
10945 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10948 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10949 // is initiated by system after the pinning request was shown and locked mode is initiated
10950 // by an authorized app directly
10951 final int callingUid = Binder.getCallingUid();
10952 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10953 long ident = Binder.clearCallingIdentity();
10955 if (!isSystemInitiated) {
10956 task.mLockTaskUid = callingUid;
10957 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10958 // startLockTask() called by app and task mode is lockTaskModeDefault.
10959 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10960 StatusBarManagerInternal statusBarManager =
10961 LocalServices.getService(StatusBarManagerInternal.class);
10962 if (statusBarManager != null) {
10963 statusBarManager.showScreenPinningRequest(task.taskId);
10968 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10969 if (stack == null || task != stack.topTask()) {
10970 throw new IllegalArgumentException("Invalid task, not in foreground");
10973 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10975 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10976 ActivityManager.LOCK_TASK_MODE_PINNED :
10977 ActivityManager.LOCK_TASK_MODE_LOCKED,
10978 "startLockTask", true);
10980 Binder.restoreCallingIdentity(ident);
10985 public void startLockTaskModeById(int taskId) {
10986 synchronized (this) {
10987 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10988 if (task != null) {
10989 startLockTaskModeLocked(task);
10995 public void startLockTaskModeByToken(IBinder token) {
10996 synchronized (this) {
10997 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11001 final TaskRecord task = r.getTask();
11002 if (task != null) {
11003 startLockTaskModeLocked(task);
11009 public void startSystemLockTaskMode(int taskId) throws RemoteException {
11010 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11011 // This makes inner call to look as if it was initiated by system.
11012 long ident = Binder.clearCallingIdentity();
11014 synchronized (this) {
11015 startLockTaskModeById(taskId);
11018 Binder.restoreCallingIdentity(ident);
11023 public void stopLockTaskMode() {
11024 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11025 if (lockTask == null) {
11026 // Our work here is done.
11030 final int callingUid = Binder.getCallingUid();
11031 final int lockTaskUid = lockTask.mLockTaskUid;
11032 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11033 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11037 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11038 // It is possible lockTaskMode was started by the system process because
11039 // android:lockTaskMode is set to a locking value in the application manifest
11040 // instead of the app calling startLockTaskMode. In this case
11041 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11042 // {@link TaskRecord.effectiveUid} instead. Also caller with
11043 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11044 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11045 && callingUid != lockTaskUid
11046 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11047 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11048 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11051 long ident = Binder.clearCallingIdentity();
11053 Log.d(TAG, "stopLockTaskMode");
11055 synchronized (this) {
11056 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11057 "stopLockTask", true);
11059 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11061 tm.showInCallScreen(false);
11064 Binder.restoreCallingIdentity(ident);
11069 * This API should be called by SystemUI only when user perform certain action to dismiss
11070 * lock task mode. We should only dismiss pinned lock task mode in this case.
11073 public void stopSystemLockTaskMode() throws RemoteException {
11074 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11075 stopLockTaskMode();
11077 mStackSupervisor.showLockTaskToast();
11082 public boolean isInLockTaskMode() {
11083 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11087 public int getLockTaskModeState() {
11088 synchronized (this) {
11089 return mStackSupervisor.getLockTaskModeState();
11094 public void showLockTaskEscapeMessage(IBinder token) {
11095 synchronized (this) {
11096 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11100 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11105 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11106 throws RemoteException {
11107 synchronized (this) {
11108 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11110 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11114 final long origId = Binder.clearCallingIdentity();
11116 r.setDisablePreviewScreenshots(disable);
11118 Binder.restoreCallingIdentity(origId);
11123 // =========================================================
11124 // CONTENT PROVIDERS
11125 // =========================================================
11127 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11128 List<ProviderInfo> providers = null;
11130 providers = AppGlobals.getPackageManager()
11131 .queryContentProviders(app.processName, app.uid,
11132 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11133 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11135 } catch (RemoteException ex) {
11137 if (DEBUG_MU) Slog.v(TAG_MU,
11138 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11139 int userId = app.userId;
11140 if (providers != null) {
11141 int N = providers.size();
11142 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11143 for (int i=0; i<N; i++) {
11144 // TODO: keep logic in sync with installEncryptionUnawareProviders
11146 (ProviderInfo)providers.get(i);
11147 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11148 cpi.name, cpi.flags);
11149 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11150 // This is a singleton provider, but a user besides the
11151 // default user is asking to initialize a process it runs
11152 // in... well, no, it doesn't actually run in this process,
11153 // it runs in the process of the default user. Get rid of it.
11154 providers.remove(i);
11160 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11161 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11163 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11164 mProviderMap.putProviderByClass(comp, cpr);
11166 if (DEBUG_MU) Slog.v(TAG_MU,
11167 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11168 app.pubProviders.put(cpi.name, cpr);
11169 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11170 // Don't add this if it is a platform component that is marked
11171 // to run in multiple processes, because this is actually
11172 // part of the framework so doesn't make sense to track as a
11173 // separate apk in the process.
11174 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11177 notifyPackageUse(cpi.applicationInfo.packageName,
11178 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11185 * Check if the calling UID has a possible chance at accessing the provider
11186 * at the given authority and user.
11188 public String checkContentProviderAccess(String authority, int userId) {
11189 if (userId == UserHandle.USER_ALL) {
11190 mContext.enforceCallingOrSelfPermission(
11191 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11192 userId = UserHandle.getCallingUserId();
11195 ProviderInfo cpi = null;
11197 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11198 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11199 | PackageManager.MATCH_DISABLED_COMPONENTS
11200 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11201 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11203 } catch (RemoteException ignored) {
11206 return "Failed to find provider " + authority + " for user " + userId
11207 + "; expected to find a valid ContentProvider for this authority";
11210 ProcessRecord r = null;
11211 synchronized (mPidsSelfLocked) {
11212 r = mPidsSelfLocked.get(Binder.getCallingPid());
11215 return "Failed to find PID " + Binder.getCallingPid();
11218 synchronized (this) {
11219 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11224 * Check if {@link ProcessRecord} has a possible chance at accessing the
11225 * given {@link ProviderInfo}. Final permission checking is always done
11226 * in {@link ContentProvider}.
11228 private final String checkContentProviderPermissionLocked(
11229 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11230 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11231 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11232 boolean checkedGrants = false;
11234 // Looking for cross-user grants before enforcing the typical cross-users permissions
11235 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11236 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11237 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11240 checkedGrants = true;
11242 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11243 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11244 if (userId != tmpTargetUserId) {
11245 // When we actually went to determine the final targer user ID, this ended
11246 // up different than our initial check for the authority. This is because
11247 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11248 // SELF. So we need to re-check the grants again.
11249 checkedGrants = false;
11252 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11253 cpi.applicationInfo.uid, cpi.exported)
11254 == PackageManager.PERMISSION_GRANTED) {
11257 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11258 cpi.applicationInfo.uid, cpi.exported)
11259 == PackageManager.PERMISSION_GRANTED) {
11263 PathPermission[] pps = cpi.pathPermissions;
11265 int i = pps.length;
11268 PathPermission pp = pps[i];
11269 String pprperm = pp.getReadPermission();
11270 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11271 cpi.applicationInfo.uid, cpi.exported)
11272 == PackageManager.PERMISSION_GRANTED) {
11275 String ppwperm = pp.getWritePermission();
11276 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11277 cpi.applicationInfo.uid, cpi.exported)
11278 == PackageManager.PERMISSION_GRANTED) {
11283 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11287 final String suffix;
11288 if (!cpi.exported) {
11289 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11290 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11291 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11293 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11295 final String msg = "Permission Denial: opening provider " + cpi.name
11296 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11297 + ", uid=" + callingUid + ")" + suffix;
11303 * Returns if the ContentProvider has granted a uri to callingUid
11305 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11306 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11307 if (perms != null) {
11308 for (int i=perms.size()-1; i>=0; i--) {
11309 GrantUri grantUri = perms.keyAt(i);
11310 if (grantUri.sourceUserId == userId || !checkUser) {
11311 if (matchesProvider(grantUri.uri, cpi)) {
11321 * Returns true if the uri authority is one of the authorities specified in the provider.
11323 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11324 String uriAuth = uri.getAuthority();
11325 String cpiAuth = cpi.authority;
11326 if (cpiAuth.indexOf(';') == -1) {
11327 return cpiAuth.equals(uriAuth);
11329 String[] cpiAuths = cpiAuth.split(";");
11330 int length = cpiAuths.length;
11331 for (int i = 0; i < length; i++) {
11332 if (cpiAuths[i].equals(uriAuth)) return true;
11337 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11338 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11340 for (int i=0; i<r.conProviders.size(); i++) {
11341 ContentProviderConnection conn = r.conProviders.get(i);
11342 if (conn.provider == cpr) {
11343 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11344 "Adding provider requested by "
11345 + r.processName + " from process "
11346 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11347 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11349 conn.stableCount++;
11350 conn.numStableIncs++;
11352 conn.unstableCount++;
11353 conn.numUnstableIncs++;
11358 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11360 conn.stableCount = 1;
11361 conn.numStableIncs = 1;
11363 conn.unstableCount = 1;
11364 conn.numUnstableIncs = 1;
11366 cpr.connections.add(conn);
11367 r.conProviders.add(conn);
11368 startAssociationLocked(r.uid, r.processName, r.curProcState,
11369 cpr.uid, cpr.name, cpr.info.processName);
11372 cpr.addExternalProcessHandleLocked(externalProcessToken);
11376 boolean decProviderCountLocked(ContentProviderConnection conn,
11377 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11378 if (conn != null) {
11379 cpr = conn.provider;
11380 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11381 "Removing provider requested by "
11382 + conn.client.processName + " from process "
11383 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11384 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11386 conn.stableCount--;
11388 conn.unstableCount--;
11390 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11391 cpr.connections.remove(conn);
11392 conn.client.conProviders.remove(conn);
11393 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11394 // The client is more important than last activity -- note the time this
11395 // is happening, so we keep the old provider process around a bit as last
11396 // activity to avoid thrashing it.
11397 if (cpr.proc != null) {
11398 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11401 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11406 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11410 private void checkTime(long startTime, String where) {
11411 long now = SystemClock.uptimeMillis();
11412 if ((now-startTime) > 50) {
11413 // If we are taking more than 50ms, log about it.
11414 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11418 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11420 PROC_SPACE_TERM|PROC_PARENS,
11421 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11424 private final long[] mProcessStateStatsLongs = new long[1];
11426 boolean isProcessAliveLocked(ProcessRecord proc) {
11427 if (proc.procStatFile == null) {
11428 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11430 mProcessStateStatsLongs[0] = 0;
11431 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11432 mProcessStateStatsLongs, null)) {
11433 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11436 final long state = mProcessStateStatsLongs[0];
11437 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11439 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11442 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11443 String name, IBinder token, boolean stable, int userId) {
11444 ContentProviderRecord cpr;
11445 ContentProviderConnection conn = null;
11446 ProviderInfo cpi = null;
11448 synchronized(this) {
11449 long startTime = SystemClock.uptimeMillis();
11451 ProcessRecord r = null;
11452 if (caller != null) {
11453 r = getRecordForAppLocked(caller);
11455 throw new SecurityException(
11456 "Unable to find app for caller " + caller
11457 + " (pid=" + Binder.getCallingPid()
11458 + ") when getting content provider " + name);
11462 boolean checkCrossUser = true;
11464 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11466 // First check if this content provider has been published...
11467 cpr = mProviderMap.getProviderByName(name, userId);
11468 // If that didn't work, check if it exists for user 0 and then
11469 // verify that it's a singleton provider before using it.
11470 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11471 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11474 if (isSingleton(cpi.processName, cpi.applicationInfo,
11475 cpi.name, cpi.flags)
11476 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11477 userId = UserHandle.USER_SYSTEM;
11478 checkCrossUser = false;
11486 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11487 if (providerRunning) {
11490 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11491 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11493 throw new SecurityException(msg);
11495 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11497 if (r != null && cpr.canRunHere(r)) {
11498 // This provider has been published or is in the process
11499 // of being published... but it is also allowed to run
11500 // in the caller's process, so don't make a connection
11501 // and just let the caller instantiate its own instance.
11502 ContentProviderHolder holder = cpr.newHolder(null);
11503 // don't give caller the provider object, it needs
11504 // to make its own.
11505 holder.provider = null;
11508 // Don't expose providers between normal apps and instant apps
11510 if (AppGlobals.getPackageManager()
11511 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11514 } catch (RemoteException e) {
11517 final long origId = Binder.clearCallingIdentity();
11519 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11521 // In this case the provider instance already exists, so we can
11522 // return it right away.
11523 conn = incProviderCountLocked(r, cpr, token, stable);
11524 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11525 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11526 // If this is a perceptible app accessing the provider,
11527 // make sure to count it as being accessed and thus
11528 // back up on the LRU list. This is good because
11529 // content providers are often expensive to start.
11530 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11531 updateLruProcessLocked(cpr.proc, false, null);
11532 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11536 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11537 final int verifiedAdj = cpr.proc.verifiedAdj;
11538 boolean success = updateOomAdjLocked(cpr.proc, true);
11539 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11540 // if the process has been successfully adjusted. So to reduce races with
11541 // it, we will check whether the process still exists. Note that this doesn't
11542 // completely get rid of races with LMK killing the process, but should make
11543 // them much smaller.
11544 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11547 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11548 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11549 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11550 // NOTE: there is still a race here where a signal could be
11551 // pending on the process even though we managed to update its
11552 // adj level. Not sure what to do about this, but at least
11553 // the race is now smaller.
11555 // Uh oh... it looks like the provider's process
11556 // has been killed on us. We need to wait for a new
11557 // process to be started, and make sure its death
11558 // doesn't kill our process.
11559 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11560 + " is crashing; detaching " + r);
11561 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11562 checkTime(startTime, "getContentProviderImpl: before appDied");
11563 appDiedLocked(cpr.proc);
11564 checkTime(startTime, "getContentProviderImpl: after appDied");
11566 // This wasn't the last ref our process had on
11567 // the provider... we have now been killed, bail.
11570 providerRunning = false;
11573 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11576 Binder.restoreCallingIdentity(origId);
11579 if (!providerRunning) {
11581 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11582 cpi = AppGlobals.getPackageManager().
11583 resolveContentProvider(name,
11584 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11585 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11586 } catch (RemoteException ex) {
11591 // If the provider is a singleton AND
11592 // (it's a call within the same user || the provider is a
11594 // Then allow connecting to the singleton provider
11595 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11596 cpi.name, cpi.flags)
11597 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11599 userId = UserHandle.USER_SYSTEM;
11601 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11602 checkTime(startTime, "getContentProviderImpl: got app info for user");
11605 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11606 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11608 throw new SecurityException(msg);
11610 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11612 if (!mProcessesReady
11613 && !cpi.processName.equals("system")) {
11614 // If this content provider does not run in the system
11615 // process, and the system is not yet ready to run other
11616 // processes, then fail fast instead of hanging.
11617 throw new IllegalArgumentException(
11618 "Attempt to launch content provider before system ready");
11621 // Make sure that the user who owns this provider is running. If not,
11622 // we don't want to allow it to run.
11623 if (!mUserController.isUserRunningLocked(userId, 0)) {
11624 Slog.w(TAG, "Unable to launch app "
11625 + cpi.applicationInfo.packageName + "/"
11626 + cpi.applicationInfo.uid + " for provider "
11627 + name + ": user " + userId + " is stopped");
11631 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11632 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11633 cpr = mProviderMap.getProviderByClass(comp, userId);
11634 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11635 final boolean firstClass = cpr == null;
11637 final long ident = Binder.clearCallingIdentity();
11639 // If permissions need a review before any of the app components can run,
11640 // we return no provider and launch a review activity if the calling app
11641 // is in the foreground.
11642 if (mPermissionReviewRequired) {
11643 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11649 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11650 ApplicationInfo ai =
11651 AppGlobals.getPackageManager().
11652 getApplicationInfo(
11653 cpi.applicationInfo.packageName,
11654 STOCK_PM_FLAGS, userId);
11655 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11657 Slog.w(TAG, "No package info for content provider "
11661 ai = getAppInfoForUser(ai, userId);
11662 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11663 } catch (RemoteException ex) {
11664 // pm is in same process, this will never happen.
11666 Binder.restoreCallingIdentity(ident);
11670 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11672 if (r != null && cpr.canRunHere(r)) {
11673 // If this is a multiprocess provider, then just return its
11674 // info and allow the caller to instantiate it. Only do
11675 // this if the provider is the same user as the caller's
11676 // process, or can run as root (so can be in any process).
11677 return cpr.newHolder(null);
11680 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11681 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11682 + cpr.info.name + " callers=" + Debug.getCallers(6));
11684 // This is single process, and our app is now connecting to it.
11685 // See if we are already in the process of launching this
11687 final int N = mLaunchingProviders.size();
11689 for (i = 0; i < N; i++) {
11690 if (mLaunchingProviders.get(i) == cpr) {
11695 // If the provider is not already being launched, then get it
11698 final long origId = Binder.clearCallingIdentity();
11701 // Content provider is now in use, its package can't be stopped.
11703 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11704 AppGlobals.getPackageManager().setPackageStoppedState(
11705 cpr.appInfo.packageName, false, userId);
11706 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11707 } catch (RemoteException e) {
11708 } catch (IllegalArgumentException e) {
11709 Slog.w(TAG, "Failed trying to unstop package "
11710 + cpr.appInfo.packageName + ": " + e);
11713 // Use existing process if already started
11714 checkTime(startTime, "getContentProviderImpl: looking for process record");
11715 ProcessRecord proc = getProcessRecordLocked(
11716 cpi.processName, cpr.appInfo.uid, false);
11717 if (proc != null && proc.thread != null && !proc.killed) {
11718 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11719 "Installing in existing process " + proc);
11720 if (!proc.pubProviders.containsKey(cpi.name)) {
11721 checkTime(startTime, "getContentProviderImpl: scheduling install");
11722 proc.pubProviders.put(cpi.name, cpr);
11724 proc.thread.scheduleInstallProvider(cpi);
11725 } catch (RemoteException e) {
11729 checkTime(startTime, "getContentProviderImpl: before start process");
11730 proc = startProcessLocked(cpi.processName,
11731 cpr.appInfo, false, 0, "content provider",
11732 new ComponentName(cpi.applicationInfo.packageName,
11733 cpi.name), false, false, false);
11734 checkTime(startTime, "getContentProviderImpl: after start process");
11735 if (proc == null) {
11736 Slog.w(TAG, "Unable to launch app "
11737 + cpi.applicationInfo.packageName + "/"
11738 + cpi.applicationInfo.uid + " for provider "
11739 + name + ": process is bad");
11743 cpr.launchingApp = proc;
11744 mLaunchingProviders.add(cpr);
11746 Binder.restoreCallingIdentity(origId);
11750 checkTime(startTime, "getContentProviderImpl: updating data structures");
11752 // Make sure the provider is published (the same provider class
11753 // may be published under multiple names).
11755 mProviderMap.putProviderByClass(comp, cpr);
11758 mProviderMap.putProviderByName(name, cpr);
11759 conn = incProviderCountLocked(r, cpr, token, stable);
11760 if (conn != null) {
11761 conn.waiting = true;
11764 checkTime(startTime, "getContentProviderImpl: done!");
11766 grantEphemeralAccessLocked(userId, null /*intent*/,
11767 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11770 // Wait for the provider to be published...
11771 synchronized (cpr) {
11772 while (cpr.provider == null) {
11773 if (cpr.launchingApp == null) {
11774 Slog.w(TAG, "Unable to launch app "
11775 + cpi.applicationInfo.packageName + "/"
11776 + cpi.applicationInfo.uid + " for provider "
11777 + name + ": launching app became null");
11778 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11779 UserHandle.getUserId(cpi.applicationInfo.uid),
11780 cpi.applicationInfo.packageName,
11781 cpi.applicationInfo.uid, name);
11785 if (DEBUG_MU) Slog.v(TAG_MU,
11786 "Waiting to start provider " + cpr
11787 + " launchingApp=" + cpr.launchingApp);
11788 if (conn != null) {
11789 conn.waiting = true;
11792 } catch (InterruptedException ex) {
11794 if (conn != null) {
11795 conn.waiting = false;
11800 return cpr != null ? cpr.newHolder(conn) : null;
11803 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11804 ProcessRecord r, final int userId) {
11805 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11806 cpi.packageName, userId)) {
11808 final boolean callerForeground = r == null || r.setSchedGroup
11809 != ProcessList.SCHED_GROUP_BACKGROUND;
11811 // Show a permission review UI only for starting from a foreground app
11812 if (!callerForeground) {
11813 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11814 + cpi.packageName + " requires a permissions review");
11818 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11819 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11820 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11821 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11823 if (DEBUG_PERMISSIONS_REVIEW) {
11824 Slog.i(TAG, "u" + userId + " Launching permission review "
11825 + "for package " + cpi.packageName);
11828 final UserHandle userHandle = new UserHandle(userId);
11829 mHandler.post(new Runnable() {
11831 public void run() {
11832 mContext.startActivityAsUser(intent, userHandle);
11842 PackageManagerInternal getPackageManagerInternalLocked() {
11843 if (mPackageManagerInt == null) {
11844 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11846 return mPackageManagerInt;
11850 public final ContentProviderHolder getContentProvider(
11851 IApplicationThread caller, String name, int userId, boolean stable) {
11852 enforceNotIsolatedCaller("getContentProvider");
11853 if (caller == null) {
11854 String msg = "null IApplicationThread when getting content provider "
11857 throw new SecurityException(msg);
11859 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11860 // with cross-user grant.
11861 return getContentProviderImpl(caller, name, null, stable, userId);
11864 public ContentProviderHolder getContentProviderExternal(
11865 String name, int userId, IBinder token) {
11866 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11867 "Do not have permission in call getContentProviderExternal()");
11868 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11869 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11870 return getContentProviderExternalUnchecked(name, token, userId);
11873 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11874 IBinder token, int userId) {
11875 return getContentProviderImpl(null, name, token, true, userId);
11879 * Drop a content provider from a ProcessRecord's bookkeeping
11881 public void removeContentProvider(IBinder connection, boolean stable) {
11882 enforceNotIsolatedCaller("removeContentProvider");
11883 long ident = Binder.clearCallingIdentity();
11885 synchronized (this) {
11886 ContentProviderConnection conn;
11888 conn = (ContentProviderConnection)connection;
11889 } catch (ClassCastException e) {
11890 String msg ="removeContentProvider: " + connection
11891 + " not a ContentProviderConnection";
11893 throw new IllegalArgumentException(msg);
11895 if (conn == null) {
11896 throw new NullPointerException("connection is null");
11898 if (decProviderCountLocked(conn, null, null, stable)) {
11899 updateOomAdjLocked();
11903 Binder.restoreCallingIdentity(ident);
11907 public void removeContentProviderExternal(String name, IBinder token) {
11908 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11909 "Do not have permission in call removeContentProviderExternal()");
11910 int userId = UserHandle.getCallingUserId();
11911 long ident = Binder.clearCallingIdentity();
11913 removeContentProviderExternalUnchecked(name, token, userId);
11915 Binder.restoreCallingIdentity(ident);
11919 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11920 synchronized (this) {
11921 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11923 //remove from mProvidersByClass
11924 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11928 //update content provider record entry info
11929 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11930 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11931 if (localCpr.hasExternalProcessHandles()) {
11932 if (localCpr.removeExternalProcessHandleLocked(token)) {
11933 updateOomAdjLocked();
11935 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11936 + " with no external reference for token: "
11940 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11941 + " with no external references.");
11946 public final void publishContentProviders(IApplicationThread caller,
11947 List<ContentProviderHolder> providers) {
11948 if (providers == null) {
11952 enforceNotIsolatedCaller("publishContentProviders");
11953 synchronized (this) {
11954 final ProcessRecord r = getRecordForAppLocked(caller);
11955 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11957 throw new SecurityException(
11958 "Unable to find app for caller " + caller
11959 + " (pid=" + Binder.getCallingPid()
11960 + ") when publishing content providers");
11963 final long origId = Binder.clearCallingIdentity();
11965 final int N = providers.size();
11966 for (int i = 0; i < N; i++) {
11967 ContentProviderHolder src = providers.get(i);
11968 if (src == null || src.info == null || src.provider == null) {
11971 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11972 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11974 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11975 mProviderMap.putProviderByClass(comp, dst);
11976 String names[] = dst.info.authority.split(";");
11977 for (int j = 0; j < names.length; j++) {
11978 mProviderMap.putProviderByName(names[j], dst);
11981 int launchingCount = mLaunchingProviders.size();
11983 boolean wasInLaunchingProviders = false;
11984 for (j = 0; j < launchingCount; j++) {
11985 if (mLaunchingProviders.get(j) == dst) {
11986 mLaunchingProviders.remove(j);
11987 wasInLaunchingProviders = true;
11992 if (wasInLaunchingProviders) {
11993 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11995 synchronized (dst) {
11996 dst.provider = src.provider;
12000 updateOomAdjLocked(r, true);
12001 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12002 src.info.authority);
12006 Binder.restoreCallingIdentity(origId);
12010 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12011 ContentProviderConnection conn;
12013 conn = (ContentProviderConnection)connection;
12014 } catch (ClassCastException e) {
12015 String msg ="refContentProvider: " + connection
12016 + " not a ContentProviderConnection";
12018 throw new IllegalArgumentException(msg);
12020 if (conn == null) {
12021 throw new NullPointerException("connection is null");
12024 synchronized (this) {
12026 conn.numStableIncs += stable;
12028 stable = conn.stableCount + stable;
12030 throw new IllegalStateException("stableCount < 0: " + stable);
12033 if (unstable > 0) {
12034 conn.numUnstableIncs += unstable;
12036 unstable = conn.unstableCount + unstable;
12037 if (unstable < 0) {
12038 throw new IllegalStateException("unstableCount < 0: " + unstable);
12041 if ((stable+unstable) <= 0) {
12042 throw new IllegalStateException("ref counts can't go to zero here: stable="
12043 + stable + " unstable=" + unstable);
12045 conn.stableCount = stable;
12046 conn.unstableCount = unstable;
12051 public void unstableProviderDied(IBinder connection) {
12052 ContentProviderConnection conn;
12054 conn = (ContentProviderConnection)connection;
12055 } catch (ClassCastException e) {
12056 String msg ="refContentProvider: " + connection
12057 + " not a ContentProviderConnection";
12059 throw new IllegalArgumentException(msg);
12061 if (conn == null) {
12062 throw new NullPointerException("connection is null");
12065 // Safely retrieve the content provider associated with the connection.
12066 IContentProvider provider;
12067 synchronized (this) {
12068 provider = conn.provider.provider;
12071 if (provider == null) {
12072 // Um, yeah, we're way ahead of you.
12076 // Make sure the caller is being honest with us.
12077 if (provider.asBinder().pingBinder()) {
12078 // Er, no, still looks good to us.
12079 synchronized (this) {
12080 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12081 + " says " + conn + " died, but we don't agree");
12086 // Well look at that! It's dead!
12087 synchronized (this) {
12088 if (conn.provider.provider != provider) {
12089 // But something changed... good enough.
12093 ProcessRecord proc = conn.provider.proc;
12094 if (proc == null || proc.thread == null) {
12095 // Seems like the process is already cleaned up.
12099 // As far as we're concerned, this is just like receiving a
12100 // death notification... just a bit prematurely.
12101 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12102 + ") early provider death");
12103 final long ident = Binder.clearCallingIdentity();
12105 appDiedLocked(proc);
12107 Binder.restoreCallingIdentity(ident);
12113 public void appNotRespondingViaProvider(IBinder connection) {
12114 enforceCallingPermission(
12115 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12117 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12118 if (conn == null) {
12119 Slog.w(TAG, "ContentProviderConnection is null");
12123 final ProcessRecord host = conn.provider.proc;
12124 if (host == null) {
12125 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12129 mHandler.post(new Runnable() {
12131 public void run() {
12132 mAppErrors.appNotResponding(host, null, null, false,
12133 "ContentProvider not responding");
12138 public final void installSystemProviders() {
12139 List<ProviderInfo> providers;
12140 synchronized (this) {
12141 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12142 providers = generateApplicationProvidersLocked(app);
12143 if (providers != null) {
12144 for (int i=providers.size()-1; i>=0; i--) {
12145 ProviderInfo pi = (ProviderInfo)providers.get(i);
12146 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12147 Slog.w(TAG, "Not installing system proc provider " + pi.name
12148 + ": not system .apk");
12149 providers.remove(i);
12154 if (providers != null) {
12155 mSystemThread.installSystemProviders(providers);
12158 mConstants.start(mContext.getContentResolver());
12159 mCoreSettingsObserver = new CoreSettingsObserver(this);
12160 mFontScaleSettingObserver = new FontScaleSettingObserver();
12162 // Now that the settings provider is published we can consider sending
12163 // in a rescue party.
12164 RescueParty.onSettingsProviderPublished(mContext);
12166 //mUsageStatsService.monitorPackages();
12169 private void startPersistentApps(int matchFlags) {
12170 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12172 synchronized (this) {
12174 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12175 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12176 for (ApplicationInfo app : apps) {
12177 if (!"android".equals(app.packageName)) {
12178 addAppLocked(app, null, false, null /* ABI override */);
12181 } catch (RemoteException ex) {
12187 * When a user is unlocked, we need to install encryption-unaware providers
12188 * belonging to any running apps.
12190 private void installEncryptionUnawareProviders(int userId) {
12191 // We're only interested in providers that are encryption unaware, and
12192 // we don't care about uninstalled apps, since there's no way they're
12193 // running at this point.
12194 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12196 synchronized (this) {
12197 final int NP = mProcessNames.getMap().size();
12198 for (int ip = 0; ip < NP; ip++) {
12199 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12200 final int NA = apps.size();
12201 for (int ia = 0; ia < NA; ia++) {
12202 final ProcessRecord app = apps.valueAt(ia);
12203 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12205 final int NG = app.pkgList.size();
12206 for (int ig = 0; ig < NG; ig++) {
12208 final String pkgName = app.pkgList.keyAt(ig);
12209 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12210 .getPackageInfo(pkgName, matchFlags, userId);
12211 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12212 for (ProviderInfo pi : pkgInfo.providers) {
12213 // TODO: keep in sync with generateApplicationProvidersLocked
12214 final boolean processMatch = Objects.equals(pi.processName,
12215 app.processName) || pi.multiprocess;
12216 final boolean userMatch = isSingleton(pi.processName,
12217 pi.applicationInfo, pi.name, pi.flags)
12218 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12219 if (processMatch && userMatch) {
12220 Log.v(TAG, "Installing " + pi);
12221 app.thread.scheduleInstallProvider(pi);
12223 Log.v(TAG, "Skipping " + pi);
12227 } catch (RemoteException ignored) {
12236 * Allows apps to retrieve the MIME type of a URI.
12237 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12238 * users, then it does not need permission to access the ContentProvider.
12239 * Either, it needs cross-user uri grants.
12241 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12243 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12244 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12246 public String getProviderMimeType(Uri uri, int userId) {
12247 enforceNotIsolatedCaller("getProviderMimeType");
12248 final String name = uri.getAuthority();
12249 int callingUid = Binder.getCallingUid();
12250 int callingPid = Binder.getCallingPid();
12252 boolean clearedIdentity = false;
12253 synchronized (this) {
12254 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12256 if (canClearIdentity(callingPid, callingUid, userId)) {
12257 clearedIdentity = true;
12258 ident = Binder.clearCallingIdentity();
12260 ContentProviderHolder holder = null;
12262 holder = getContentProviderExternalUnchecked(name, null, userId);
12263 if (holder != null) {
12264 return holder.provider.getType(uri);
12266 } catch (RemoteException e) {
12267 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12269 } catch (Exception e) {
12270 Log.w(TAG, "Exception while determining type of " + uri, e);
12273 // We need to clear the identity to call removeContentProviderExternalUnchecked
12274 if (!clearedIdentity) {
12275 ident = Binder.clearCallingIdentity();
12278 if (holder != null) {
12279 removeContentProviderExternalUnchecked(name, null, userId);
12282 Binder.restoreCallingIdentity(ident);
12289 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12290 if (UserHandle.getUserId(callingUid) == userId) {
12293 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12294 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12295 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12296 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12302 // =========================================================
12303 // GLOBAL MANAGEMENT
12304 // =========================================================
12306 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12307 boolean isolated, int isolatedUid) {
12308 String proc = customProcess != null ? customProcess : info.processName;
12309 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12310 final int userId = UserHandle.getUserId(info.uid);
12311 int uid = info.uid;
12313 if (isolatedUid == 0) {
12314 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12316 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12317 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12318 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12320 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12321 mNextIsolatedProcessUid++;
12322 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12323 // No process for this uid, use it.
12327 if (stepsLeft <= 0) {
12332 // Special case for startIsolatedProcess (internal only), where
12333 // the uid of the isolated process is specified by the caller.
12336 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12338 // Register the isolated UID with this application so BatteryStats knows to
12339 // attribute resource usage to the application.
12341 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12342 // about the process state of the isolated UID *before* it is registered with the
12343 // owning application.
12344 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12346 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12347 if (!mBooted && !mBooting
12348 && userId == UserHandle.USER_SYSTEM
12349 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12350 r.persistent = true;
12351 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12353 addProcessNameLocked(r);
12357 private boolean uidOnBackgroundWhitelist(final int uid) {
12358 final int appId = UserHandle.getAppId(uid);
12359 final int[] whitelist = mBackgroundAppIdWhitelist;
12360 final int N = whitelist.length;
12361 for (int i = 0; i < N; i++) {
12362 if (appId == whitelist[i]) {
12370 public void backgroundWhitelistUid(final int uid) {
12371 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12372 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12375 if (DEBUG_BACKGROUND_CHECK) {
12376 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12378 synchronized (this) {
12379 final int N = mBackgroundAppIdWhitelist.length;
12380 int[] newList = new int[N+1];
12381 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12382 newList[N] = UserHandle.getAppId(uid);
12383 mBackgroundAppIdWhitelist = newList;
12387 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12388 String abiOverride) {
12391 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12398 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12399 updateLruProcessLocked(app, false, null);
12400 updateOomAdjLocked();
12403 // This package really, really can not be stopped.
12405 AppGlobals.getPackageManager().setPackageStoppedState(
12406 info.packageName, false, UserHandle.getUserId(app.uid));
12407 } catch (RemoteException e) {
12408 } catch (IllegalArgumentException e) {
12409 Slog.w(TAG, "Failed trying to unstop package "
12410 + info.packageName + ": " + e);
12413 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12414 app.persistent = true;
12415 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12417 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12418 mPersistentStartingProcesses.add(app);
12419 startProcessLocked(app, "added application",
12420 customProcess != null ? customProcess : app.processName, abiOverride,
12421 null /* entryPoint */, null /* entryPointArgs */);
12427 public void unhandledBack() {
12428 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12429 "unhandledBack()");
12431 synchronized(this) {
12432 final long origId = Binder.clearCallingIdentity();
12434 getFocusedStack().unhandledBackLocked();
12436 Binder.restoreCallingIdentity(origId);
12441 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12442 enforceNotIsolatedCaller("openContentUri");
12443 final int userId = UserHandle.getCallingUserId();
12444 final Uri uri = Uri.parse(uriString);
12445 String name = uri.getAuthority();
12446 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12447 ParcelFileDescriptor pfd = null;
12449 // We record the binder invoker's uid in thread-local storage before
12450 // going to the content provider to open the file. Later, in the code
12451 // that handles all permissions checks, we look for this uid and use
12452 // that rather than the Activity Manager's own uid. The effect is that
12453 // we do the check against the caller's permissions even though it looks
12454 // to the content provider like the Activity Manager itself is making
12456 Binder token = new Binder();
12457 sCallerIdentity.set(new Identity(
12458 token, Binder.getCallingPid(), Binder.getCallingUid()));
12460 pfd = cph.provider.openFile(null, uri, "r", null, token);
12461 } catch (FileNotFoundException e) {
12462 // do nothing; pfd will be returned null
12464 // Ensure that whatever happens, we clean up the identity state
12465 sCallerIdentity.remove();
12466 // Ensure we're done with the provider.
12467 removeContentProviderExternalUnchecked(name, null, userId);
12470 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12475 // Actually is sleeping or shutting down or whatever else in the future
12476 // is an inactive state.
12477 boolean isSleepingOrShuttingDownLocked() {
12478 return isSleepingLocked() || mShuttingDown;
12481 boolean isShuttingDownLocked() {
12482 return mShuttingDown;
12485 boolean isSleepingLocked() {
12489 void onWakefulnessChanged(int wakefulness) {
12490 synchronized(this) {
12491 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12492 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12493 mWakefulness = wakefulness;
12495 if (wasAwake != isAwake) {
12496 // Also update state in a special way for running foreground services UI.
12497 mServices.updateScreenStateLocked(isAwake);
12498 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12504 void finishRunningVoiceLocked() {
12505 if (mRunningVoice != null) {
12506 mRunningVoice = null;
12507 mVoiceWakeLock.release();
12508 updateSleepIfNeededLocked();
12512 void startTimeTrackingFocusedActivityLocked() {
12513 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12514 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12515 mCurAppTimeTracker.start(resumedActivity.packageName);
12519 void updateSleepIfNeededLocked() {
12520 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12521 final boolean wasSleeping = mSleeping;
12523 if (!shouldSleep) {
12524 // If wasSleeping is true, we need to wake up activity manager state from when
12525 // we started sleeping. In either case, we need to apply the sleep tokens, which
12526 // will wake up stacks or put them to sleep as appropriate.
12529 startTimeTrackingFocusedActivityLocked();
12530 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12531 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12533 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12535 updateOomAdjLocked();
12537 } else if (!mSleeping && shouldSleep) {
12539 if (mCurAppTimeTracker != null) {
12540 mCurAppTimeTracker.stop();
12542 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12543 mStackSupervisor.goingToSleepLocked();
12544 updateOomAdjLocked();
12548 /** Pokes the task persister. */
12549 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12550 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12554 * Notifies all listeners when the pinned stack animation starts.
12557 public void notifyPinnedStackAnimationStarted() {
12558 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12562 * Notifies all listeners when the pinned stack animation ends.
12565 public void notifyPinnedStackAnimationEnded() {
12566 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12570 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12571 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12575 public boolean shutdown(int timeout) {
12576 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12577 != PackageManager.PERMISSION_GRANTED) {
12578 throw new SecurityException("Requires permission "
12579 + android.Manifest.permission.SHUTDOWN);
12582 boolean timedout = false;
12584 synchronized(this) {
12585 mShuttingDown = true;
12586 mStackSupervisor.prepareForShutdownLocked();
12587 updateEventDispatchingLocked();
12588 timedout = mStackSupervisor.shutdownLocked(timeout);
12591 mAppOpsService.shutdown();
12592 if (mUsageStatsService != null) {
12593 mUsageStatsService.prepareShutdown();
12595 mBatteryStatsService.shutdown();
12596 synchronized (this) {
12597 mProcessStats.shutdownLocked();
12598 notifyTaskPersisterLocked(null, true);
12604 public final void activitySlept(IBinder token) {
12605 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12607 final long origId = Binder.clearCallingIdentity();
12609 synchronized (this) {
12610 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12612 mStackSupervisor.activitySleptLocked(r);
12616 Binder.restoreCallingIdentity(origId);
12619 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12620 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12621 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12622 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12623 boolean wasRunningVoice = mRunningVoice != null;
12624 mRunningVoice = session;
12625 if (!wasRunningVoice) {
12626 mVoiceWakeLock.acquire();
12627 updateSleepIfNeededLocked();
12632 private void updateEventDispatchingLocked() {
12633 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12637 public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12638 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12639 != PackageManager.PERMISSION_GRANTED) {
12640 throw new SecurityException("Requires permission "
12641 + android.Manifest.permission.DEVICE_POWER);
12644 synchronized(this) {
12645 long ident = Binder.clearCallingIdentity();
12647 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12649 Binder.restoreCallingIdentity(ident);
12653 mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12658 public void notifyLockedProfile(@UserIdInt int userId) {
12660 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12661 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12663 } catch (RemoteException ex) {
12664 throw new SecurityException("Fail to check is caller a privileged app", ex);
12667 synchronized (this) {
12668 final long ident = Binder.clearCallingIdentity();
12670 if (mUserController.shouldConfirmCredentials(userId)) {
12671 if (mKeyguardController.isKeyguardLocked()) {
12672 // Showing launcher to avoid user entering credential twice.
12673 final int currentUserId = mUserController.getCurrentUserIdLocked();
12674 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12676 mStackSupervisor.lockAllProfileTasks(userId);
12679 Binder.restoreCallingIdentity(ident);
12685 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12686 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12687 synchronized (this) {
12688 final long ident = Binder.clearCallingIdentity();
12690 mActivityStarter.startConfirmCredentialIntent(intent, options);
12692 Binder.restoreCallingIdentity(ident);
12698 public void stopAppSwitches() {
12699 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12700 != PackageManager.PERMISSION_GRANTED) {
12701 throw new SecurityException("viewquires permission "
12702 + android.Manifest.permission.STOP_APP_SWITCHES);
12705 synchronized(this) {
12706 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12707 + APP_SWITCH_DELAY_TIME;
12708 mDidAppSwitch = false;
12709 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12710 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12711 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12715 public void resumeAppSwitches() {
12716 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12717 != PackageManager.PERMISSION_GRANTED) {
12718 throw new SecurityException("Requires permission "
12719 + android.Manifest.permission.STOP_APP_SWITCHES);
12722 synchronized(this) {
12723 // Note that we don't execute any pending app switches... we will
12724 // let those wait until either the timeout, or the next start
12725 // activity request.
12726 mAppSwitchesAllowedTime = 0;
12730 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12731 int callingPid, int callingUid, String name) {
12732 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12736 int perm = checkComponentPermission(
12737 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12738 sourceUid, -1, true);
12739 if (perm == PackageManager.PERMISSION_GRANTED) {
12743 // If the actual IPC caller is different from the logical source, then
12744 // also see if they are allowed to control app switches.
12745 if (callingUid != -1 && callingUid != sourceUid) {
12746 perm = checkComponentPermission(
12747 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12748 callingUid, -1, true);
12749 if (perm == PackageManager.PERMISSION_GRANTED) {
12754 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12758 public void setDebugApp(String packageName, boolean waitForDebugger,
12759 boolean persistent) {
12760 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12763 long ident = Binder.clearCallingIdentity();
12765 // Note that this is not really thread safe if there are multiple
12766 // callers into it at the same time, but that's not a situation we
12769 final ContentResolver resolver = mContext.getContentResolver();
12770 Settings.Global.putString(
12771 resolver, Settings.Global.DEBUG_APP,
12773 Settings.Global.putInt(
12774 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12775 waitForDebugger ? 1 : 0);
12778 synchronized (this) {
12780 mOrigDebugApp = mDebugApp;
12781 mOrigWaitForDebugger = mWaitForDebugger;
12783 mDebugApp = packageName;
12784 mWaitForDebugger = waitForDebugger;
12785 mDebugTransient = !persistent;
12786 if (packageName != null) {
12787 forceStopPackageLocked(packageName, -1, false, false, true, true,
12788 false, UserHandle.USER_ALL, "set debug app");
12792 Binder.restoreCallingIdentity(ident);
12796 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12797 synchronized (this) {
12798 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12799 if (!isDebuggable) {
12800 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12801 throw new SecurityException("Process not debuggable: " + app.packageName);
12805 mTrackAllocationApp = processName;
12809 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12810 synchronized (this) {
12811 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12812 if (!isDebuggable) {
12813 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12814 throw new SecurityException("Process not debuggable: " + app.packageName);
12817 mProfileApp = processName;
12819 if (mProfilerInfo != null) {
12820 if (mProfilerInfo.profileFd != null) {
12822 mProfilerInfo.profileFd.close();
12823 } catch (IOException e) {
12827 mProfilerInfo = new ProfilerInfo(profilerInfo);
12832 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12833 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12834 if (!isDebuggable) {
12835 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12836 throw new SecurityException("Process not debuggable: " + app.packageName);
12839 mNativeDebuggingApp = processName;
12843 public void setAlwaysFinish(boolean enabled) {
12844 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12845 "setAlwaysFinish()");
12847 long ident = Binder.clearCallingIdentity();
12849 Settings.Global.putInt(
12850 mContext.getContentResolver(),
12851 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12853 synchronized (this) {
12854 mAlwaysFinishActivities = enabled;
12857 Binder.restoreCallingIdentity(ident);
12862 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12863 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12864 "setActivityController()");
12865 synchronized (this) {
12866 mController = controller;
12867 mControllerIsAMonkey = imAMonkey;
12868 Watchdog.getInstance().setActivityController(controller);
12873 public void setUserIsMonkey(boolean userIsMonkey) {
12874 synchronized (this) {
12875 synchronized (mPidsSelfLocked) {
12876 final int callingPid = Binder.getCallingPid();
12877 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12878 if (proc == null) {
12879 throw new SecurityException("Unknown process: " + callingPid);
12881 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12882 throw new SecurityException("Only an instrumentation process "
12883 + "with a UiAutomation can call setUserIsMonkey");
12886 mUserIsMonkey = userIsMonkey;
12891 public boolean isUserAMonkey() {
12892 synchronized (this) {
12893 // If there is a controller also implies the user is a monkey.
12894 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12899 * @deprecated This method is only used by a few internal components and it will soon be
12900 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12901 * No new code should be calling it.
12905 public void requestBugReport(int bugreportType) {
12906 String extraOptions = null;
12907 switch (bugreportType) {
12908 case ActivityManager.BUGREPORT_OPTION_FULL:
12909 // Default options.
12911 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12912 extraOptions = "bugreportplus";
12914 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12915 extraOptions = "bugreportremote";
12917 case ActivityManager.BUGREPORT_OPTION_WEAR:
12918 extraOptions = "bugreportwear";
12920 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12921 extraOptions = "bugreporttelephony";
12924 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12927 // Always log caller, even if it does not have permission to dump.
12928 String type = extraOptions == null ? "bugreport" : extraOptions;
12929 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12931 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12932 if (extraOptions != null) {
12933 SystemProperties.set("dumpstate.options", extraOptions);
12935 SystemProperties.set("ctl.start", "bugreport");
12939 * @deprecated This method is only used by a few internal components and it will soon be
12940 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12941 * No new code should be calling it.
12945 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12947 if (!TextUtils.isEmpty(shareTitle)) {
12948 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12949 String errorStr = "shareTitle should be less than " +
12950 MAX_BUGREPORT_TITLE_SIZE + " characters";
12951 throw new IllegalArgumentException(errorStr);
12953 if (!TextUtils.isEmpty(shareDescription)) {
12956 length = shareDescription.getBytes("UTF-8").length;
12957 } catch (UnsupportedEncodingException e) {
12958 String errorStr = "shareDescription: UnsupportedEncodingException";
12959 throw new IllegalArgumentException(errorStr);
12961 if (length > SystemProperties.PROP_VALUE_MAX) {
12962 String errorStr = "shareTitle should be less than " +
12963 SystemProperties.PROP_VALUE_MAX + " bytes";
12964 throw new IllegalArgumentException(errorStr);
12966 SystemProperties.set("dumpstate.options.description", shareDescription);
12969 SystemProperties.set("dumpstate.options.title", shareTitle);
12973 Slog.d(TAG, "Bugreport notification title " + shareTitle
12974 + " description " + shareDescription);
12975 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12978 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12979 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12982 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12983 if (r != null && (r.instr != null || r.usingWrapper)) {
12984 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12986 return KEY_DISPATCHING_TIMEOUT;
12990 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12991 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12992 != PackageManager.PERMISSION_GRANTED) {
12993 throw new SecurityException("Requires permission "
12994 + android.Manifest.permission.FILTER_EVENTS);
12996 ProcessRecord proc;
12998 synchronized (this) {
12999 synchronized (mPidsSelfLocked) {
13000 proc = mPidsSelfLocked.get(pid);
13002 timeout = getInputDispatchingTimeoutLocked(proc);
13005 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13013 * Handle input dispatching timeouts.
13014 * Returns whether input dispatching should be aborted or not.
13016 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13017 final ActivityRecord activity, final ActivityRecord parent,
13018 final boolean aboveSystem, String reason) {
13019 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13020 != PackageManager.PERMISSION_GRANTED) {
13021 throw new SecurityException("Requires permission "
13022 + android.Manifest.permission.FILTER_EVENTS);
13025 final String annotation;
13026 if (reason == null) {
13027 annotation = "Input dispatching timed out";
13029 annotation = "Input dispatching timed out (" + reason + ")";
13032 if (proc != null) {
13033 synchronized (this) {
13034 if (proc.debugging) {
13038 if (proc.instr != null) {
13039 Bundle info = new Bundle();
13040 info.putString("shortMsg", "keyDispatchingTimedOut");
13041 info.putString("longMsg", annotation);
13042 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13046 mHandler.post(new Runnable() {
13048 public void run() {
13049 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13058 public Bundle getAssistContextExtras(int requestType) {
13059 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13060 null, null, true /* focused */, true /* newSessionId */,
13061 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13065 synchronized (pae) {
13066 while (!pae.haveResult) {
13069 } catch (InterruptedException e) {
13073 synchronized (this) {
13074 buildAssistBundleLocked(pae, pae.result);
13075 mPendingAssistExtras.remove(pae);
13076 mUiHandler.removeCallbacks(pae);
13082 public boolean isAssistDataAllowedOnCurrentActivity() {
13084 synchronized (this) {
13085 final ActivityStack focusedStack = getFocusedStack();
13086 if (focusedStack == null || focusedStack.isAssistantStack()) {
13090 final ActivityRecord activity = focusedStack.topActivity();
13091 if (activity == null) {
13094 userId = activity.userId;
13096 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13097 Context.DEVICE_POLICY_SERVICE);
13098 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13102 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13103 long ident = Binder.clearCallingIdentity();
13105 synchronized (this) {
13106 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13107 ActivityRecord top = getFocusedStack().topActivity();
13108 if (top != caller) {
13109 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13110 + " is not current top " + top);
13113 if (!top.nowVisible) {
13114 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13115 + " is not visible");
13119 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13122 Binder.restoreCallingIdentity(ident);
13127 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13128 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13129 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13130 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13131 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13135 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13136 IBinder activityToken, int flags) {
13137 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13138 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13139 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13142 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13143 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13144 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13146 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13147 "enqueueAssistContext()");
13149 synchronized (this) {
13150 ActivityRecord activity = getFocusedStack().topActivity();
13151 if (activity == null) {
13152 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13155 if (activity.app == null || activity.app.thread == null) {
13156 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13160 if (activityToken != null) {
13161 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13162 if (activity != caller) {
13163 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13164 + " is not current top " + activity);
13169 activity = ActivityRecord.forTokenLocked(activityToken);
13170 if (activity == null) {
13171 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13172 + " couldn't be found");
13175 if (activity.app == null || activity.app.thread == null) {
13176 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13181 PendingAssistExtras pae;
13182 Bundle extras = new Bundle();
13183 if (args != null) {
13184 extras.putAll(args);
13186 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13187 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13189 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13191 pae.isHome = activity.isHomeActivity();
13193 // Increment the sessionId if necessary
13194 if (newSessionId) {
13198 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13199 mViSessionId, flags);
13200 mPendingAssistExtras.add(pae);
13201 mUiHandler.postDelayed(pae, timeout);
13202 } catch (RemoteException e) {
13203 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13210 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13211 IResultReceiver receiver;
13212 synchronized (this) {
13213 mPendingAssistExtras.remove(pae);
13214 receiver = pae.receiver;
13216 if (receiver != null) {
13217 // Caller wants result sent back to them.
13218 Bundle sendBundle = new Bundle();
13219 // At least return the receiver extras
13220 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13221 pae.receiverExtras);
13223 pae.receiver.send(0, sendBundle);
13224 } catch (RemoteException e) {
13229 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13230 if (result != null) {
13231 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13233 if (pae.hint != null) {
13234 pae.extras.putBoolean(pae.hint, true);
13238 /** Called from an app when assist data is ready. */
13240 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13241 AssistContent content, Uri referrer) {
13242 PendingAssistExtras pae = (PendingAssistExtras)token;
13243 synchronized (pae) {
13244 pae.result = extras;
13245 pae.structure = structure;
13246 pae.content = content;
13247 if (referrer != null) {
13248 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13250 if (structure != null) {
13251 structure.setHomeActivity(pae.isHome);
13253 pae.haveResult = true;
13255 if (pae.intent == null && pae.receiver == null) {
13256 // Caller is just waiting for the result.
13260 // We are now ready to launch the assist activity.
13261 IResultReceiver sendReceiver = null;
13262 Bundle sendBundle = null;
13263 synchronized (this) {
13264 buildAssistBundleLocked(pae, extras);
13265 boolean exists = mPendingAssistExtras.remove(pae);
13266 mUiHandler.removeCallbacks(pae);
13271 if ((sendReceiver=pae.receiver) != null) {
13272 // Caller wants result sent back to them.
13273 sendBundle = new Bundle();
13274 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13275 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13276 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13277 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13278 pae.receiverExtras);
13281 if (sendReceiver != null) {
13283 sendReceiver.send(0, sendBundle);
13284 } catch (RemoteException e) {
13289 final long ident = Binder.clearCallingIdentity();
13291 if (TextUtils.equals(pae.intent.getAction(),
13292 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13293 pae.intent.putExtras(pae.extras);
13294 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13296 pae.intent.replaceExtras(pae.extras);
13297 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13298 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13299 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13300 closeSystemDialogs("assist");
13303 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13304 } catch (ActivityNotFoundException e) {
13305 Slog.w(TAG, "No activity to handle assist action.", e);
13309 Binder.restoreCallingIdentity(ident);
13313 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13315 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13316 true /* focused */, true /* newSessionId */, userHandle, args,
13317 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13320 public void registerProcessObserver(IProcessObserver observer) {
13321 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13322 "registerProcessObserver()");
13323 synchronized (this) {
13324 mProcessObservers.register(observer);
13329 public void unregisterProcessObserver(IProcessObserver observer) {
13330 synchronized (this) {
13331 mProcessObservers.unregister(observer);
13336 public int getUidProcessState(int uid, String callingPackage) {
13337 if (!hasUsageStatsPermission(callingPackage)) {
13338 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13339 "getUidProcessState");
13342 synchronized (this) {
13343 UidRecord uidRec = mActiveUids.get(uid);
13344 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13349 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13350 String callingPackage) {
13351 if (!hasUsageStatsPermission(callingPackage)) {
13352 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13353 "registerUidObserver");
13355 synchronized (this) {
13356 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13357 callingPackage, which, cutpoint));
13362 public void unregisterUidObserver(IUidObserver observer) {
13363 synchronized (this) {
13364 mUidObservers.unregister(observer);
13369 public boolean convertFromTranslucent(IBinder token) {
13370 final long origId = Binder.clearCallingIdentity();
13372 synchronized (this) {
13373 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13377 final boolean translucentChanged = r.changeWindowTranslucency(true);
13378 if (translucentChanged) {
13379 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13381 mWindowManager.setAppFullscreen(token, true);
13382 return translucentChanged;
13385 Binder.restoreCallingIdentity(origId);
13390 public boolean convertToTranslucent(IBinder token, Bundle options) {
13391 final long origId = Binder.clearCallingIdentity();
13393 synchronized (this) {
13394 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13398 final TaskRecord task = r.getTask();
13399 int index = task.mActivities.lastIndexOf(r);
13401 ActivityRecord under = task.mActivities.get(index - 1);
13402 under.returningOptions = ActivityOptions.fromBundle(options);
13404 final boolean translucentChanged = r.changeWindowTranslucency(false);
13405 if (translucentChanged) {
13406 r.getStack().convertActivityToTranslucent(r);
13408 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13409 mWindowManager.setAppFullscreen(token, false);
13410 return translucentChanged;
13413 Binder.restoreCallingIdentity(origId);
13418 public Bundle getActivityOptions(IBinder token) {
13419 final long origId = Binder.clearCallingIdentity();
13421 synchronized (this) {
13422 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13424 final ActivityOptions activityOptions = r.takeOptionsLocked();
13425 return activityOptions == null ? null : activityOptions.toBundle();
13430 Binder.restoreCallingIdentity(origId);
13435 public void setImmersive(IBinder token, boolean immersive) {
13436 synchronized(this) {
13437 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13439 throw new IllegalArgumentException();
13441 r.immersive = immersive;
13443 // update associated state if we're frontmost
13444 if (r == mStackSupervisor.getResumedActivityLocked()) {
13445 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13446 applyUpdateLockStateLocked(r);
13452 public boolean isImmersive(IBinder token) {
13453 synchronized (this) {
13454 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13456 throw new IllegalArgumentException();
13458 return r.immersive;
13463 public void setVrThread(int tid) {
13464 enforceSystemHasVrFeature();
13465 synchronized (this) {
13466 synchronized (mPidsSelfLocked) {
13467 final int pid = Binder.getCallingPid();
13468 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13469 mVrController.setVrThreadLocked(tid, pid, proc);
13475 public void setPersistentVrThread(int tid) {
13476 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13477 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13478 + Binder.getCallingPid()
13479 + ", uid=" + Binder.getCallingUid()
13480 + " requires " + permission.RESTRICTED_VR_ACCESS;
13482 throw new SecurityException(msg);
13484 enforceSystemHasVrFeature();
13485 synchronized (this) {
13486 synchronized (mPidsSelfLocked) {
13487 final int pid = Binder.getCallingPid();
13488 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13489 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13495 * Schedule the given thread a normal scheduling priority.
13497 * @param tid the tid of the thread to adjust the scheduling of.
13498 * @param suppressLogs {@code true} if any error logging should be disabled.
13500 * @return {@code true} if this succeeded.
13502 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13504 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13506 } catch (IllegalArgumentException e) {
13507 if (!suppressLogs) {
13508 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13510 } catch (SecurityException e) {
13511 if (!suppressLogs) {
13512 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13519 * Schedule the given thread an FIFO scheduling priority.
13521 * @param tid the tid of the thread to adjust the scheduling of.
13522 * @param suppressLogs {@code true} if any error logging should be disabled.
13524 * @return {@code true} if this succeeded.
13526 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13528 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13530 } catch (IllegalArgumentException e) {
13531 if (!suppressLogs) {
13532 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13534 } catch (SecurityException e) {
13535 if (!suppressLogs) {
13536 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13543 * Check that we have the features required for VR-related API calls, and throw an exception if
13546 private void enforceSystemHasVrFeature() {
13547 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13548 throw new UnsupportedOperationException("VR mode not supported on this device!");
13553 public void setRenderThread(int tid) {
13554 synchronized (this) {
13555 ProcessRecord proc;
13556 int pid = Binder.getCallingPid();
13557 if (pid == Process.myPid()) {
13558 demoteSystemServerRenderThread(tid);
13561 synchronized (mPidsSelfLocked) {
13562 proc = mPidsSelfLocked.get(pid);
13563 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13564 // ensure the tid belongs to the process
13565 if (!isThreadInProcess(pid, tid)) {
13566 throw new IllegalArgumentException(
13567 "Render thread does not belong to process");
13569 proc.renderThreadTid = tid;
13570 if (DEBUG_OOM_ADJ) {
13571 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13573 // promote to FIFO now
13574 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13575 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13576 if (mUseFifoUiScheduling) {
13577 setThreadScheduler(proc.renderThreadTid,
13578 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13580 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13584 if (DEBUG_OOM_ADJ) {
13585 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13586 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13587 mUseFifoUiScheduling);
13595 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13596 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13598 * @param tid the tid of the RenderThread
13600 private void demoteSystemServerRenderThread(int tid) {
13601 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13605 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13606 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13607 throw new UnsupportedOperationException("VR mode not supported on this device!");
13610 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13613 synchronized (this) {
13614 r = ActivityRecord.isInStackLocked(token);
13618 throw new IllegalArgumentException();
13622 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13623 VrManagerInternal.NO_ERROR) {
13627 synchronized(this) {
13628 r.requestedVrComponent = (enabled) ? packageName : null;
13630 // Update associated state if this activity is currently focused
13631 if (r == mStackSupervisor.getResumedActivityLocked()) {
13632 applyUpdateVrModeLocked(r);
13639 public boolean isVrModePackageEnabled(ComponentName packageName) {
13640 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13641 throw new UnsupportedOperationException("VR mode not supported on this device!");
13644 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13646 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13647 VrManagerInternal.NO_ERROR;
13650 public boolean isTopActivityImmersive() {
13651 enforceNotIsolatedCaller("startActivity");
13652 synchronized (this) {
13653 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13654 return (r != null) ? r.immersive : false;
13659 * @return whether the system should disable UI modes incompatible with VR mode.
13661 boolean shouldDisableNonVrUiLocked() {
13662 return mVrController.shouldDisableNonVrUiLocked();
13666 public boolean isTopOfTask(IBinder token) {
13667 synchronized (this) {
13668 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13670 throw new IllegalArgumentException();
13672 return r.getTask().getTopActivity() == r;
13677 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13678 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13679 String msg = "Permission Denial: setHasTopUi() from pid="
13680 + Binder.getCallingPid()
13681 + ", uid=" + Binder.getCallingUid()
13682 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13684 throw new SecurityException(msg);
13686 final int pid = Binder.getCallingPid();
13687 final long origId = Binder.clearCallingIdentity();
13689 synchronized (this) {
13690 boolean changed = false;
13692 synchronized (mPidsSelfLocked) {
13693 pr = mPidsSelfLocked.get(pid);
13695 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13698 if (pr.hasTopUi != hasTopUi) {
13699 if (DEBUG_OOM_ADJ) {
13700 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13702 pr.hasTopUi = hasTopUi;
13707 updateOomAdjLocked(pr, true);
13711 Binder.restoreCallingIdentity(origId);
13715 public final void enterSafeMode() {
13716 synchronized(this) {
13717 // It only makes sense to do this before the system is ready
13718 // and started launching other packages.
13719 if (!mSystemReady) {
13721 AppGlobals.getPackageManager().enterSafeMode();
13722 } catch (RemoteException e) {
13730 public final void showSafeModeOverlay() {
13731 View v = LayoutInflater.from(mContext).inflate(
13732 com.android.internal.R.layout.safe_mode, null);
13733 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13734 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13735 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13736 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13737 lp.gravity = Gravity.BOTTOM | Gravity.START;
13738 lp.format = v.getBackground().getOpacity();
13739 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13740 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13741 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13742 ((WindowManager)mContext.getSystemService(
13743 Context.WINDOW_SERVICE)).addView(v, lp);
13746 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13747 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13750 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13751 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13752 synchronized (stats) {
13753 if (mBatteryStatsService.isOnBattery()) {
13754 mBatteryStatsService.enforceCallingPermission();
13755 int MY_UID = Binder.getCallingUid();
13757 if (sender == null) {
13760 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13762 BatteryStatsImpl.Uid.Pkg pkg =
13763 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13764 sourcePkg != null ? sourcePkg : rec.key.packageName);
13765 pkg.noteWakeupAlarmLocked(tag);
13770 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13771 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13774 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13775 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13776 synchronized (stats) {
13777 mBatteryStatsService.enforceCallingPermission();
13778 int MY_UID = Binder.getCallingUid();
13780 if (sender == null) {
13783 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13785 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13789 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13790 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13793 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13794 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13795 synchronized (stats) {
13796 mBatteryStatsService.enforceCallingPermission();
13797 int MY_UID = Binder.getCallingUid();
13799 if (sender == null) {
13802 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13804 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13808 public boolean killPids(int[] pids, String pReason, boolean secure) {
13809 if (Binder.getCallingUid() != SYSTEM_UID) {
13810 throw new SecurityException("killPids only available to the system");
13812 String reason = (pReason == null) ? "Unknown" : pReason;
13813 // XXX Note: don't acquire main activity lock here, because the window
13814 // manager calls in with its locks held.
13816 boolean killed = false;
13817 synchronized (mPidsSelfLocked) {
13819 for (int i=0; i<pids.length; i++) {
13820 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13821 if (proc != null) {
13822 int type = proc.setAdj;
13823 if (type > worstType) {
13829 // If the worst oom_adj is somewhere in the cached proc LRU range,
13830 // then constrain it so we will kill all cached procs.
13831 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13832 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13833 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13836 // If this is not a secure call, don't let it kill processes that
13838 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13839 worstType = ProcessList.SERVICE_ADJ;
13842 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13843 for (int i=0; i<pids.length; i++) {
13844 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13845 if (proc == null) {
13848 int adj = proc.setAdj;
13849 if (adj >= worstType && !proc.killedByAm) {
13850 proc.kill(reason, true);
13859 public void killUid(int appId, int userId, String reason) {
13860 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13861 synchronized (this) {
13862 final long identity = Binder.clearCallingIdentity();
13864 killPackageProcessesLocked(null, appId, userId,
13865 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13866 reason != null ? reason : "kill uid");
13868 Binder.restoreCallingIdentity(identity);
13874 public boolean killProcessesBelowForeground(String reason) {
13875 if (Binder.getCallingUid() != SYSTEM_UID) {
13876 throw new SecurityException("killProcessesBelowForeground() only available to system");
13879 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13882 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13883 if (Binder.getCallingUid() != SYSTEM_UID) {
13884 throw new SecurityException("killProcessesBelowAdj() only available to system");
13887 boolean killed = false;
13888 synchronized (mPidsSelfLocked) {
13889 final int size = mPidsSelfLocked.size();
13890 for (int i = 0; i < size; i++) {
13891 final int pid = mPidsSelfLocked.keyAt(i);
13892 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13893 if (proc == null) continue;
13895 final int adj = proc.setAdj;
13896 if (adj > belowAdj && !proc.killedByAm) {
13897 proc.kill(reason, true);
13906 public void hang(final IBinder who, boolean allowRestart) {
13907 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13908 != PackageManager.PERMISSION_GRANTED) {
13909 throw new SecurityException("Requires permission "
13910 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13913 final IBinder.DeathRecipient death = new DeathRecipient() {
13915 public void binderDied() {
13916 synchronized (this) {
13923 who.linkToDeath(death, 0);
13924 } catch (RemoteException e) {
13925 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13929 synchronized (this) {
13930 Watchdog.getInstance().setAllowRestart(allowRestart);
13931 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13932 synchronized (death) {
13933 while (who.isBinderAlive()) {
13936 } catch (InterruptedException e) {
13940 Watchdog.getInstance().setAllowRestart(true);
13945 public void restart() {
13946 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13947 != PackageManager.PERMISSION_GRANTED) {
13948 throw new SecurityException("Requires permission "
13949 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13952 Log.i(TAG, "Sending shutdown broadcast...");
13954 BroadcastReceiver br = new BroadcastReceiver() {
13955 @Override public void onReceive(Context context, Intent intent) {
13956 // Now the broadcast is done, finish up the low-level shutdown.
13957 Log.i(TAG, "Shutting down activity manager...");
13959 Log.i(TAG, "Shutdown complete, restarting!");
13960 killProcess(myPid());
13965 // First send the high-level shut down broadcast.
13966 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13967 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13968 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13969 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13970 mContext.sendOrderedBroadcastAsUser(intent,
13971 UserHandle.ALL, null, br, mHandler, 0, null, null);
13973 br.onReceive(mContext, intent);
13976 private long getLowRamTimeSinceIdle(long now) {
13977 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13981 public void performIdleMaintenance() {
13982 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13983 != PackageManager.PERMISSION_GRANTED) {
13984 throw new SecurityException("Requires permission "
13985 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13988 synchronized (this) {
13989 final long now = SystemClock.uptimeMillis();
13990 final long timeSinceLastIdle = now - mLastIdleTime;
13991 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13992 mLastIdleTime = now;
13993 mLowRamTimeSinceLastIdle = 0;
13994 if (mLowRamStartTime != 0) {
13995 mLowRamStartTime = now;
13998 StringBuilder sb = new StringBuilder(128);
13999 sb.append("Idle maintenance over ");
14000 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14001 sb.append(" low RAM for ");
14002 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14003 Slog.i(TAG, sb.toString());
14005 // If at least 1/3 of our time since the last idle period has been spent
14006 // with RAM low, then we want to kill processes.
14007 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14009 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14010 ProcessRecord proc = mLruProcesses.get(i);
14011 if (proc.notCachedSinceIdle) {
14012 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14013 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14014 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14015 if (doKilling && proc.initialIdlePss != 0
14016 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14017 sb = new StringBuilder(128);
14019 sb.append(proc.processName);
14020 sb.append(" in idle maint: pss=");
14021 sb.append(proc.lastPss);
14022 sb.append(", swapPss=");
14023 sb.append(proc.lastSwapPss);
14024 sb.append(", initialPss=");
14025 sb.append(proc.initialIdlePss);
14026 sb.append(", period=");
14027 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14028 sb.append(", lowRamPeriod=");
14029 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14030 Slog.wtfQuiet(TAG, sb.toString());
14031 proc.kill("idle maint (pss " + proc.lastPss
14032 + " from " + proc.initialIdlePss + ")", true);
14035 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14036 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14037 proc.notCachedSinceIdle = true;
14038 proc.initialIdlePss = 0;
14039 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14040 mTestPssMode, isSleepingLocked(), now);
14044 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14045 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14050 public void sendIdleJobTrigger() {
14051 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14052 != PackageManager.PERMISSION_GRANTED) {
14053 throw new SecurityException("Requires permission "
14054 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14057 final long ident = Binder.clearCallingIdentity();
14059 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14060 .setPackage("android")
14061 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14062 broadcastIntent(null, intent, null, null, 0, null, null, null,
14063 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14065 Binder.restoreCallingIdentity(ident);
14069 private void retrieveSettings() {
14070 final ContentResolver resolver = mContext.getContentResolver();
14071 final boolean freeformWindowManagement =
14072 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14073 || Settings.Global.getInt(
14074 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14076 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14077 final boolean supportsPictureInPicture = supportsMultiWindow &&
14078 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14079 final boolean supportsSplitScreenMultiWindow =
14080 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14081 final boolean supportsMultiDisplay = mContext.getPackageManager()
14082 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14083 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14084 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14085 final boolean alwaysFinishActivities =
14086 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14087 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14088 final boolean forceResizable = Settings.Global.getInt(
14089 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14090 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14091 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14092 final boolean supportsLeanbackOnly =
14093 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14095 // Transfer any global setting for forcing RTL layout, into a System Property
14096 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14098 final Configuration configuration = new Configuration();
14099 Settings.System.getConfiguration(resolver, configuration);
14101 // This will take care of setting the correct layout direction flags
14102 configuration.setLayoutDirection(configuration.locale);
14105 synchronized (this) {
14106 mDebugApp = mOrigDebugApp = debugApp;
14107 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14108 mAlwaysFinishActivities = alwaysFinishActivities;
14109 mSupportsLeanbackOnly = supportsLeanbackOnly;
14110 mForceResizableActivities = forceResizable;
14111 final boolean multiWindowFormEnabled = freeformWindowManagement
14112 || supportsSplitScreenMultiWindow
14113 || supportsPictureInPicture
14114 || supportsMultiDisplay;
14115 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14116 mSupportsMultiWindow = true;
14117 mSupportsFreeformWindowManagement = freeformWindowManagement;
14118 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14119 mSupportsPictureInPicture = supportsPictureInPicture;
14120 mSupportsMultiDisplay = supportsMultiDisplay;
14122 mSupportsMultiWindow = false;
14123 mSupportsFreeformWindowManagement = false;
14124 mSupportsSplitScreenMultiWindow = false;
14125 mSupportsPictureInPicture = false;
14126 mSupportsMultiDisplay = false;
14128 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14129 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14130 // This happens before any activities are started, so we can change global configuration
14132 updateConfigurationLocked(configuration, null, true);
14133 final Configuration globalConfig = getGlobalConfiguration();
14134 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14136 // Load resources only after the current configuration has been set.
14137 final Resources res = mContext.getResources();
14138 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14139 mThumbnailWidth = res.getDimensionPixelSize(
14140 com.android.internal.R.dimen.thumbnail_width);
14141 mThumbnailHeight = res.getDimensionPixelSize(
14142 com.android.internal.R.dimen.thumbnail_height);
14143 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14144 com.android.internal.R.string.config_appsNotReportingCrashes));
14145 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14146 com.android.internal.R.bool.config_customUserSwitchUi);
14147 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14148 mFullscreenThumbnailScale = (float) res
14149 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14150 (float) globalConfig.screenWidthDp;
14152 mFullscreenThumbnailScale = res.getFraction(
14153 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14155 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14159 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14160 traceLog.traceBegin("PhaseActivityManagerReady");
14161 synchronized(this) {
14162 if (mSystemReady) {
14163 // If we're done calling all the receivers, run the next "boot phase" passed in
14164 // by the SystemServer
14165 if (goingCallback != null) {
14166 goingCallback.run();
14171 mLocalDeviceIdleController
14172 = LocalServices.getService(DeviceIdleController.LocalService.class);
14173 mAssistUtils = new AssistUtils(mContext);
14174 mVrController.onSystemReady();
14175 // Make sure we have the current profile info, since it is needed for security checks.
14176 mUserController.onSystemReady();
14177 mRecentTasks.onSystemReadyLocked();
14178 mAppOpsService.systemReady();
14179 mSystemReady = true;
14183 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14184 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14186 } catch (RemoteException e) {}
14188 ArrayList<ProcessRecord> procsToKill = null;
14189 synchronized(mPidsSelfLocked) {
14190 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14191 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14192 if (!isAllowedWhileBooting(proc.info)){
14193 if (procsToKill == null) {
14194 procsToKill = new ArrayList<ProcessRecord>();
14196 procsToKill.add(proc);
14201 synchronized(this) {
14202 if (procsToKill != null) {
14203 for (int i=procsToKill.size()-1; i>=0; i--) {
14204 ProcessRecord proc = procsToKill.get(i);
14205 Slog.i(TAG, "Removing system update proc: " + proc);
14206 removeProcessLocked(proc, true, false, "system update done");
14210 // Now that we have cleaned up any update processes, we
14211 // are ready to start launching real processes and know that
14212 // we won't trample on them any more.
14213 mProcessesReady = true;
14216 Slog.i(TAG, "System now ready");
14217 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14218 SystemClock.uptimeMillis());
14220 synchronized(this) {
14221 // Make sure we have no pre-ready processes sitting around.
14223 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14224 ResolveInfo ri = mContext.getPackageManager()
14225 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14227 CharSequence errorMsg = null;
14229 ActivityInfo ai = ri.activityInfo;
14230 ApplicationInfo app = ai.applicationInfo;
14231 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14232 mTopAction = Intent.ACTION_FACTORY_TEST;
14234 mTopComponent = new ComponentName(app.packageName,
14237 errorMsg = mContext.getResources().getText(
14238 com.android.internal.R.string.factorytest_not_system);
14241 errorMsg = mContext.getResources().getText(
14242 com.android.internal.R.string.factorytest_no_action);
14244 if (errorMsg != null) {
14247 mTopComponent = null;
14248 Message msg = Message.obtain();
14249 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14250 msg.getData().putCharSequence("msg", errorMsg);
14251 mUiHandler.sendMessage(msg);
14256 retrieveSettings();
14257 final int currentUserId;
14258 synchronized (this) {
14259 currentUserId = mUserController.getCurrentUserIdLocked();
14260 readGrantedUriPermissionsLocked();
14263 if (goingCallback != null) goingCallback.run();
14264 traceLog.traceBegin("ActivityManagerStartApps");
14265 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14266 Integer.toString(currentUserId), currentUserId);
14267 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14268 Integer.toString(currentUserId), currentUserId);
14269 mSystemServiceManager.startUser(currentUserId);
14271 synchronized (this) {
14272 // Only start up encryption-aware persistent apps; once user is
14273 // unlocked we'll come back around and start unaware apps
14274 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14276 // Start up initial activity.
14278 // Enable home activity for system user, so that the system can always boot. We don't
14279 // do this when the system user is not setup since the setup wizard should be the one
14280 // to handle home activity in this case.
14281 if (UserManager.isSplitSystemUser() &&
14282 Settings.Secure.getInt(mContext.getContentResolver(),
14283 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14284 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14286 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14287 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14288 UserHandle.USER_SYSTEM);
14289 } catch (RemoteException e) {
14290 throw e.rethrowAsRuntimeException();
14293 startHomeActivityLocked(currentUserId, "systemReady");
14296 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14297 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14298 + " data partition or your device will be unstable.");
14299 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14301 } catch (RemoteException e) {
14304 if (!Build.isBuildConsistent()) {
14305 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14306 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14309 long ident = Binder.clearCallingIdentity();
14311 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14312 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14313 | Intent.FLAG_RECEIVER_FOREGROUND);
14314 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14315 broadcastIntentLocked(null, null, intent,
14316 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14317 null, false, false, MY_PID, SYSTEM_UID,
14319 intent = new Intent(Intent.ACTION_USER_STARTING);
14320 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14321 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14322 broadcastIntentLocked(null, null, intent,
14323 null, new IIntentReceiver.Stub() {
14325 public void performReceive(Intent intent, int resultCode, String data,
14326 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14327 throws RemoteException {
14330 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14331 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14332 } catch (Throwable t) {
14333 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14335 Binder.restoreCallingIdentity(ident);
14337 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14338 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14339 traceLog.traceEnd(); // ActivityManagerStartApps
14340 traceLog.traceEnd(); // PhaseActivityManagerReady
14344 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14345 synchronized (this) {
14346 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14350 void skipCurrentReceiverLocked(ProcessRecord app) {
14351 for (BroadcastQueue queue : mBroadcastQueues) {
14352 queue.skipCurrentReceiverLocked(app);
14357 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14358 * The application process will exit immediately after this call returns.
14359 * @param app object of the crashing app, null for the system server
14360 * @param crashInfo describing the exception
14362 public void handleApplicationCrash(IBinder app,
14363 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14364 ProcessRecord r = findAppProcess(app, "Crash");
14365 final String processName = app == null ? "system_server"
14366 : (r == null ? "unknown" : r.processName);
14368 handleApplicationCrashInner("crash", r, processName, crashInfo);
14371 /* Native crash reporting uses this inner version because it needs to be somewhat
14372 * decoupled from the AM-managed cleanup lifecycle
14374 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14375 ApplicationErrorReport.CrashInfo crashInfo) {
14376 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14377 UserHandle.getUserId(Binder.getCallingUid()), processName,
14378 r == null ? -1 : r.info.flags,
14379 crashInfo.exceptionClassName,
14380 crashInfo.exceptionMessage,
14381 crashInfo.throwFileName,
14382 crashInfo.throwLineNumber);
14384 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14386 mAppErrors.crashApplication(r, crashInfo);
14389 public void handleApplicationStrictModeViolation(
14392 StrictMode.ViolationInfo info) {
14393 ProcessRecord r = findAppProcess(app, "StrictMode");
14398 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14399 Integer stackFingerprint = info.hashCode();
14400 boolean logIt = true;
14401 synchronized (mAlreadyLoggedViolatedStacks) {
14402 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14404 // TODO: sub-sample into EventLog for these, with
14405 // the info.durationMillis? Then we'd get
14406 // the relative pain numbers, without logging all
14407 // the stack traces repeatedly. We'd want to do
14408 // likewise in the client code, which also does
14409 // dup suppression, before the Binder call.
14411 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14412 mAlreadyLoggedViolatedStacks.clear();
14414 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14418 logStrictModeViolationToDropBox(r, info);
14422 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14423 AppErrorResult result = new AppErrorResult();
14424 synchronized (this) {
14425 final long origId = Binder.clearCallingIdentity();
14427 Message msg = Message.obtain();
14428 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14429 HashMap<String, Object> data = new HashMap<String, Object>();
14430 data.put("result", result);
14431 data.put("app", r);
14432 data.put("violationMask", violationMask);
14433 data.put("info", info);
14435 mUiHandler.sendMessage(msg);
14437 Binder.restoreCallingIdentity(origId);
14439 int res = result.get();
14440 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14444 // Depending on the policy in effect, there could be a bunch of
14445 // these in quick succession so we try to batch these together to
14446 // minimize disk writes, number of dropbox entries, and maximize
14447 // compression, by having more fewer, larger records.
14448 private void logStrictModeViolationToDropBox(
14449 ProcessRecord process,
14450 StrictMode.ViolationInfo info) {
14451 if (info == null) {
14454 final boolean isSystemApp = process == null ||
14455 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14456 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14457 final String processName = process == null ? "unknown" : process.processName;
14458 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14459 final DropBoxManager dbox = (DropBoxManager)
14460 mContext.getSystemService(Context.DROPBOX_SERVICE);
14462 // Exit early if the dropbox isn't configured to accept this report type.
14463 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14465 boolean bufferWasEmpty;
14466 boolean needsFlush;
14467 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14468 synchronized (sb) {
14469 bufferWasEmpty = sb.length() == 0;
14470 appendDropBoxProcessHeaders(process, processName, sb);
14471 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14472 sb.append("System-App: ").append(isSystemApp).append("\n");
14473 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14474 if (info.violationNumThisLoop != 0) {
14475 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14477 if (info.numAnimationsRunning != 0) {
14478 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14480 if (info.broadcastIntentAction != null) {
14481 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14483 if (info.durationMillis != -1) {
14484 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14486 if (info.numInstances != -1) {
14487 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14489 if (info.tags != null) {
14490 for (String tag : info.tags) {
14491 sb.append("Span-Tag: ").append(tag).append("\n");
14495 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14496 sb.append(info.crashInfo.stackTrace);
14499 if (info.message != null) {
14500 sb.append(info.message);
14504 // Only buffer up to ~64k. Various logging bits truncate
14506 needsFlush = (sb.length() > 64 * 1024);
14509 // Flush immediately if the buffer's grown too large, or this
14510 // is a non-system app. Non-system apps are isolated with a
14511 // different tag & policy and not batched.
14513 // Batching is useful during internal testing with
14514 // StrictMode settings turned up high. Without batching,
14515 // thousands of separate files could be created on boot.
14516 if (!isSystemApp || needsFlush) {
14517 new Thread("Error dump: " + dropboxTag) {
14519 public void run() {
14521 synchronized (sb) {
14522 report = sb.toString();
14523 sb.delete(0, sb.length());
14526 if (report.length() != 0) {
14527 dbox.addText(dropboxTag, report);
14534 // System app batching:
14535 if (!bufferWasEmpty) {
14536 // An existing dropbox-writing thread is outstanding, so
14537 // we don't need to start it up. The existing thread will
14538 // catch the buffer appends we just did.
14542 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14543 // (After this point, we shouldn't access AMS internal data structures.)
14544 new Thread("Error dump: " + dropboxTag) {
14546 public void run() {
14547 // 5 second sleep to let stacks arrive and be batched together
14549 Thread.sleep(5000); // 5 seconds
14550 } catch (InterruptedException e) {}
14552 String errorReport;
14553 synchronized (mStrictModeBuffer) {
14554 errorReport = mStrictModeBuffer.toString();
14555 if (errorReport.length() == 0) {
14558 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14559 mStrictModeBuffer.trimToSize();
14561 dbox.addText(dropboxTag, errorReport);
14567 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14568 * @param app object of the crashing app, null for the system server
14569 * @param tag reported by the caller
14570 * @param system whether this wtf is coming from the system
14571 * @param crashInfo describing the context of the error
14572 * @return true if the process should exit immediately (WTF is fatal)
14574 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14575 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14576 final int callingUid = Binder.getCallingUid();
14577 final int callingPid = Binder.getCallingPid();
14580 // If this is coming from the system, we could very well have low-level
14581 // system locks held, so we want to do this all asynchronously. And we
14582 // never want this to become fatal, so there is that too.
14583 mHandler.post(new Runnable() {
14584 @Override public void run() {
14585 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14591 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14594 final boolean isFatal = Build.IS_ENG || Settings.Global
14595 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14596 final boolean isSystem = (r == null) || r.persistent;
14598 if (isFatal && !isSystem) {
14599 mAppErrors.crashApplication(r, crashInfo);
14606 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14607 final ApplicationErrorReport.CrashInfo crashInfo) {
14608 final ProcessRecord r = findAppProcess(app, "WTF");
14609 final String processName = app == null ? "system_server"
14610 : (r == null ? "unknown" : r.processName);
14612 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14613 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14615 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14621 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14622 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14624 private ProcessRecord findAppProcess(IBinder app, String reason) {
14629 synchronized (this) {
14630 final int NP = mProcessNames.getMap().size();
14631 for (int ip=0; ip<NP; ip++) {
14632 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14633 final int NA = apps.size();
14634 for (int ia=0; ia<NA; ia++) {
14635 ProcessRecord p = apps.valueAt(ia);
14636 if (p.thread != null && p.thread.asBinder() == app) {
14642 Slog.w(TAG, "Can't find mystery application for " + reason
14643 + " from pid=" + Binder.getCallingPid()
14644 + " uid=" + Binder.getCallingUid() + ": " + app);
14650 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14651 * to append various headers to the dropbox log text.
14653 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14654 StringBuilder sb) {
14655 // Watchdog thread ends up invoking this function (with
14656 // a null ProcessRecord) to add the stack file to dropbox.
14657 // Do not acquire a lock on this (am) in such cases, as it
14658 // could cause a potential deadlock, if and when watchdog
14659 // is invoked due to unavailability of lock on am and it
14660 // would prevent watchdog from killing system_server.
14661 if (process == null) {
14662 sb.append("Process: ").append(processName).append("\n");
14665 // Note: ProcessRecord 'process' is guarded by the service
14666 // instance. (notably process.pkgList, which could otherwise change
14667 // concurrently during execution of this method)
14668 synchronized (this) {
14669 sb.append("Process: ").append(processName).append("\n");
14670 sb.append("PID: ").append(process.pid).append("\n");
14671 int flags = process.info.flags;
14672 IPackageManager pm = AppGlobals.getPackageManager();
14673 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14674 for (int ip=0; ip<process.pkgList.size(); ip++) {
14675 String pkg = process.pkgList.keyAt(ip);
14676 sb.append("Package: ").append(pkg);
14678 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14680 sb.append(" v").append(pi.versionCode);
14681 if (pi.versionName != null) {
14682 sb.append(" (").append(pi.versionName).append(")");
14685 } catch (RemoteException e) {
14686 Slog.e(TAG, "Error getting package info: " + pkg, e);
14690 if (process.info.isInstantApp()) {
14691 sb.append("Instant-App: true\n");
14696 private static String processClass(ProcessRecord process) {
14697 if (process == null || process.pid == MY_PID) {
14698 return "system_server";
14699 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14700 return "system_app";
14706 private volatile long mWtfClusterStart;
14707 private volatile int mWtfClusterCount;
14710 * Write a description of an error (crash, WTF, ANR) to the drop box.
14711 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14712 * @param process which caused the error, null means the system server
14713 * @param activity which triggered the error, null if unknown
14714 * @param parent activity related to the error, null if unknown
14715 * @param subject line related to the error, null if absent
14716 * @param report in long form describing the error, null if absent
14717 * @param dataFile text file to include in the report, null if none
14718 * @param crashInfo giving an application stack trace, null if absent
14720 public void addErrorToDropBox(String eventType,
14721 ProcessRecord process, String processName, ActivityRecord activity,
14722 ActivityRecord parent, String subject,
14723 final String report, final File dataFile,
14724 final ApplicationErrorReport.CrashInfo crashInfo) {
14725 // NOTE -- this must never acquire the ActivityManagerService lock,
14726 // otherwise the watchdog may be prevented from resetting the system.
14728 // Bail early if not published yet
14729 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14730 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14732 // Exit early if the dropbox isn't configured to accept this report type.
14733 final String dropboxTag = processClass(process) + "_" + eventType;
14734 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14736 // Rate-limit how often we're willing to do the heavy lifting below to
14737 // collect and record logs; currently 5 logs per 10 second period.
14738 final long now = SystemClock.elapsedRealtime();
14739 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14740 mWtfClusterStart = now;
14741 mWtfClusterCount = 1;
14743 if (mWtfClusterCount++ >= 5) return;
14746 final StringBuilder sb = new StringBuilder(1024);
14747 appendDropBoxProcessHeaders(process, processName, sb);
14748 if (process != null) {
14749 sb.append("Foreground: ")
14750 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14753 if (activity != null) {
14754 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14756 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14757 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14759 if (parent != null && parent != activity) {
14760 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14762 if (subject != null) {
14763 sb.append("Subject: ").append(subject).append("\n");
14765 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14766 if (Debug.isDebuggerConnected()) {
14767 sb.append("Debugger: Connected\n");
14771 // Do the rest in a worker thread to avoid blocking the caller on I/O
14772 // (After this point, we shouldn't access AMS internal data structures.)
14773 Thread worker = new Thread("Error dump: " + dropboxTag) {
14775 public void run() {
14776 if (report != null) {
14780 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14781 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14782 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14783 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14785 if (dataFile != null && maxDataFileSize > 0) {
14787 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14788 "\n\n[[TRUNCATED]]"));
14789 } catch (IOException e) {
14790 Slog.e(TAG, "Error reading " + dataFile, e);
14793 if (crashInfo != null && crashInfo.stackTrace != null) {
14794 sb.append(crashInfo.stackTrace);
14800 // Merge several logcat streams, and take the last N lines
14801 InputStreamReader input = null;
14803 java.lang.Process logcat = new ProcessBuilder(
14804 "/system/bin/timeout", "-k", "15s", "10s",
14805 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14806 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14807 .redirectErrorStream(true).start();
14809 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14810 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14811 input = new InputStreamReader(logcat.getInputStream());
14814 char[] buf = new char[8192];
14815 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14816 } catch (IOException e) {
14817 Slog.e(TAG, "Error running logcat", e);
14819 if (input != null) try { input.close(); } catch (IOException e) {}
14823 dbox.addText(dropboxTag, sb.toString());
14827 if (process == null) {
14828 // If process is null, we are being called from some internal code
14829 // and may be about to die -- run this synchronously.
14837 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14838 enforceNotIsolatedCaller("getProcessesInErrorState");
14839 // assume our apps are happy - lazy create the list
14840 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14842 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14843 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14844 int userId = UserHandle.getUserId(Binder.getCallingUid());
14846 synchronized (this) {
14848 // iterate across all processes
14849 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14850 ProcessRecord app = mLruProcesses.get(i);
14851 if (!allUsers && app.userId != userId) {
14854 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14855 // This one's in trouble, so we'll generate a report for it
14856 // crashes are higher priority (in case there's a crash *and* an anr)
14857 ActivityManager.ProcessErrorStateInfo report = null;
14858 if (app.crashing) {
14859 report = app.crashingReport;
14860 } else if (app.notResponding) {
14861 report = app.notRespondingReport;
14864 if (report != null) {
14865 if (errList == null) {
14866 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14868 errList.add(report);
14870 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14871 " crashing = " + app.crashing +
14872 " notResponding = " + app.notResponding);
14881 static int procStateToImportance(int procState, int memAdj,
14882 ActivityManager.RunningAppProcessInfo currApp,
14883 int clientTargetSdk) {
14884 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14885 procState, clientTargetSdk);
14886 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14887 currApp.lru = memAdj;
14894 private void fillInProcMemInfo(ProcessRecord app,
14895 ActivityManager.RunningAppProcessInfo outInfo,
14896 int clientTargetSdk) {
14897 outInfo.pid = app.pid;
14898 outInfo.uid = app.info.uid;
14899 if (mHeavyWeightProcess == app) {
14900 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14902 if (app.persistent) {
14903 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14905 if (app.activities.size() > 0) {
14906 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14908 outInfo.lastTrimLevel = app.trimMemoryLevel;
14909 int adj = app.curAdj;
14910 int procState = app.curProcState;
14911 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14912 outInfo.importanceReasonCode = app.adjTypeCode;
14913 outInfo.processState = app.curProcState;
14917 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14918 enforceNotIsolatedCaller("getRunningAppProcesses");
14920 final int callingUid = Binder.getCallingUid();
14921 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14923 // Lazy instantiation of list
14924 List<ActivityManager.RunningAppProcessInfo> runList = null;
14925 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14926 callingUid) == PackageManager.PERMISSION_GRANTED;
14927 final int userId = UserHandle.getUserId(callingUid);
14928 final boolean allUids = isGetTasksAllowed(
14929 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14931 synchronized (this) {
14932 // Iterate across all processes
14933 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14934 ProcessRecord app = mLruProcesses.get(i);
14935 if ((!allUsers && app.userId != userId)
14936 || (!allUids && app.uid != callingUid)) {
14939 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14940 // Generate process state info for running application
14941 ActivityManager.RunningAppProcessInfo currApp =
14942 new ActivityManager.RunningAppProcessInfo(app.processName,
14943 app.pid, app.getPackageList());
14944 fillInProcMemInfo(app, currApp, clientTargetSdk);
14945 if (app.adjSource instanceof ProcessRecord) {
14946 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14947 currApp.importanceReasonImportance =
14948 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14949 app.adjSourceProcState);
14950 } else if (app.adjSource instanceof ActivityRecord) {
14951 ActivityRecord r = (ActivityRecord)app.adjSource;
14952 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14954 if (app.adjTarget instanceof ComponentName) {
14955 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14957 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14958 // + " lru=" + currApp.lru);
14959 if (runList == null) {
14960 runList = new ArrayList<>();
14962 runList.add(currApp);
14970 public List<ApplicationInfo> getRunningExternalApplications() {
14971 enforceNotIsolatedCaller("getRunningExternalApplications");
14972 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14973 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14974 if (runningApps != null && runningApps.size() > 0) {
14975 Set<String> extList = new HashSet<String>();
14976 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14977 if (app.pkgList != null) {
14978 for (String pkg : app.pkgList) {
14983 IPackageManager pm = AppGlobals.getPackageManager();
14984 for (String pkg : extList) {
14986 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14987 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14990 } catch (RemoteException e) {
14998 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14999 enforceNotIsolatedCaller("getMyMemoryState");
15001 final int callingUid = Binder.getCallingUid();
15002 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15004 synchronized (this) {
15005 ProcessRecord proc;
15006 synchronized (mPidsSelfLocked) {
15007 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15009 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15014 public int getMemoryTrimLevel() {
15015 enforceNotIsolatedCaller("getMyMemoryState");
15016 synchronized (this) {
15017 return mLastMemoryLevel;
15022 public void onShellCommand(FileDescriptor in, FileDescriptor out,
15023 FileDescriptor err, String[] args, ShellCallback callback,
15024 ResultReceiver resultReceiver) {
15025 (new ActivityManagerShellCommand(this, false)).exec(
15026 this, in, out, err, args, callback, resultReceiver);
15029 SleepToken acquireSleepToken(String tag, int displayId) {
15030 synchronized (this) {
15031 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15032 updateSleepIfNeededLocked();
15038 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15039 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15041 boolean dumpAll = false;
15042 boolean dumpClient = false;
15043 boolean dumpCheckin = false;
15044 boolean dumpCheckinFormat = false;
15045 boolean dumpVisibleStacksOnly = false;
15046 boolean dumpFocusedStackOnly = false;
15047 String dumpPackage = null;
15050 while (opti < args.length) {
15051 String opt = args[opti];
15052 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15056 if ("-a".equals(opt)) {
15058 } else if ("-c".equals(opt)) {
15060 } else if ("-v".equals(opt)) {
15061 dumpVisibleStacksOnly = true;
15062 } else if ("-f".equals(opt)) {
15063 dumpFocusedStackOnly = true;
15064 } else if ("-p".equals(opt)) {
15065 if (opti < args.length) {
15066 dumpPackage = args[opti];
15069 pw.println("Error: -p option requires package argument");
15073 } else if ("--checkin".equals(opt)) {
15074 dumpCheckin = dumpCheckinFormat = true;
15075 } else if ("-C".equals(opt)) {
15076 dumpCheckinFormat = true;
15077 } else if ("-h".equals(opt)) {
15078 ActivityManagerShellCommand.dumpHelp(pw, true);
15081 pw.println("Unknown argument: " + opt + "; use -h for help");
15085 long origId = Binder.clearCallingIdentity();
15086 boolean more = false;
15087 // Is the caller requesting to dump a particular piece of data?
15088 if (opti < args.length) {
15089 String cmd = args[opti];
15091 if ("activities".equals(cmd) || "a".equals(cmd)) {
15092 synchronized (this) {
15093 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15095 } else if ("lastanr".equals(cmd)) {
15096 synchronized (this) {
15097 dumpLastANRLocked(pw);
15099 } else if ("starter".equals(cmd)) {
15100 synchronized (this) {
15101 dumpActivityStarterLocked(pw, dumpPackage);
15103 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15104 synchronized (this) {
15105 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15107 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15110 if (opti >= args.length) {
15112 newArgs = EMPTY_STRING_ARRAY;
15114 dumpPackage = args[opti];
15116 newArgs = new String[args.length - opti];
15117 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15118 args.length - opti);
15120 synchronized (this) {
15121 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15123 } else if ("broadcast-stats".equals(cmd)) {
15126 if (opti >= args.length) {
15128 newArgs = EMPTY_STRING_ARRAY;
15130 dumpPackage = args[opti];
15132 newArgs = new String[args.length - opti];
15133 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15134 args.length - opti);
15136 synchronized (this) {
15137 if (dumpCheckinFormat) {
15138 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15141 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15144 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15147 if (opti >= args.length) {
15149 newArgs = EMPTY_STRING_ARRAY;
15151 dumpPackage = args[opti];
15153 newArgs = new String[args.length - opti];
15154 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15155 args.length - opti);
15157 synchronized (this) {
15158 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15160 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15163 if (opti >= args.length) {
15165 newArgs = EMPTY_STRING_ARRAY;
15167 dumpPackage = args[opti];
15169 newArgs = new String[args.length - opti];
15170 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15171 args.length - opti);
15173 synchronized (this) {
15174 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15176 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15177 synchronized (this) {
15178 dumpOomLocked(fd, pw, args, opti, true);
15180 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15181 synchronized (this) {
15182 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15184 } else if ("provider".equals(cmd)) {
15187 if (opti >= args.length) {
15189 newArgs = EMPTY_STRING_ARRAY;
15193 newArgs = new String[args.length - opti];
15194 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15196 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15197 pw.println("No providers match: " + name);
15198 pw.println("Use -h for help.");
15200 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15201 synchronized (this) {
15202 dumpProvidersLocked(fd, pw, args, opti, true, null);
15204 } else if ("service".equals(cmd)) {
15207 if (opti >= args.length) {
15209 newArgs = EMPTY_STRING_ARRAY;
15213 newArgs = new String[args.length - opti];
15214 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15215 args.length - opti);
15217 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15218 pw.println("No services match: " + name);
15219 pw.println("Use -h for help.");
15221 } else if ("package".equals(cmd)) {
15223 if (opti >= args.length) {
15224 pw.println("package: no package name specified");
15225 pw.println("Use -h for help.");
15227 dumpPackage = args[opti];
15229 newArgs = new String[args.length - opti];
15230 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15231 args.length - opti);
15236 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15237 synchronized (this) {
15238 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15240 } else if ("settings".equals(cmd)) {
15241 synchronized (this) {
15242 mConstants.dump(pw);
15244 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15246 ActiveServices.ServiceDumper dumper;
15247 synchronized (this) {
15248 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15251 dumper.dumpWithClient();
15253 synchronized (this) {
15254 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15255 dumpPackage).dumpLocked();
15258 } else if ("locks".equals(cmd)) {
15259 LockGuard.dump(fd, pw, args);
15261 // Dumping a single activity?
15262 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15263 dumpFocusedStackOnly)) {
15264 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15265 int res = shell.exec(this, null, fd, null, args, null,
15266 new ResultReceiver(null));
15268 pw.println("Bad activity command, or no activities match: " + cmd);
15269 pw.println("Use -h for help.");
15274 Binder.restoreCallingIdentity(origId);
15279 // No piece of data specified, dump everything.
15280 if (dumpCheckinFormat) {
15281 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15282 } else if (dumpClient) {
15283 ActiveServices.ServiceDumper sdumper;
15284 synchronized (this) {
15285 mConstants.dump(pw);
15288 pw.println("-------------------------------------------------------------------------------");
15290 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15293 pw.println("-------------------------------------------------------------------------------");
15295 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15298 pw.println("-------------------------------------------------------------------------------");
15300 if (dumpAll || dumpPackage != null) {
15301 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15304 pw.println("-------------------------------------------------------------------------------");
15307 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15310 pw.println("-------------------------------------------------------------------------------");
15312 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15315 pw.println("-------------------------------------------------------------------------------");
15317 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15320 sdumper.dumpWithClient();
15322 synchronized (this) {
15324 pw.println("-------------------------------------------------------------------------------");
15326 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15329 pw.println("-------------------------------------------------------------------------------");
15331 dumpLastANRLocked(pw);
15334 pw.println("-------------------------------------------------------------------------------");
15336 dumpActivityStarterLocked(pw, dumpPackage);
15339 pw.println("-------------------------------------------------------------------------------");
15341 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15342 if (mAssociations.size() > 0) {
15345 pw.println("-------------------------------------------------------------------------------");
15347 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15351 pw.println("-------------------------------------------------------------------------------");
15353 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15357 synchronized (this) {
15358 mConstants.dump(pw);
15361 pw.println("-------------------------------------------------------------------------------");
15363 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15366 pw.println("-------------------------------------------------------------------------------");
15368 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15371 pw.println("-------------------------------------------------------------------------------");
15373 if (dumpAll || dumpPackage != null) {
15374 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15377 pw.println("-------------------------------------------------------------------------------");
15380 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15383 pw.println("-------------------------------------------------------------------------------");
15385 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15388 pw.println("-------------------------------------------------------------------------------");
15390 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15394 pw.println("-------------------------------------------------------------------------------");
15396 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15399 pw.println("-------------------------------------------------------------------------------");
15401 dumpLastANRLocked(pw);
15404 pw.println("-------------------------------------------------------------------------------");
15406 dumpActivityStarterLocked(pw, dumpPackage);
15409 pw.println("-------------------------------------------------------------------------------");
15411 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15412 if (mAssociations.size() > 0) {
15415 pw.println("-------------------------------------------------------------------------------");
15417 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15421 pw.println("-------------------------------------------------------------------------------");
15423 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15426 Binder.restoreCallingIdentity(origId);
15429 private void dumpLastANRLocked(PrintWriter pw) {
15430 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15431 if (mLastANRState == null) {
15432 pw.println(" <no ANR has occurred since boot>");
15434 pw.println(mLastANRState);
15438 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15439 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15440 mActivityStarter.dump(pw, "", dumpPackage);
15443 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15444 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15445 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15446 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15449 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15450 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15451 pw.println(header);
15453 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15455 boolean needSep = printedAnything;
15457 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15458 mStackSupervisor.getResumedActivityLocked(),
15459 dumpPackage, needSep, " ResumedActivity: ");
15461 printedAnything = true;
15465 if (dumpPackage == null) {
15469 printedAnything = true;
15470 mStackSupervisor.dump(pw, " ");
15473 if (!printedAnything) {
15474 pw.println(" (nothing)");
15478 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15479 int opti, boolean dumpAll, String dumpPackage) {
15480 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15482 boolean printedAnything = false;
15484 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15485 boolean printedHeader = false;
15487 final int N = mRecentTasks.size();
15488 for (int i=0; i<N; i++) {
15489 TaskRecord tr = mRecentTasks.get(i);
15490 if (dumpPackage != null) {
15491 if (tr.realActivity == null ||
15492 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15496 if (!printedHeader) {
15497 pw.println(" Recent tasks:");
15498 printedHeader = true;
15499 printedAnything = true;
15501 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15504 mRecentTasks.get(i).dump(pw, " ");
15509 if (!printedAnything) {
15510 pw.println(" (nothing)");
15514 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15515 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15516 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15519 if (dumpPackage != null) {
15520 IPackageManager pm = AppGlobals.getPackageManager();
15522 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15523 } catch (RemoteException e) {
15527 boolean printedAnything = false;
15529 final long now = SystemClock.uptimeMillis();
15531 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15532 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15533 = mAssociations.valueAt(i1);
15534 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15535 SparseArray<ArrayMap<String, Association>> sourceUids
15536 = targetComponents.valueAt(i2);
15537 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15538 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15539 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15540 Association ass = sourceProcesses.valueAt(i4);
15541 if (dumpPackage != null) {
15542 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15543 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15547 printedAnything = true;
15549 pw.print(ass.mTargetProcess);
15551 UserHandle.formatUid(pw, ass.mTargetUid);
15553 pw.print(ass.mSourceProcess);
15555 UserHandle.formatUid(pw, ass.mSourceUid);
15558 pw.print(ass.mTargetComponent.flattenToShortString());
15561 long dur = ass.mTime;
15562 if (ass.mNesting > 0) {
15563 dur += now - ass.mStartTime;
15565 TimeUtils.formatDuration(dur, pw);
15567 pw.print(ass.mCount);
15568 pw.print(" times)");
15570 for (int i=0; i<ass.mStateTimes.length; i++) {
15571 long amt = ass.mStateTimes[i];
15572 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15573 amt += now - ass.mLastStateUptime;
15577 pw.print(ProcessList.makeProcStateString(
15578 i + ActivityManager.MIN_PROCESS_STATE));
15580 TimeUtils.formatDuration(amt, pw);
15581 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15587 if (ass.mNesting > 0) {
15588 pw.print(" Currently active: ");
15589 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15598 if (!printedAnything) {
15599 pw.println(" (nothing)");
15603 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15604 String header, boolean needSep) {
15605 boolean printed = false;
15606 int whichAppId = -1;
15607 if (dumpPackage != null) {
15609 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15611 whichAppId = UserHandle.getAppId(info.uid);
15612 } catch (NameNotFoundException e) {
15613 e.printStackTrace();
15616 for (int i=0; i<uids.size(); i++) {
15617 UidRecord uidRec = uids.valueAt(i);
15618 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15627 pw.println(header);
15630 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15631 pw.print(": "); pw.println(uidRec);
15636 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15637 int opti, boolean dumpAll, String dumpPackage) {
15638 boolean needSep = false;
15639 boolean printedAnything = false;
15642 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15645 final int NP = mProcessNames.getMap().size();
15646 for (int ip=0; ip<NP; ip++) {
15647 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15648 final int NA = procs.size();
15649 for (int ia=0; ia<NA; ia++) {
15650 ProcessRecord r = procs.valueAt(ia);
15651 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15655 pw.println(" All known processes:");
15657 printedAnything = true;
15659 pw.print(r.persistent ? " *PERS*" : " *APP*");
15660 pw.print(" UID "); pw.print(procs.keyAt(ia));
15661 pw.print(" "); pw.println(r);
15663 if (r.persistent) {
15670 if (mIsolatedProcesses.size() > 0) {
15671 boolean printed = false;
15672 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15673 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15674 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15681 pw.println(" Isolated process list (sorted by uid):");
15682 printedAnything = true;
15686 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15691 if (mActiveInstrumentation.size() > 0) {
15692 boolean printed = false;
15693 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15694 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15695 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15696 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15703 pw.println(" Active instrumentation:");
15704 printedAnything = true;
15708 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15714 if (mActiveUids.size() > 0) {
15715 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15716 printedAnything = needSep = true;
15720 if (mValidateUids.size() > 0) {
15721 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15722 printedAnything = needSep = true;
15727 if (mLruProcesses.size() > 0) {
15731 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15732 pw.print(" total, non-act at ");
15733 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15734 pw.print(", non-svc at ");
15735 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15737 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15739 printedAnything = true;
15742 if (dumpAll || dumpPackage != null) {
15743 synchronized (mPidsSelfLocked) {
15744 boolean printed = false;
15745 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15746 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15747 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15751 if (needSep) pw.println();
15753 pw.println(" PID mappings:");
15755 printedAnything = true;
15757 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15758 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15763 if (mImportantProcesses.size() > 0) {
15764 synchronized (mPidsSelfLocked) {
15765 boolean printed = false;
15766 for (int i = 0; i< mImportantProcesses.size(); i++) {
15767 ProcessRecord r = mPidsSelfLocked.get(
15768 mImportantProcesses.valueAt(i).pid);
15769 if (dumpPackage != null && (r == null
15770 || !r.pkgList.containsKey(dumpPackage))) {
15774 if (needSep) pw.println();
15776 pw.println(" Foreground Processes:");
15778 printedAnything = true;
15780 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15781 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15786 if (mPersistentStartingProcesses.size() > 0) {
15787 if (needSep) pw.println();
15789 printedAnything = true;
15790 pw.println(" Persisent processes that are starting:");
15791 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15792 "Starting Norm", "Restarting PERS", dumpPackage);
15795 if (mRemovedProcesses.size() > 0) {
15796 if (needSep) pw.println();
15798 printedAnything = true;
15799 pw.println(" Processes that are being removed:");
15800 dumpProcessList(pw, this, mRemovedProcesses, " ",
15801 "Removed Norm", "Removed PERS", dumpPackage);
15804 if (mProcessesOnHold.size() > 0) {
15805 if (needSep) pw.println();
15807 printedAnything = true;
15808 pw.println(" Processes that are on old until the system is ready:");
15809 dumpProcessList(pw, this, mProcessesOnHold, " ",
15810 "OnHold Norm", "OnHold PERS", dumpPackage);
15813 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15815 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15817 printedAnything = true;
15820 if (dumpPackage == null) {
15823 mUserController.dump(pw, dumpAll);
15825 if (mHomeProcess != null && (dumpPackage == null
15826 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15831 pw.println(" mHomeProcess: " + mHomeProcess);
15833 if (mPreviousProcess != null && (dumpPackage == null
15834 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15839 pw.println(" mPreviousProcess: " + mPreviousProcess);
15842 StringBuilder sb = new StringBuilder(128);
15843 sb.append(" mPreviousProcessVisibleTime: ");
15844 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15847 if (mHeavyWeightProcess != null && (dumpPackage == null
15848 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15853 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15855 if (dumpPackage == null) {
15856 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15857 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15860 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15861 if (mCompatModePackages.getPackages().size() > 0) {
15862 boolean printed = false;
15863 for (Map.Entry<String, Integer> entry
15864 : mCompatModePackages.getPackages().entrySet()) {
15865 String pkg = entry.getKey();
15866 int mode = entry.getValue();
15867 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15871 pw.println(" mScreenCompatPackages:");
15874 pw.print(" "); pw.print(pkg); pw.print(": ");
15875 pw.print(mode); pw.println();
15878 final int NI = mUidObservers.getRegisteredCallbackCount();
15879 boolean printed = false;
15880 for (int i=0; i<NI; i++) {
15881 final UidObserverRegistration reg = (UidObserverRegistration)
15882 mUidObservers.getRegisteredCallbackCookie(i);
15883 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15885 pw.println(" mUidObservers:");
15888 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15889 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15890 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15893 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15896 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15899 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15900 pw.print(" STATE");
15901 pw.print(" (cut="); pw.print(reg.cutpoint);
15905 if (reg.lastProcStates != null) {
15906 final int NJ = reg.lastProcStates.size();
15907 for (int j=0; j<NJ; j++) {
15908 pw.print(" Last ");
15909 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15910 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15915 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15916 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15917 if (mPendingTempWhitelist.size() > 0) {
15918 pw.println(" mPendingTempWhitelist:");
15919 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15920 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15922 UserHandle.formatUid(pw, ptw.targetUid);
15924 TimeUtils.formatDuration(ptw.duration, pw);
15926 pw.println(ptw.tag);
15930 if (dumpPackage == null) {
15931 pw.println(" mWakefulness="
15932 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15933 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
15934 pw.println(" mSleeping=" + mSleeping);
15935 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15936 if (mRunningVoice != null) {
15937 pw.println(" mRunningVoice=" + mRunningVoice);
15938 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15941 pw.println(" mVrController=" + mVrController);
15942 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15943 || mOrigWaitForDebugger) {
15944 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15945 || dumpPackage.equals(mOrigDebugApp)) {
15950 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15951 + " mDebugTransient=" + mDebugTransient
15952 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15955 if (mCurAppTimeTracker != null) {
15956 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15958 if (mMemWatchProcesses.getMap().size() > 0) {
15959 pw.println(" Mem watch processes:");
15960 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15961 = mMemWatchProcesses.getMap();
15962 for (int i=0; i<procs.size(); i++) {
15963 final String proc = procs.keyAt(i);
15964 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15965 for (int j=0; j<uids.size(); j++) {
15970 StringBuilder sb = new StringBuilder();
15971 sb.append(" ").append(proc).append('/');
15972 UserHandle.formatUid(sb, uids.keyAt(j));
15973 Pair<Long, String> val = uids.valueAt(j);
15974 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15975 if (val.second != null) {
15976 sb.append(", report to ").append(val.second);
15978 pw.println(sb.toString());
15981 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15982 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15983 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15984 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15986 if (mTrackAllocationApp != null) {
15987 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15992 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15995 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15996 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15997 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16002 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16003 if (mProfilerInfo != null) {
16004 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16005 mProfilerInfo.profileFd);
16006 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
16007 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16008 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16009 pw.println(" mProfileType=" + mProfileType);
16013 if (mNativeDebuggingApp != null) {
16014 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16019 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
16022 if (dumpPackage == null) {
16023 if (mAlwaysFinishActivities) {
16024 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16026 if (mController != null) {
16027 pw.println(" mController=" + mController
16028 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16031 pw.println(" Total persistent processes: " + numPers);
16032 pw.println(" mProcessesReady=" + mProcessesReady
16033 + " mSystemReady=" + mSystemReady
16034 + " mBooted=" + mBooted
16035 + " mFactoryTest=" + mFactoryTest);
16036 pw.println(" mBooting=" + mBooting
16037 + " mCallFinishBooting=" + mCallFinishBooting
16038 + " mBootAnimationComplete=" + mBootAnimationComplete);
16039 pw.print(" mLastPowerCheckUptime=");
16040 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16042 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16043 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16044 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16045 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
16046 + " (" + mLruProcesses.size() + " total)"
16047 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16048 + " mNumServiceProcs=" + mNumServiceProcs
16049 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16050 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
16051 + " mLastMemoryLevel=" + mLastMemoryLevel
16052 + " mLastNumProcesses=" + mLastNumProcesses);
16053 long now = SystemClock.uptimeMillis();
16054 pw.print(" mLastIdleTime=");
16055 TimeUtils.formatDuration(now, mLastIdleTime, pw);
16056 pw.print(" mLowRamSinceLastIdle=");
16057 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16062 if (!printedAnything) {
16063 pw.println(" (nothing)");
16067 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16068 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16069 if (mProcessesToGc.size() > 0) {
16070 boolean printed = false;
16071 long now = SystemClock.uptimeMillis();
16072 for (int i=0; i<mProcessesToGc.size(); i++) {
16073 ProcessRecord proc = mProcessesToGc.get(i);
16074 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16078 if (needSep) pw.println();
16080 pw.println(" Processes that are waiting to GC:");
16083 pw.print(" Process "); pw.println(proc);
16084 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16085 pw.print(", last gced=");
16086 pw.print(now-proc.lastRequestedGc);
16087 pw.print(" ms ago, last lowMem=");
16088 pw.print(now-proc.lastLowMemory);
16089 pw.println(" ms ago");
16096 void printOomLevel(PrintWriter pw, String name, int adj) {
16100 if (adj < 10) pw.print(' ');
16102 if (adj > -10) pw.print(' ');
16108 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16112 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16113 int opti, boolean dumpAll) {
16114 boolean needSep = false;
16116 if (mLruProcesses.size() > 0) {
16117 if (needSep) pw.println();
16119 pw.println(" OOM levels:");
16120 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16121 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16122 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16123 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16124 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16125 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16126 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16127 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16128 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16129 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16130 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16131 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16132 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16133 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16135 if (needSep) pw.println();
16136 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16137 pw.print(" total, non-act at ");
16138 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16139 pw.print(", non-svc at ");
16140 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16142 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16146 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16149 pw.println(" mHomeProcess: " + mHomeProcess);
16150 pw.println(" mPreviousProcess: " + mPreviousProcess);
16151 if (mHeavyWeightProcess != null) {
16152 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16159 * There are three ways to call this:
16160 * - no provider specified: dump all the providers
16161 * - a flattened component name that matched an existing provider was specified as the
16162 * first arg: dump that one provider
16163 * - the first arg isn't the flattened component name of an existing provider:
16164 * dump all providers whose component contains the first arg as a substring
16166 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16167 int opti, boolean dumpAll) {
16168 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16171 static class ItemMatcher {
16172 ArrayList<ComponentName> components;
16173 ArrayList<String> strings;
16174 ArrayList<Integer> objects;
16181 void build(String name) {
16182 ComponentName componentName = ComponentName.unflattenFromString(name);
16183 if (componentName != null) {
16184 if (components == null) {
16185 components = new ArrayList<ComponentName>();
16187 components.add(componentName);
16191 // Not a '/' separated full component name; maybe an object ID?
16193 objectId = Integer.parseInt(name, 16);
16194 if (objects == null) {
16195 objects = new ArrayList<Integer>();
16197 objects.add(objectId);
16199 } catch (RuntimeException e) {
16200 // Not an integer; just do string match.
16201 if (strings == null) {
16202 strings = new ArrayList<String>();
16210 int build(String[] args, int opti) {
16211 for (; opti<args.length; opti++) {
16212 String name = args[opti];
16213 if ("--".equals(name)) {
16221 boolean match(Object object, ComponentName comp) {
16225 if (components != null) {
16226 for (int i=0; i<components.size(); i++) {
16227 if (components.get(i).equals(comp)) {
16232 if (objects != null) {
16233 for (int i=0; i<objects.size(); i++) {
16234 if (System.identityHashCode(object) == objects.get(i)) {
16239 if (strings != null) {
16240 String flat = comp.flattenToString();
16241 for (int i=0; i<strings.size(); i++) {
16242 if (flat.contains(strings.get(i))) {
16252 * There are three things that cmd can be:
16253 * - a flattened component name that matches an existing activity
16254 * - the cmd arg isn't the flattened component name of an existing activity:
16255 * dump all activity whose component contains the cmd as a substring
16256 * - A hex number of the ActivityRecord object instance.
16258 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16259 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16261 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16262 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16263 ArrayList<ActivityRecord> activities;
16265 synchronized (this) {
16266 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16267 dumpFocusedStackOnly);
16270 if (activities.size() <= 0) {
16274 String[] newArgs = new String[args.length - opti];
16275 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16277 TaskRecord lastTask = null;
16278 boolean needSep = false;
16279 for (int i=activities.size()-1; i>=0; i--) {
16280 ActivityRecord r = activities.get(i);
16285 synchronized (this) {
16286 final TaskRecord task = r.getTask();
16287 if (lastTask != task) {
16289 pw.print("TASK "); pw.print(lastTask.affinity);
16290 pw.print(" id="); pw.print(lastTask.taskId);
16291 pw.print(" userId="); pw.println(lastTask.userId);
16293 lastTask.dump(pw, " ");
16297 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16303 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16304 * there is a thread associated with the activity.
16306 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16307 final ActivityRecord r, String[] args, boolean dumpAll) {
16308 String innerPrefix = prefix + " ";
16309 synchronized (this) {
16310 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16311 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16313 if (r.app != null) pw.println(r.app.pid);
16314 else pw.println("(not running)");
16316 r.dump(pw, innerPrefix);
16319 if (r.app != null && r.app.thread != null) {
16320 // flush anything that is already in the PrintWriter since the thread is going
16321 // to write to the file descriptor directly
16324 TransferPipe tp = new TransferPipe();
16326 r.app.thread.dumpActivity(tp.getWriteFd(),
16327 r.appToken, innerPrefix, args);
16332 } catch (IOException e) {
16333 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16334 } catch (RemoteException e) {
16335 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16340 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16341 int opti, boolean dumpAll, String dumpPackage) {
16342 boolean needSep = false;
16343 boolean onlyHistory = false;
16344 boolean printedAnything = false;
16346 if ("history".equals(dumpPackage)) {
16347 if (opti < args.length && "-s".equals(args[opti])) {
16350 onlyHistory = true;
16351 dumpPackage = null;
16354 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16355 if (!onlyHistory && dumpAll) {
16356 if (mRegisteredReceivers.size() > 0) {
16357 boolean printed = false;
16358 Iterator it = mRegisteredReceivers.values().iterator();
16359 while (it.hasNext()) {
16360 ReceiverList r = (ReceiverList)it.next();
16361 if (dumpPackage != null && (r.app == null ||
16362 !dumpPackage.equals(r.app.info.packageName))) {
16366 pw.println(" Registered Receivers:");
16369 printedAnything = true;
16371 pw.print(" * "); pw.println(r);
16376 if (mReceiverResolver.dump(pw, needSep ?
16377 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16378 " ", dumpPackage, false, false)) {
16380 printedAnything = true;
16384 for (BroadcastQueue q : mBroadcastQueues) {
16385 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16386 printedAnything |= needSep;
16391 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16392 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16397 printedAnything = true;
16398 pw.print(" Sticky broadcasts for user ");
16399 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16400 StringBuilder sb = new StringBuilder(128);
16401 for (Map.Entry<String, ArrayList<Intent>> ent
16402 : mStickyBroadcasts.valueAt(user).entrySet()) {
16403 pw.print(" * Sticky action "); pw.print(ent.getKey());
16406 ArrayList<Intent> intents = ent.getValue();
16407 final int N = intents.size();
16408 for (int i=0; i<N; i++) {
16410 sb.append(" Intent: ");
16411 intents.get(i).toShortString(sb, false, true, false, false);
16412 pw.println(sb.toString());
16413 Bundle bundle = intents.get(i).getExtras();
16414 if (bundle != null) {
16416 pw.println(bundle.toString());
16426 if (!onlyHistory && dumpAll) {
16428 for (BroadcastQueue queue : mBroadcastQueues) {
16429 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16430 + queue.mBroadcastsScheduled);
16432 pw.println(" mHandler:");
16433 mHandler.dump(new PrintWriterPrinter(pw), " ");
16435 printedAnything = true;
16438 if (!printedAnything) {
16439 pw.println(" (nothing)");
16443 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16444 int opti, boolean dumpAll, String dumpPackage) {
16445 if (mCurBroadcastStats == null) {
16449 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16450 final long now = SystemClock.elapsedRealtime();
16451 if (mLastBroadcastStats != null) {
16452 pw.print(" Last stats (from ");
16453 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16455 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16457 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16458 - mLastBroadcastStats.mStartUptime, pw);
16459 pw.println(" uptime):");
16460 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16461 pw.println(" (nothing)");
16465 pw.print(" Current stats (from ");
16466 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16467 pw.print(" to now, ");
16468 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16469 - mCurBroadcastStats.mStartUptime, pw);
16470 pw.println(" uptime):");
16471 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16472 pw.println(" (nothing)");
16476 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16477 int opti, boolean fullCheckin, String dumpPackage) {
16478 if (mCurBroadcastStats == null) {
16482 if (mLastBroadcastStats != null) {
16483 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16485 mLastBroadcastStats = null;
16489 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16491 mCurBroadcastStats = null;
16495 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16496 int opti, boolean dumpAll, String dumpPackage) {
16498 boolean printedAnything = false;
16500 ItemMatcher matcher = new ItemMatcher();
16501 matcher.build(args, opti);
16503 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16505 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16506 printedAnything |= needSep;
16508 if (mLaunchingProviders.size() > 0) {
16509 boolean printed = false;
16510 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16511 ContentProviderRecord r = mLaunchingProviders.get(i);
16512 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16516 if (needSep) pw.println();
16518 pw.println(" Launching content providers:");
16520 printedAnything = true;
16522 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16527 if (!printedAnything) {
16528 pw.println(" (nothing)");
16532 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16533 int opti, boolean dumpAll, String dumpPackage) {
16534 boolean needSep = false;
16535 boolean printedAnything = false;
16537 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16539 if (mGrantedUriPermissions.size() > 0) {
16540 boolean printed = false;
16542 if (dumpPackage != null) {
16544 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16545 MATCH_ANY_USER, 0);
16546 } catch (NameNotFoundException e) {
16550 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16551 int uid = mGrantedUriPermissions.keyAt(i);
16552 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16555 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16557 if (needSep) pw.println();
16559 pw.println(" Granted Uri Permissions:");
16561 printedAnything = true;
16563 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16564 for (UriPermission perm : perms.values()) {
16565 pw.print(" "); pw.println(perm);
16567 perm.dump(pw, " ");
16573 if (!printedAnything) {
16574 pw.println(" (nothing)");
16578 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16579 int opti, boolean dumpAll, String dumpPackage) {
16580 boolean printed = false;
16582 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16584 if (mIntentSenderRecords.size() > 0) {
16585 // Organize these by package name, so they are easier to read.
16586 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16587 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16588 final Iterator<WeakReference<PendingIntentRecord>> it
16589 = mIntentSenderRecords.values().iterator();
16590 while (it.hasNext()) {
16591 WeakReference<PendingIntentRecord> ref = it.next();
16592 PendingIntentRecord rec = ref != null ? ref.get() : null;
16597 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16600 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16601 if (list == null) {
16602 list = new ArrayList<>();
16603 byPackage.put(rec.key.packageName, list);
16607 for (int i = 0; i < byPackage.size(); i++) {
16608 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16610 pw.print(" * "); pw.print(byPackage.keyAt(i));
16611 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16612 for (int j = 0; j < intents.size(); j++) {
16613 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16615 intents.get(j).dump(pw, " ");
16619 if (weakRefs.size() > 0) {
16621 pw.println(" * WEAK REFS:");
16622 for (int i = 0; i < weakRefs.size(); i++) {
16623 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16629 pw.println(" (nothing)");
16633 private static final int dumpProcessList(PrintWriter pw,
16634 ActivityManagerService service, List list,
16635 String prefix, String normalLabel, String persistentLabel,
16636 String dumpPackage) {
16638 final int N = list.size()-1;
16639 for (int i=N; i>=0; i--) {
16640 ProcessRecord r = (ProcessRecord)list.get(i);
16641 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16644 pw.println(String.format("%s%s #%2d: %s",
16645 prefix, (r.persistent ? persistentLabel : normalLabel),
16647 if (r.persistent) {
16654 private static final boolean dumpProcessOomList(PrintWriter pw,
16655 ActivityManagerService service, List<ProcessRecord> origList,
16656 String prefix, String normalLabel, String persistentLabel,
16657 boolean inclDetails, String dumpPackage) {
16659 ArrayList<Pair<ProcessRecord, Integer>> list
16660 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16661 for (int i=0; i<origList.size(); i++) {
16662 ProcessRecord r = origList.get(i);
16663 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16666 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16669 if (list.size() <= 0) {
16673 Comparator<Pair<ProcessRecord, Integer>> comparator
16674 = new Comparator<Pair<ProcessRecord, Integer>>() {
16676 public int compare(Pair<ProcessRecord, Integer> object1,
16677 Pair<ProcessRecord, Integer> object2) {
16678 if (object1.first.setAdj != object2.first.setAdj) {
16679 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16681 if (object1.first.setProcState != object2.first.setProcState) {
16682 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16684 if (object1.second.intValue() != object2.second.intValue()) {
16685 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16691 Collections.sort(list, comparator);
16693 final long curUptime = SystemClock.uptimeMillis();
16694 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16696 for (int i=list.size()-1; i>=0; i--) {
16697 ProcessRecord r = list.get(i).first;
16698 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16700 switch (r.setSchedGroup) {
16701 case ProcessList.SCHED_GROUP_BACKGROUND:
16704 case ProcessList.SCHED_GROUP_DEFAULT:
16707 case ProcessList.SCHED_GROUP_TOP_APP:
16715 if (r.foregroundActivities) {
16717 } else if (r.foregroundServices) {
16722 String procState = ProcessList.makeProcStateString(r.curProcState);
16724 pw.print(r.persistent ? persistentLabel : normalLabel);
16726 int num = (origList.size()-1)-list.get(i).second;
16727 if (num < 10) pw.print(' ');
16732 pw.print(schedGroup);
16734 pw.print(foreground);
16736 pw.print(procState);
16738 if (r.trimMemoryLevel < 10) pw.print(' ');
16739 pw.print(r.trimMemoryLevel);
16741 pw.print(r.toShortString());
16743 pw.print(r.adjType);
16745 if (r.adjSource != null || r.adjTarget != null) {
16748 if (r.adjTarget instanceof ComponentName) {
16749 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16750 } else if (r.adjTarget != null) {
16751 pw.print(r.adjTarget.toString());
16753 pw.print("{null}");
16756 if (r.adjSource instanceof ProcessRecord) {
16758 pw.print(((ProcessRecord)r.adjSource).toShortString());
16760 } else if (r.adjSource != null) {
16761 pw.println(r.adjSource.toString());
16763 pw.println("{null}");
16769 pw.print("oom: max="); pw.print(r.maxAdj);
16770 pw.print(" curRaw="); pw.print(r.curRawAdj);
16771 pw.print(" setRaw="); pw.print(r.setRawAdj);
16772 pw.print(" cur="); pw.print(r.curAdj);
16773 pw.print(" set="); pw.println(r.setAdj);
16776 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16777 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16778 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16779 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16780 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16784 pw.print("cached="); pw.print(r.cached);
16785 pw.print(" empty="); pw.print(r.empty);
16786 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16788 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16789 if (r.lastCpuTime != 0) {
16790 long timeUsed = r.curCpuTime - r.lastCpuTime;
16793 pw.print("run cpu over ");
16794 TimeUtils.formatDuration(uptimeSince, pw);
16795 pw.print(" used ");
16796 TimeUtils.formatDuration(timeUsed, pw);
16798 pw.print((timeUsed*100)/uptimeSince);
16807 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16809 ArrayList<ProcessRecord> procs;
16810 synchronized (this) {
16811 if (args != null && args.length > start
16812 && args[start].charAt(0) != '-') {
16813 procs = new ArrayList<ProcessRecord>();
16816 pid = Integer.parseInt(args[start]);
16817 } catch (NumberFormatException e) {
16819 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16820 ProcessRecord proc = mLruProcesses.get(i);
16821 if (proc.pid == pid) {
16823 } else if (allPkgs && proc.pkgList != null
16824 && proc.pkgList.containsKey(args[start])) {
16826 } else if (proc.processName.equals(args[start])) {
16830 if (procs.size() <= 0) {
16834 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16840 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16841 PrintWriter pw, String[] args) {
16842 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16843 if (procs == null) {
16844 pw.println("No process found for: " + args[0]);
16848 long uptime = SystemClock.uptimeMillis();
16849 long realtime = SystemClock.elapsedRealtime();
16850 pw.println("Applications Graphics Acceleration Info:");
16851 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16853 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16854 ProcessRecord r = procs.get(i);
16855 if (r.thread != null) {
16856 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16859 TransferPipe tp = new TransferPipe();
16861 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16866 } catch (IOException e) {
16867 pw.println("Failure while dumping the app: " + r);
16869 } catch (RemoteException e) {
16870 pw.println("Got a RemoteException while dumping the app " + r);
16877 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16878 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16879 if (procs == null) {
16880 pw.println("No process found for: " + args[0]);
16884 pw.println("Applications Database Info:");
16886 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16887 ProcessRecord r = procs.get(i);
16888 if (r.thread != null) {
16889 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16892 TransferPipe tp = new TransferPipe();
16894 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16899 } catch (IOException e) {
16900 pw.println("Failure while dumping the app: " + r);
16902 } catch (RemoteException e) {
16903 pw.println("Got a RemoteException while dumping the app " + r);
16910 final static class MemItem {
16911 final boolean isProc;
16912 final String label;
16913 final String shortLabel;
16915 final long swapPss;
16917 final boolean hasActivities;
16918 ArrayList<MemItem> subitems;
16920 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16921 boolean _hasActivities) {
16924 shortLabel = _shortLabel;
16926 swapPss = _swapPss;
16928 hasActivities = _hasActivities;
16931 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16934 shortLabel = _shortLabel;
16936 swapPss = _swapPss;
16938 hasActivities = false;
16942 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16943 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16944 if (sort && !isCompact) {
16945 Collections.sort(items, new Comparator<MemItem>() {
16947 public int compare(MemItem lhs, MemItem rhs) {
16948 if (lhs.pss < rhs.pss) {
16950 } else if (lhs.pss > rhs.pss) {
16958 for (int i=0; i<items.size(); i++) {
16959 MemItem mi = items.get(i);
16962 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16963 mi.label, stringifyKBSize(mi.swapPss));
16965 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16967 } else if (mi.isProc) {
16968 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16969 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16970 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16971 pw.println(mi.hasActivities ? ",a" : ",e");
16973 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16974 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16976 if (mi.subitems != null) {
16977 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16978 true, isCompact, dumpSwapPss);
16983 // These are in KB.
16984 static final long[] DUMP_MEM_BUCKETS = new long[] {
16985 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16986 120*1024, 160*1024, 200*1024,
16987 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16988 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16991 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16992 boolean stackLike) {
16993 int start = label.lastIndexOf('.');
16994 if (start >= 0) start++;
16996 int end = label.length();
16997 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16998 if (DUMP_MEM_BUCKETS[i] >= memKB) {
16999 long bucket = DUMP_MEM_BUCKETS[i]/1024;
17000 out.append(bucket);
17001 out.append(stackLike ? "MB." : "MB ");
17002 out.append(label, start, end);
17006 out.append(memKB/1024);
17007 out.append(stackLike ? "MB." : "MB ");
17008 out.append(label, start, end);
17011 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17012 ProcessList.NATIVE_ADJ,
17013 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17014 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17015 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17016 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17017 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17018 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17020 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17022 "System", "Persistent", "Persistent Service", "Foreground",
17023 "Visible", "Perceptible",
17024 "Heavy Weight", "Backup",
17025 "A Services", "Home",
17026 "Previous", "B Services", "Cached"
17028 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17030 "sys", "pers", "persvc", "fore",
17033 "servicea", "home",
17034 "prev", "serviceb", "cached"
17037 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17038 long realtime, boolean isCheckinRequest, boolean isCompact) {
17040 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17042 if (isCheckinRequest || isCompact) {
17043 // short checkin version
17044 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17046 pw.println("Applications Memory Usage (in Kilobytes):");
17047 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17051 private static final int KSM_SHARED = 0;
17052 private static final int KSM_SHARING = 1;
17053 private static final int KSM_UNSHARED = 2;
17054 private static final int KSM_VOLATILE = 3;
17056 private final long[] getKsmInfo() {
17057 long[] longOut = new long[4];
17058 final int[] SINGLE_LONG_FORMAT = new int[] {
17059 PROC_SPACE_TERM| PROC_OUT_LONG
17061 long[] longTmp = new long[1];
17062 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17063 SINGLE_LONG_FORMAT, null, longTmp, null);
17064 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17066 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17067 SINGLE_LONG_FORMAT, null, longTmp, null);
17068 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17070 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17071 SINGLE_LONG_FORMAT, null, longTmp, null);
17072 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17074 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17075 SINGLE_LONG_FORMAT, null, longTmp, null);
17076 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17080 private static String stringifySize(long size, int order) {
17081 Locale locale = Locale.US;
17084 return String.format(locale, "%,13d", size);
17086 return String.format(locale, "%,9dK", size / 1024);
17088 return String.format(locale, "%,5dM", size / 1024 / 1024);
17089 case 1024 * 1024 * 1024:
17090 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17092 throw new IllegalArgumentException("Invalid size order");
17096 private static String stringifyKBSize(long size) {
17097 return stringifySize(size * 1024, 1024);
17100 // Update this version number in case you change the 'compact' format
17101 private static final int MEMINFO_COMPACT_VERSION = 1;
17103 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17104 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17105 boolean dumpDetails = false;
17106 boolean dumpFullDetails = false;
17107 boolean dumpDalvik = false;
17108 boolean dumpSummaryOnly = false;
17109 boolean dumpUnreachable = false;
17110 boolean oomOnly = false;
17111 boolean isCompact = false;
17112 boolean localOnly = false;
17113 boolean packages = false;
17114 boolean isCheckinRequest = false;
17115 boolean dumpSwapPss = false;
17118 while (opti < args.length) {
17119 String opt = args[opti];
17120 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17124 if ("-a".equals(opt)) {
17125 dumpDetails = true;
17126 dumpFullDetails = true;
17128 dumpSwapPss = true;
17129 } else if ("-d".equals(opt)) {
17131 } else if ("-c".equals(opt)) {
17133 } else if ("-s".equals(opt)) {
17134 dumpDetails = true;
17135 dumpSummaryOnly = true;
17136 } else if ("-S".equals(opt)) {
17137 dumpSwapPss = true;
17138 } else if ("--unreachable".equals(opt)) {
17139 dumpUnreachable = true;
17140 } else if ("--oom".equals(opt)) {
17142 } else if ("--local".equals(opt)) {
17144 } else if ("--package".equals(opt)) {
17146 } else if ("--checkin".equals(opt)) {
17147 isCheckinRequest = true;
17149 } else if ("-h".equals(opt)) {
17150 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17151 pw.println(" -a: include all available information for each process.");
17152 pw.println(" -d: include dalvik details.");
17153 pw.println(" -c: dump in a compact machine-parseable representation.");
17154 pw.println(" -s: dump only summary of application memory usage.");
17155 pw.println(" -S: dump also SwapPss.");
17156 pw.println(" --oom: only show processes organized by oom adj.");
17157 pw.println(" --local: only collect details locally, don't call process.");
17158 pw.println(" --package: interpret process arg as package, dumping all");
17159 pw.println(" processes that have loaded that package.");
17160 pw.println(" --checkin: dump data for a checkin");
17161 pw.println("If [process] is specified it can be the name or ");
17162 pw.println("pid of a specific process to dump.");
17165 pw.println("Unknown argument: " + opt + "; use -h for help");
17169 long uptime = SystemClock.uptimeMillis();
17170 long realtime = SystemClock.elapsedRealtime();
17171 final long[] tmpLong = new long[1];
17173 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17174 if (procs == null) {
17175 // No Java processes. Maybe they want to print a native process.
17176 if (args != null && args.length > opti
17177 && args[opti].charAt(0) != '-') {
17178 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17179 = new ArrayList<ProcessCpuTracker.Stats>();
17180 updateCpuStatsNow();
17183 findPid = Integer.parseInt(args[opti]);
17184 } catch (NumberFormatException e) {
17186 synchronized (mProcessCpuTracker) {
17187 final int N = mProcessCpuTracker.countStats();
17188 for (int i=0; i<N; i++) {
17189 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17190 if (st.pid == findPid || (st.baseName != null
17191 && st.baseName.equals(args[opti]))) {
17192 nativeProcs.add(st);
17196 if (nativeProcs.size() > 0) {
17197 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17199 Debug.MemoryInfo mi = null;
17200 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17201 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17202 final int pid = r.pid;
17203 if (!isCheckinRequest && dumpDetails) {
17204 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17207 mi = new Debug.MemoryInfo();
17209 if (dumpDetails || (!brief && !oomOnly)) {
17210 Debug.getMemoryInfo(pid, mi);
17212 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17213 mi.dalvikPrivateDirty = (int)tmpLong[0];
17215 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17216 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17217 if (isCheckinRequest) {
17224 pw.println("No process found for: " + args[opti]);
17228 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17229 dumpDetails = true;
17232 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17234 String[] innerArgs = new String[args.length-opti];
17235 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17237 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17238 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17239 long nativePss = 0;
17240 long nativeSwapPss = 0;
17241 long dalvikPss = 0;
17242 long dalvikSwapPss = 0;
17243 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17245 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17248 long otherSwapPss = 0;
17249 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17250 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17252 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17253 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17254 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17255 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17258 long totalSwapPss = 0;
17259 long cachedPss = 0;
17260 long cachedSwapPss = 0;
17261 boolean hasSwapPss = false;
17263 Debug.MemoryInfo mi = null;
17264 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17265 final ProcessRecord r = procs.get(i);
17266 final IApplicationThread thread;
17269 final boolean hasActivities;
17270 synchronized (this) {
17273 oomAdj = r.getSetAdjWithServices();
17274 hasActivities = r.activities.size() > 0;
17276 if (thread != null) {
17277 if (!isCheckinRequest && dumpDetails) {
17278 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17281 mi = new Debug.MemoryInfo();
17283 if (dumpDetails || (!brief && !oomOnly)) {
17284 Debug.getMemoryInfo(pid, mi);
17285 hasSwapPss = mi.hasSwappedOutPss;
17287 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17288 mi.dalvikPrivateDirty = (int)tmpLong[0];
17292 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17293 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17294 if (isCheckinRequest) {
17300 TransferPipe tp = new TransferPipe();
17302 thread.dumpMemInfo(tp.getWriteFd(),
17303 mi, isCheckinRequest, dumpFullDetails,
17304 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17309 } catch (IOException e) {
17310 if (!isCheckinRequest) {
17311 pw.println("Got IoException! " + e);
17314 } catch (RemoteException e) {
17315 if (!isCheckinRequest) {
17316 pw.println("Got RemoteException! " + e);
17323 final long myTotalPss = mi.getTotalPss();
17324 final long myTotalUss = mi.getTotalUss();
17325 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17327 synchronized (this) {
17328 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17329 // Record this for posterity if the process has been stable.
17330 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17334 if (!isCheckinRequest && mi != null) {
17335 totalPss += myTotalPss;
17336 totalSwapPss += myTotalSwapPss;
17337 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17338 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17339 myTotalSwapPss, pid, hasActivities);
17340 procMems.add(pssItem);
17341 procMemsMap.put(pid, pssItem);
17343 nativePss += mi.nativePss;
17344 nativeSwapPss += mi.nativeSwappedOutPss;
17345 dalvikPss += mi.dalvikPss;
17346 dalvikSwapPss += mi.dalvikSwappedOutPss;
17347 for (int j=0; j<dalvikSubitemPss.length; j++) {
17348 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17349 dalvikSubitemSwapPss[j] +=
17350 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17352 otherPss += mi.otherPss;
17353 otherSwapPss += mi.otherSwappedOutPss;
17354 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17355 long mem = mi.getOtherPss(j);
17358 mem = mi.getOtherSwappedOutPss(j);
17359 miscSwapPss[j] += mem;
17360 otherSwapPss -= mem;
17363 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17364 cachedPss += myTotalPss;
17365 cachedSwapPss += myTotalSwapPss;
17368 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17369 if (oomIndex == (oomPss.length - 1)
17370 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17371 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17372 oomPss[oomIndex] += myTotalPss;
17373 oomSwapPss[oomIndex] += myTotalSwapPss;
17374 if (oomProcs[oomIndex] == null) {
17375 oomProcs[oomIndex] = new ArrayList<MemItem>();
17377 oomProcs[oomIndex].add(pssItem);
17385 long nativeProcTotalPss = 0;
17387 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17388 // If we are showing aggregations, also look for native processes to
17389 // include so that our aggregations are more accurate.
17390 updateCpuStatsNow();
17392 synchronized (mProcessCpuTracker) {
17393 final int N = mProcessCpuTracker.countStats();
17394 for (int i=0; i<N; i++) {
17395 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17396 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17398 mi = new Debug.MemoryInfo();
17400 if (!brief && !oomOnly) {
17401 Debug.getMemoryInfo(st.pid, mi);
17403 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17404 mi.nativePrivateDirty = (int)tmpLong[0];
17407 final long myTotalPss = mi.getTotalPss();
17408 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17409 totalPss += myTotalPss;
17410 nativeProcTotalPss += myTotalPss;
17412 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17413 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17414 procMems.add(pssItem);
17416 nativePss += mi.nativePss;
17417 nativeSwapPss += mi.nativeSwappedOutPss;
17418 dalvikPss += mi.dalvikPss;
17419 dalvikSwapPss += mi.dalvikSwappedOutPss;
17420 for (int j=0; j<dalvikSubitemPss.length; j++) {
17421 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17422 dalvikSubitemSwapPss[j] +=
17423 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17425 otherPss += mi.otherPss;
17426 otherSwapPss += mi.otherSwappedOutPss;
17427 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17428 long mem = mi.getOtherPss(j);
17431 mem = mi.getOtherSwappedOutPss(j);
17432 miscSwapPss[j] += mem;
17433 otherSwapPss -= mem;
17435 oomPss[0] += myTotalPss;
17436 oomSwapPss[0] += myTotalSwapPss;
17437 if (oomProcs[0] == null) {
17438 oomProcs[0] = new ArrayList<MemItem>();
17440 oomProcs[0].add(pssItem);
17445 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17447 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17448 final int dalvikId = -2;
17449 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17450 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17451 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17452 String label = Debug.MemoryInfo.getOtherLabel(j);
17453 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17455 if (dalvikSubitemPss.length > 0) {
17456 // Add dalvik subitems.
17457 for (MemItem memItem : catMems) {
17458 int memItemStart = 0, memItemEnd = 0;
17459 if (memItem.id == dalvikId) {
17460 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17461 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17462 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17463 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17464 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17465 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17466 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17467 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17468 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17469 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17470 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17472 continue; // No subitems, continue.
17474 memItem.subitems = new ArrayList<MemItem>();
17475 for (int j=memItemStart; j<=memItemEnd; j++) {
17476 final String name = Debug.MemoryInfo.getOtherLabel(
17477 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17478 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17479 dalvikSubitemSwapPss[j], j));
17484 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17485 for (int j=0; j<oomPss.length; j++) {
17486 if (oomPss[j] != 0) {
17487 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17488 : DUMP_MEM_OOM_LABEL[j];
17489 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17490 DUMP_MEM_OOM_ADJ[j]);
17491 item.subitems = oomProcs[j];
17496 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17497 if (!brief && !oomOnly && !isCompact) {
17499 pw.println("Total PSS by process:");
17500 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17504 pw.println("Total PSS by OOM adjustment:");
17506 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17507 if (!brief && !oomOnly) {
17508 PrintWriter out = categoryPw != null ? categoryPw : pw;
17511 out.println("Total PSS by category:");
17513 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17518 MemInfoReader memInfo = new MemInfoReader();
17519 memInfo.readMemInfo();
17520 if (nativeProcTotalPss > 0) {
17521 synchronized (this) {
17522 final long cachedKb = memInfo.getCachedSizeKb();
17523 final long freeKb = memInfo.getFreeSizeKb();
17524 final long zramKb = memInfo.getZramTotalSizeKb();
17525 final long kernelKb = memInfo.getKernelUsedSizeKb();
17526 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17527 kernelKb*1024, nativeProcTotalPss*1024);
17528 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17529 nativeProcTotalPss);
17534 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17535 pw.print(" (status ");
17536 switch (mLastMemoryLevel) {
17537 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17538 pw.println("normal)");
17540 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17541 pw.println("moderate)");
17543 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17544 pw.println("low)");
17546 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17547 pw.println("critical)");
17550 pw.print(mLastMemoryLevel);
17554 pw.print(" Free RAM: ");
17555 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17556 + memInfo.getFreeSizeKb()));
17558 pw.print(stringifyKBSize(cachedPss));
17559 pw.print(" cached pss + ");
17560 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17561 pw.print(" cached kernel + ");
17562 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17563 pw.println(" free)");
17565 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17566 pw.print(cachedPss + memInfo.getCachedSizeKb()
17567 + memInfo.getFreeSizeKb()); pw.print(",");
17568 pw.println(totalPss - cachedPss);
17571 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17572 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17573 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17575 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17576 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17577 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17578 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17579 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17581 pw.print("lostram,"); pw.println(lostRAM);
17584 if (memInfo.getZramTotalSizeKb() != 0) {
17586 pw.print(" ZRAM: ");
17587 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17588 pw.print(" physical used for ");
17589 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17590 - memInfo.getSwapFreeSizeKb()));
17591 pw.print(" in swap (");
17592 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17593 pw.println(" total swap)");
17595 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17596 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17597 pw.println(memInfo.getSwapFreeSizeKb());
17600 final long[] ksm = getKsmInfo();
17602 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17603 || ksm[KSM_VOLATILE] != 0) {
17604 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17605 pw.print(" saved from shared ");
17606 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17607 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17608 pw.print(" unshared; ");
17609 pw.print(stringifyKBSize(
17610 ksm[KSM_VOLATILE])); pw.println(" volatile");
17612 pw.print(" Tuning: ");
17613 pw.print(ActivityManager.staticGetMemoryClass());
17614 pw.print(" (large ");
17615 pw.print(ActivityManager.staticGetLargeMemoryClass());
17616 pw.print("), oom ");
17617 pw.print(stringifySize(
17618 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17619 pw.print(", restore limit ");
17620 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17621 if (ActivityManager.isLowRamDeviceStatic()) {
17622 pw.print(" (low-ram)");
17624 if (ActivityManager.isHighEndGfx()) {
17625 pw.print(" (high-end-gfx)");
17629 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17630 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17631 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17632 pw.print("tuning,");
17633 pw.print(ActivityManager.staticGetMemoryClass());
17635 pw.print(ActivityManager.staticGetLargeMemoryClass());
17637 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17638 if (ActivityManager.isLowRamDeviceStatic()) {
17639 pw.print(",low-ram");
17641 if (ActivityManager.isHighEndGfx()) {
17642 pw.print(",high-end-gfx");
17650 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17651 long memtrack, String name) {
17653 sb.append(ProcessList.makeOomAdjString(oomAdj));
17655 sb.append(ProcessList.makeProcStateString(procState));
17657 ProcessList.appendRamKb(sb, pss);
17660 if (memtrack > 0) {
17662 sb.append(stringifyKBSize(memtrack));
17663 sb.append(" memtrack)");
17667 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17668 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17669 sb.append(" (pid ");
17672 sb.append(mi.adjType);
17674 if (mi.adjReason != null) {
17676 sb.append(mi.adjReason);
17681 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17682 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17683 for (int i=0, N=memInfos.size(); i<N; i++) {
17684 ProcessMemInfo mi = memInfos.get(i);
17685 infoMap.put(mi.pid, mi);
17687 updateCpuStatsNow();
17688 long[] memtrackTmp = new long[1];
17689 final List<ProcessCpuTracker.Stats> stats;
17690 // Get a list of Stats that have vsize > 0
17691 synchronized (mProcessCpuTracker) {
17692 stats = mProcessCpuTracker.getStats((st) -> {
17693 return st.vsize > 0;
17696 final int statsCount = stats.size();
17697 for (int i = 0; i < statsCount; i++) {
17698 ProcessCpuTracker.Stats st = stats.get(i);
17699 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17701 if (infoMap.indexOfKey(st.pid) < 0) {
17702 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17703 ProcessList.NATIVE_ADJ, -1, "native", null);
17705 mi.memtrack = memtrackTmp[0];
17712 long totalMemtrack = 0;
17713 for (int i=0, N=memInfos.size(); i<N; i++) {
17714 ProcessMemInfo mi = memInfos.get(i);
17716 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17717 mi.memtrack = memtrackTmp[0];
17719 totalPss += mi.pss;
17720 totalMemtrack += mi.memtrack;
17722 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17723 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17724 if (lhs.oomAdj != rhs.oomAdj) {
17725 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17727 if (lhs.pss != rhs.pss) {
17728 return lhs.pss < rhs.pss ? 1 : -1;
17734 StringBuilder tag = new StringBuilder(128);
17735 StringBuilder stack = new StringBuilder(128);
17736 tag.append("Low on memory -- ");
17737 appendMemBucket(tag, totalPss, "total", false);
17738 appendMemBucket(stack, totalPss, "total", true);
17740 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17741 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17742 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17744 boolean firstLine = true;
17745 int lastOomAdj = Integer.MIN_VALUE;
17746 long extraNativeRam = 0;
17747 long extraNativeMemtrack = 0;
17748 long cachedPss = 0;
17749 for (int i=0, N=memInfos.size(); i<N; i++) {
17750 ProcessMemInfo mi = memInfos.get(i);
17752 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17753 cachedPss += mi.pss;
17756 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17757 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17758 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17759 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17760 if (lastOomAdj != mi.oomAdj) {
17761 lastOomAdj = mi.oomAdj;
17762 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17765 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17770 stack.append("\n\t at ");
17778 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17779 appendMemBucket(tag, mi.pss, mi.name, false);
17781 appendMemBucket(stack, mi.pss, mi.name, true);
17782 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17783 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17785 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17786 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17787 stack.append(DUMP_MEM_OOM_LABEL[k]);
17789 stack.append(DUMP_MEM_OOM_ADJ[k]);
17796 appendMemInfo(fullNativeBuilder, mi);
17797 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17798 // The short form only has native processes that are >= 512K.
17799 if (mi.pss >= 512) {
17800 appendMemInfo(shortNativeBuilder, mi);
17802 extraNativeRam += mi.pss;
17803 extraNativeMemtrack += mi.memtrack;
17806 // Short form has all other details, but if we have collected RAM
17807 // from smaller native processes let's dump a summary of that.
17808 if (extraNativeRam > 0) {
17809 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17810 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17811 shortNativeBuilder.append('\n');
17812 extraNativeRam = 0;
17814 appendMemInfo(fullJavaBuilder, mi);
17818 fullJavaBuilder.append(" ");
17819 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17820 fullJavaBuilder.append(": TOTAL");
17821 if (totalMemtrack > 0) {
17822 fullJavaBuilder.append(" (");
17823 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17824 fullJavaBuilder.append(" memtrack)");
17827 fullJavaBuilder.append("\n");
17829 MemInfoReader memInfo = new MemInfoReader();
17830 memInfo.readMemInfo();
17831 final long[] infos = memInfo.getRawInfo();
17833 StringBuilder memInfoBuilder = new StringBuilder(1024);
17834 Debug.getMemInfo(infos);
17835 memInfoBuilder.append(" MemInfo: ");
17836 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17837 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17838 memInfoBuilder.append(stringifyKBSize(
17839 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17840 memInfoBuilder.append(stringifyKBSize(
17841 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17842 memInfoBuilder.append(stringifyKBSize(
17843 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17844 memInfoBuilder.append(" ");
17845 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17846 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17847 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17848 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17849 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17850 memInfoBuilder.append(" ZRAM: ");
17851 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17852 memInfoBuilder.append(" RAM, ");
17853 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17854 memInfoBuilder.append(" swap total, ");
17855 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17856 memInfoBuilder.append(" swap free\n");
17858 final long[] ksm = getKsmInfo();
17859 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17860 || ksm[KSM_VOLATILE] != 0) {
17861 memInfoBuilder.append(" KSM: ");
17862 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17863 memInfoBuilder.append(" saved from shared ");
17864 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17865 memInfoBuilder.append("\n ");
17866 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17867 memInfoBuilder.append(" unshared; ");
17868 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17869 memInfoBuilder.append(" volatile\n");
17871 memInfoBuilder.append(" Free RAM: ");
17872 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17873 + memInfo.getFreeSizeKb()));
17874 memInfoBuilder.append("\n");
17875 memInfoBuilder.append(" Used RAM: ");
17876 memInfoBuilder.append(stringifyKBSize(
17877 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17878 memInfoBuilder.append("\n");
17879 memInfoBuilder.append(" Lost RAM: ");
17880 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17881 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17882 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17883 memInfoBuilder.append("\n");
17884 Slog.i(TAG, "Low on memory:");
17885 Slog.i(TAG, shortNativeBuilder.toString());
17886 Slog.i(TAG, fullJavaBuilder.toString());
17887 Slog.i(TAG, memInfoBuilder.toString());
17889 StringBuilder dropBuilder = new StringBuilder(1024);
17891 StringWriter oomSw = new StringWriter();
17892 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17893 StringWriter catSw = new StringWriter();
17894 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17895 String[] emptyArgs = new String[] { };
17896 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17898 String oomString = oomSw.toString();
17900 dropBuilder.append("Low on memory:");
17901 dropBuilder.append(stack);
17902 dropBuilder.append('\n');
17903 dropBuilder.append(fullNativeBuilder);
17904 dropBuilder.append(fullJavaBuilder);
17905 dropBuilder.append('\n');
17906 dropBuilder.append(memInfoBuilder);
17907 dropBuilder.append('\n');
17909 dropBuilder.append(oomString);
17910 dropBuilder.append('\n');
17912 StringWriter catSw = new StringWriter();
17913 synchronized (ActivityManagerService.this) {
17914 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17915 String[] emptyArgs = new String[] { };
17917 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17919 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17920 false, null).dumpLocked();
17922 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17925 dropBuilder.append(catSw.toString());
17926 addErrorToDropBox("lowmem", null, "system_server", null,
17927 null, tag.toString(), dropBuilder.toString(), null, null);
17928 //Slog.i(TAG, "Sent to dropbox:");
17929 //Slog.i(TAG, dropBuilder.toString());
17930 synchronized (ActivityManagerService.this) {
17931 long now = SystemClock.uptimeMillis();
17932 if (mLastMemUsageReportTime < now) {
17933 mLastMemUsageReportTime = now;
17939 * Searches array of arguments for the specified string
17940 * @param args array of argument strings
17941 * @param value value to search for
17942 * @return true if the value is contained in the array
17944 private static boolean scanArgs(String[] args, String value) {
17945 if (args != null) {
17946 for (String arg : args) {
17947 if (value.equals(arg)) {
17955 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17956 ContentProviderRecord cpr, boolean always) {
17957 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17959 if (!inLaunching || always) {
17960 synchronized (cpr) {
17961 cpr.launchingApp = null;
17964 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17965 String names[] = cpr.info.authority.split(";");
17966 for (int j = 0; j < names.length; j++) {
17967 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17971 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17972 ContentProviderConnection conn = cpr.connections.get(i);
17973 if (conn.waiting) {
17974 // If this connection is waiting for the provider, then we don't
17975 // need to mess with its process unless we are always removing
17976 // or for some reason the provider is not currently launching.
17977 if (inLaunching && !always) {
17981 ProcessRecord capp = conn.client;
17983 if (conn.stableCount > 0) {
17984 if (!capp.persistent && capp.thread != null
17986 && capp.pid != MY_PID) {
17987 capp.kill("depends on provider "
17988 + cpr.name.flattenToShortString()
17989 + " in dying proc " + (proc != null ? proc.processName : "??")
17990 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17992 } else if (capp.thread != null && conn.provider.provider != null) {
17994 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17995 } catch (RemoteException e) {
17997 // In the protocol here, we don't expect the client to correctly
17998 // clean up this connection, we'll just remove it.
17999 cpr.connections.remove(i);
18000 if (conn.client.conProviders.remove(conn)) {
18001 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18006 if (inLaunching && always) {
18007 mLaunchingProviders.remove(cpr);
18009 return inLaunching;
18013 * Main code for cleaning up a process when it has gone away. This is
18014 * called both as a result of the process dying, or directly when stopping
18015 * a process when running in single process mode.
18017 * @return Returns true if the given process has been restarted, so the
18018 * app that was passed in must remain on the process lists.
18020 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18021 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18023 removeLruProcessLocked(app);
18024 ProcessList.remove(app.pid);
18027 mProcessesToGc.remove(app);
18028 mPendingPssProcesses.remove(app);
18030 // Dismiss any open dialogs.
18031 if (app.crashDialog != null && !app.forceCrashReport) {
18032 app.crashDialog.dismiss();
18033 app.crashDialog = null;
18035 if (app.anrDialog != null) {
18036 app.anrDialog.dismiss();
18037 app.anrDialog = null;
18039 if (app.waitDialog != null) {
18040 app.waitDialog.dismiss();
18041 app.waitDialog = null;
18044 app.crashing = false;
18045 app.notResponding = false;
18047 app.resetPackageList(mProcessStats);
18048 app.unlinkDeathRecipient();
18049 app.makeInactive(mProcessStats);
18050 app.waitingToKill = null;
18051 app.forcingToImportant = null;
18052 updateProcessForegroundLocked(app, false, false);
18053 app.foregroundActivities = false;
18054 app.hasShownUi = false;
18055 app.treatLikeActivity = false;
18056 app.hasAboveClient = false;
18057 app.hasClientActivities = false;
18059 mServices.killServicesLocked(app, allowRestart);
18061 boolean restart = false;
18063 // Remove published content providers.
18064 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18065 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18066 final boolean always = app.bad || !allowRestart;
18067 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18068 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18069 // We left the provider in the launching list, need to
18074 cpr.provider = null;
18077 app.pubProviders.clear();
18079 // Take care of any launching providers waiting for this process.
18080 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18084 // Unregister from connected content providers.
18085 if (!app.conProviders.isEmpty()) {
18086 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18087 ContentProviderConnection conn = app.conProviders.get(i);
18088 conn.provider.connections.remove(conn);
18089 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18090 conn.provider.name);
18092 app.conProviders.clear();
18095 // At this point there may be remaining entries in mLaunchingProviders
18096 // where we were the only one waiting, so they are no longer of use.
18097 // Look for these and clean up if found.
18098 // XXX Commented out for now. Trying to figure out a way to reproduce
18099 // the actual situation to identify what is actually going on.
18101 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18102 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18103 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18104 synchronized (cpr) {
18105 cpr.launchingApp = null;
18112 skipCurrentReceiverLocked(app);
18114 // Unregister any receivers.
18115 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18116 removeReceiverLocked(app.receivers.valueAt(i));
18118 app.receivers.clear();
18120 // If the app is undergoing backup, tell the backup manager about it
18121 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18122 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18123 + mBackupTarget.appInfo + " died during backup");
18124 mHandler.post(new Runnable() {
18128 IBackupManager bm = IBackupManager.Stub.asInterface(
18129 ServiceManager.getService(Context.BACKUP_SERVICE));
18130 bm.agentDisconnected(app.info.packageName);
18131 } catch (RemoteException e) {
18132 // can't happen; backup manager is local
18138 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18139 ProcessChangeItem item = mPendingProcessChanges.get(i);
18140 if (item.pid == app.pid) {
18141 mPendingProcessChanges.remove(i);
18142 mAvailProcessChanges.add(item);
18145 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18146 null).sendToTarget();
18148 // If the caller is restarting this app, then leave it in its
18149 // current lists and let the caller take care of it.
18154 if (!app.persistent || app.isolated) {
18155 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18156 "Removing non-persistent process during cleanup: " + app);
18157 if (!replacingPid) {
18158 removeProcessNameLocked(app.processName, app.uid, app);
18160 if (mHeavyWeightProcess == app) {
18161 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18162 mHeavyWeightProcess.userId, 0));
18163 mHeavyWeightProcess = null;
18165 } else if (!app.removed) {
18166 // This app is persistent, so we need to keep its record around.
18167 // If it is not already on the pending app list, add it there
18168 // and start a new process for it.
18169 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18170 mPersistentStartingProcesses.add(app);
18174 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18175 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18176 mProcessesOnHold.remove(app);
18178 if (app == mHomeProcess) {
18179 mHomeProcess = null;
18181 if (app == mPreviousProcess) {
18182 mPreviousProcess = null;
18185 if (restart && !app.isolated) {
18186 // We have components that still need to be running in the
18187 // process, so re-launch it.
18189 ProcessList.remove(app.pid);
18191 addProcessNameLocked(app);
18192 startProcessLocked(app, "restart", app.processName);
18194 } else if (app.pid > 0 && app.pid != MY_PID) {
18197 synchronized (mPidsSelfLocked) {
18198 mPidsSelfLocked.remove(app.pid);
18199 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18201 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18202 if (app.isolated) {
18203 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18210 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18211 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18212 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18213 if (cpr.launchingApp == app) {
18220 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18221 // Look through the content providers we are waiting to have launched,
18222 // and if any run in this process then either schedule a restart of
18223 // the process or kill the client waiting for it if this process has
18225 boolean restart = false;
18226 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18227 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18228 if (cpr.launchingApp == app) {
18229 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18232 removeDyingProviderLocked(app, cpr, true);
18239 // =========================================================
18241 // =========================================================
18244 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18246 enforceNotIsolatedCaller("getServices");
18248 final int callingUid = Binder.getCallingUid();
18249 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18250 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18251 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18253 synchronized (this) {
18254 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18255 allowed, canInteractAcrossUsers);
18260 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18261 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18262 synchronized (this) {
18263 return mServices.getRunningServiceControlPanelLocked(name);
18268 public ComponentName startService(IApplicationThread caller, Intent service,
18269 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18270 throws TransactionTooLargeException {
18271 enforceNotIsolatedCaller("startService");
18272 // Refuse possible leaked file descriptors
18273 if (service != null && service.hasFileDescriptors() == true) {
18274 throw new IllegalArgumentException("File descriptors passed in Intent");
18277 if (callingPackage == null) {
18278 throw new IllegalArgumentException("callingPackage cannot be null");
18281 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18282 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18283 synchronized(this) {
18284 final int callingPid = Binder.getCallingPid();
18285 final int callingUid = Binder.getCallingUid();
18286 final long origId = Binder.clearCallingIdentity();
18289 res = mServices.startServiceLocked(caller, service,
18290 resolvedType, callingPid, callingUid,
18291 requireForeground, callingPackage, userId);
18293 Binder.restoreCallingIdentity(origId);
18299 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18300 boolean fgRequired, String callingPackage, int userId)
18301 throws TransactionTooLargeException {
18302 synchronized(this) {
18303 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18304 "startServiceInPackage: " + service + " type=" + resolvedType);
18305 final long origId = Binder.clearCallingIdentity();
18308 res = mServices.startServiceLocked(null, service,
18309 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18311 Binder.restoreCallingIdentity(origId);
18318 public int stopService(IApplicationThread caller, Intent service,
18319 String resolvedType, int userId) {
18320 enforceNotIsolatedCaller("stopService");
18321 // Refuse possible leaked file descriptors
18322 if (service != null && service.hasFileDescriptors() == true) {
18323 throw new IllegalArgumentException("File descriptors passed in Intent");
18326 synchronized(this) {
18327 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18332 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18333 enforceNotIsolatedCaller("peekService");
18334 // Refuse possible leaked file descriptors
18335 if (service != null && service.hasFileDescriptors() == true) {
18336 throw new IllegalArgumentException("File descriptors passed in Intent");
18339 if (callingPackage == null) {
18340 throw new IllegalArgumentException("callingPackage cannot be null");
18343 synchronized(this) {
18344 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18349 public boolean stopServiceToken(ComponentName className, IBinder token,
18351 synchronized(this) {
18352 return mServices.stopServiceTokenLocked(className, token, startId);
18357 public void setServiceForeground(ComponentName className, IBinder token,
18358 int id, Notification notification, int flags) {
18359 synchronized(this) {
18360 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18365 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18366 boolean requireFull, String name, String callerPackage) {
18367 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18368 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18371 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18372 String className, int flags) {
18373 boolean result = false;
18374 // For apps that don't have pre-defined UIDs, check for permission
18375 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18376 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18377 if (ActivityManager.checkUidPermission(
18378 INTERACT_ACROSS_USERS,
18379 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18380 ComponentName comp = new ComponentName(aInfo.packageName, className);
18381 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18382 + " requests FLAG_SINGLE_USER, but app does not hold "
18383 + INTERACT_ACROSS_USERS;
18385 throw new SecurityException(msg);
18387 // Permission passed
18390 } else if ("system".equals(componentProcessName)) {
18392 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18393 // Phone app and persistent apps are allowed to export singleuser providers.
18394 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18395 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18397 if (DEBUG_MU) Slog.v(TAG_MU,
18398 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18399 + Integer.toHexString(flags) + ") = " + result);
18404 * Checks to see if the caller is in the same app as the singleton
18405 * component, or the component is in a special app. It allows special apps
18406 * to export singleton components but prevents exporting singleton
18407 * components for regular apps.
18409 boolean isValidSingletonCall(int callingUid, int componentUid) {
18410 int componentAppId = UserHandle.getAppId(componentUid);
18411 return UserHandle.isSameApp(callingUid, componentUid)
18412 || componentAppId == SYSTEM_UID
18413 || componentAppId == PHONE_UID
18414 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18415 == PackageManager.PERMISSION_GRANTED;
18418 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18419 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18420 int userId) throws TransactionTooLargeException {
18421 enforceNotIsolatedCaller("bindService");
18423 // Refuse possible leaked file descriptors
18424 if (service != null && service.hasFileDescriptors() == true) {
18425 throw new IllegalArgumentException("File descriptors passed in Intent");
18428 if (callingPackage == null) {
18429 throw new IllegalArgumentException("callingPackage cannot be null");
18432 synchronized(this) {
18433 return mServices.bindServiceLocked(caller, token, service,
18434 resolvedType, connection, flags, callingPackage, userId);
18438 public boolean unbindService(IServiceConnection connection) {
18439 synchronized (this) {
18440 return mServices.unbindServiceLocked(connection);
18444 public void publishService(IBinder token, Intent intent, IBinder service) {
18445 // Refuse possible leaked file descriptors
18446 if (intent != null && intent.hasFileDescriptors() == true) {
18447 throw new IllegalArgumentException("File descriptors passed in Intent");
18450 synchronized(this) {
18451 if (!(token instanceof ServiceRecord)) {
18452 throw new IllegalArgumentException("Invalid service token");
18454 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18458 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18459 // Refuse possible leaked file descriptors
18460 if (intent != null && intent.hasFileDescriptors() == true) {
18461 throw new IllegalArgumentException("File descriptors passed in Intent");
18464 synchronized(this) {
18465 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18469 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18470 synchronized(this) {
18471 if (!(token instanceof ServiceRecord)) {
18472 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18473 throw new IllegalArgumentException("Invalid service token");
18475 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18479 // =========================================================
18480 // BACKUP AND RESTORE
18481 // =========================================================
18483 // Cause the target app to be launched if necessary and its backup agent
18484 // instantiated. The backup agent will invoke backupAgentCreated() on the
18485 // activity manager to announce its creation.
18486 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18487 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18488 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18490 IPackageManager pm = AppGlobals.getPackageManager();
18491 ApplicationInfo app = null;
18493 app = pm.getApplicationInfo(packageName, 0, userId);
18494 } catch (RemoteException e) {
18495 // can't happen; package manager is process-local
18498 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18505 synchronized(this) {
18506 // !!! TODO: currently no check here that we're already bound
18507 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18508 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18509 synchronized (stats) {
18510 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18513 // Backup agent is now in use, its package can't be stopped.
18515 AppGlobals.getPackageManager().setPackageStoppedState(
18516 app.packageName, false, UserHandle.getUserId(app.uid));
18517 } catch (RemoteException e) {
18518 } catch (IllegalArgumentException e) {
18519 Slog.w(TAG, "Failed trying to unstop package "
18520 + app.packageName + ": " + e);
18523 BackupRecord r = new BackupRecord(ss, app, backupMode);
18524 ComponentName hostingName =
18525 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18526 ? new ComponentName(app.packageName, app.backupAgentName)
18527 : new ComponentName("android", "FullBackupAgent");
18528 // startProcessLocked() returns existing proc's record if it's already running
18529 ProcessRecord proc = startProcessLocked(app.processName, app,
18530 false, 0, "backup", hostingName, false, false, false);
18531 if (proc == null) {
18532 Slog.e(TAG, "Unable to start backup agent process " + r);
18536 // If the app is a regular app (uid >= 10000) and not the system server or phone
18537 // process, etc, then mark it as being in full backup so that certain calls to the
18538 // process can be blocked. This is not reset to false anywhere because we kill the
18539 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18540 if (UserHandle.isApp(app.uid) &&
18541 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18542 proc.inFullBackup = true;
18545 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18546 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18548 mBackupAppName = app.packageName;
18550 // Try not to kill the process during backup
18551 updateOomAdjLocked(proc, true);
18553 // If the process is already attached, schedule the creation of the backup agent now.
18554 // If it is not yet live, this will be done when it attaches to the framework.
18555 if (proc.thread != null) {
18556 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18558 proc.thread.scheduleCreateBackupAgent(app,
18559 compatibilityInfoForPackageLocked(app), backupMode);
18560 } catch (RemoteException e) {
18561 // Will time out on the backup manager side
18564 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18566 // Invariants: at this point, the target app process exists and the application
18567 // is either already running or in the process of coming up. mBackupTarget and
18568 // mBackupAppName describe the app, so that when it binds back to the AM we
18569 // know that it's scheduled for a backup-agent operation.
18572 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18573 if (oldBackupUid != -1) {
18574 js.removeBackingUpUid(oldBackupUid);
18576 if (newBackupUid != -1) {
18577 js.addBackingUpUid(newBackupUid);
18584 public void clearPendingBackup() {
18585 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18586 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18588 synchronized (this) {
18589 mBackupTarget = null;
18590 mBackupAppName = null;
18593 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18594 js.clearAllBackingUpUids();
18597 // A backup agent has just come up
18598 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18599 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18602 synchronized(this) {
18603 if (!agentPackageName.equals(mBackupAppName)) {
18604 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18609 long oldIdent = Binder.clearCallingIdentity();
18611 IBackupManager bm = IBackupManager.Stub.asInterface(
18612 ServiceManager.getService(Context.BACKUP_SERVICE));
18613 bm.agentConnected(agentPackageName, agent);
18614 } catch (RemoteException e) {
18615 // can't happen; the backup manager service is local
18616 } catch (Exception e) {
18617 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18618 e.printStackTrace();
18620 Binder.restoreCallingIdentity(oldIdent);
18624 // done with this agent
18625 public void unbindBackupAgent(ApplicationInfo appInfo) {
18626 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18627 if (appInfo == null) {
18628 Slog.w(TAG, "unbind backup agent for null app");
18634 synchronized(this) {
18636 if (mBackupAppName == null) {
18637 Slog.w(TAG, "Unbinding backup agent with no active backup");
18641 if (!mBackupAppName.equals(appInfo.packageName)) {
18642 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18646 // Not backing this app up any more; reset its OOM adjustment
18647 final ProcessRecord proc = mBackupTarget.app;
18648 updateOomAdjLocked(proc, true);
18649 proc.inFullBackup = false;
18651 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18653 // If the app crashed during backup, 'thread' will be null here
18654 if (proc.thread != null) {
18656 proc.thread.scheduleDestroyBackupAgent(appInfo,
18657 compatibilityInfoForPackageLocked(appInfo));
18658 } catch (Exception e) {
18659 Slog.e(TAG, "Exception when unbinding backup agent:");
18660 e.printStackTrace();
18664 mBackupTarget = null;
18665 mBackupAppName = null;
18669 if (oldBackupUid != -1) {
18670 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18671 js.removeBackingUpUid(oldBackupUid);
18675 // =========================================================
18677 // =========================================================
18679 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18680 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18683 // Easy case -- we have the app's ProcessRecord.
18684 if (record != null) {
18685 return record.info.isInstantApp();
18687 // Otherwise check with PackageManager.
18688 if (callerPackage == null) {
18689 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18690 throw new IllegalArgumentException("Calling application did not provide package name");
18692 mAppOpsService.checkPackage(uid, callerPackage);
18694 IPackageManager pm = AppGlobals.getPackageManager();
18695 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18696 } catch (RemoteException e) {
18697 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18702 boolean isPendingBroadcastProcessLocked(int pid) {
18703 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18704 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18707 void skipPendingBroadcastLocked(int pid) {
18708 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18709 for (BroadcastQueue queue : mBroadcastQueues) {
18710 queue.skipPendingBroadcastLocked(pid);
18714 // The app just attached; send any pending broadcasts that it should receive
18715 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18716 boolean didSomething = false;
18717 for (BroadcastQueue queue : mBroadcastQueues) {
18718 didSomething |= queue.sendPendingBroadcastsLocked(app);
18720 return didSomething;
18723 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18724 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18726 enforceNotIsolatedCaller("registerReceiver");
18727 ArrayList<Intent> stickyIntents = null;
18728 ProcessRecord callerApp = null;
18729 final boolean visibleToInstantApps
18730 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18733 boolean instantApp;
18734 synchronized(this) {
18735 if (caller != null) {
18736 callerApp = getRecordForAppLocked(caller);
18737 if (callerApp == null) {
18738 throw new SecurityException(
18739 "Unable to find app for caller " + caller
18740 + " (pid=" + Binder.getCallingPid()
18741 + ") when registering receiver " + receiver);
18743 if (callerApp.info.uid != SYSTEM_UID &&
18744 !callerApp.pkgList.containsKey(callerPackage) &&
18745 !"android".equals(callerPackage)) {
18746 throw new SecurityException("Given caller package " + callerPackage
18747 + " is not running in process " + callerApp);
18749 callingUid = callerApp.info.uid;
18750 callingPid = callerApp.pid;
18752 callerPackage = null;
18753 callingUid = Binder.getCallingUid();
18754 callingPid = Binder.getCallingPid();
18757 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18758 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18759 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18761 Iterator<String> actions = filter.actionsIterator();
18762 if (actions == null) {
18763 ArrayList<String> noAction = new ArrayList<String>(1);
18764 noAction.add(null);
18765 actions = noAction.iterator();
18768 // Collect stickies of users
18769 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18770 while (actions.hasNext()) {
18771 String action = actions.next();
18772 for (int id : userIds) {
18773 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18774 if (stickies != null) {
18775 ArrayList<Intent> intents = stickies.get(action);
18776 if (intents != null) {
18777 if (stickyIntents == null) {
18778 stickyIntents = new ArrayList<Intent>();
18780 stickyIntents.addAll(intents);
18787 ArrayList<Intent> allSticky = null;
18788 if (stickyIntents != null) {
18789 final ContentResolver resolver = mContext.getContentResolver();
18790 // Look for any matching sticky broadcasts...
18791 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18792 Intent intent = stickyIntents.get(i);
18793 // Don't provided intents that aren't available to instant apps.
18795 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18798 // If intent has scheme "content", it will need to acccess
18799 // provider that needs to lock mProviderMap in ActivityThread
18800 // and also it may need to wait application response, so we
18801 // cannot lock ActivityManagerService here.
18802 if (filter.match(resolver, intent, true, TAG) >= 0) {
18803 if (allSticky == null) {
18804 allSticky = new ArrayList<Intent>();
18806 allSticky.add(intent);
18811 // The first sticky in the list is returned directly back to the client.
18812 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18813 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18814 if (receiver == null) {
18818 synchronized (this) {
18819 if (callerApp != null && (callerApp.thread == null
18820 || callerApp.thread.asBinder() != caller.asBinder())) {
18821 // Original caller already died
18824 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18826 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18828 if (rl.app != null) {
18829 rl.app.receivers.add(rl);
18832 receiver.asBinder().linkToDeath(rl, 0);
18833 } catch (RemoteException e) {
18836 rl.linkedToDeath = true;
18838 mRegisteredReceivers.put(receiver.asBinder(), rl);
18839 } else if (rl.uid != callingUid) {
18840 throw new IllegalArgumentException(
18841 "Receiver requested to register for uid " + callingUid
18842 + " was previously registered for uid " + rl.uid
18843 + " callerPackage is " + callerPackage);
18844 } else if (rl.pid != callingPid) {
18845 throw new IllegalArgumentException(
18846 "Receiver requested to register for pid " + callingPid
18847 + " was previously registered for pid " + rl.pid
18848 + " callerPackage is " + callerPackage);
18849 } else if (rl.userId != userId) {
18850 throw new IllegalArgumentException(
18851 "Receiver requested to register for user " + userId
18852 + " was previously registered for user " + rl.userId
18853 + " callerPackage is " + callerPackage);
18855 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18856 permission, callingUid, userId, instantApp, visibleToInstantApps);
18858 if (!bf.debugCheck()) {
18859 Slog.w(TAG, "==> For Dynamic broadcast");
18861 mReceiverResolver.addFilter(bf);
18863 // Enqueue broadcasts for all existing stickies that match
18865 if (allSticky != null) {
18866 ArrayList receivers = new ArrayList();
18869 final int stickyCount = allSticky.size();
18870 for (int i = 0; i < stickyCount; i++) {
18871 Intent intent = allSticky.get(i);
18872 BroadcastQueue queue = broadcastQueueForIntent(intent);
18873 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18874 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18875 null, 0, null, null, false, true, true, -1);
18876 queue.enqueueParallelBroadcastLocked(r);
18877 queue.scheduleBroadcastsLocked();
18885 public void unregisterReceiver(IIntentReceiver receiver) {
18886 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18888 final long origId = Binder.clearCallingIdentity();
18890 boolean doTrim = false;
18892 synchronized(this) {
18893 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18895 final BroadcastRecord r = rl.curBroadcast;
18896 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18897 final boolean doNext = r.queue.finishReceiverLocked(
18898 r, r.resultCode, r.resultData, r.resultExtras,
18899 r.resultAbort, false);
18902 r.queue.processNextBroadcast(false);
18906 if (rl.app != null) {
18907 rl.app.receivers.remove(rl);
18909 removeReceiverLocked(rl);
18910 if (rl.linkedToDeath) {
18911 rl.linkedToDeath = false;
18912 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18917 // If we actually concluded any broadcasts, we might now be able
18918 // to trim the recipients' apps from our working set
18920 trimApplications();
18925 Binder.restoreCallingIdentity(origId);
18929 void removeReceiverLocked(ReceiverList rl) {
18930 mRegisteredReceivers.remove(rl.receiver.asBinder());
18931 for (int i = rl.size() - 1; i >= 0; i--) {
18932 mReceiverResolver.removeFilter(rl.get(i));
18936 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18937 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18938 ProcessRecord r = mLruProcesses.get(i);
18939 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18941 r.thread.dispatchPackageBroadcast(cmd, packages);
18942 } catch (RemoteException ex) {
18948 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18949 int callingUid, int[] users) {
18950 // TODO: come back and remove this assumption to triage all broadcasts
18951 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18953 List<ResolveInfo> receivers = null;
18955 HashSet<ComponentName> singleUserReceivers = null;
18956 boolean scannedFirstReceivers = false;
18957 for (int user : users) {
18958 // Skip users that have Shell restrictions, with exception of always permitted
18959 // Shell broadcasts
18960 if (callingUid == SHELL_UID
18961 && mUserController.hasUserRestriction(
18962 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18963 && !isPermittedShellBroadcast(intent)) {
18966 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18967 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18968 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18969 // If this is not the system user, we need to check for
18970 // any receivers that should be filtered out.
18971 for (int i=0; i<newReceivers.size(); i++) {
18972 ResolveInfo ri = newReceivers.get(i);
18973 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18974 newReceivers.remove(i);
18979 if (newReceivers != null && newReceivers.size() == 0) {
18980 newReceivers = null;
18982 if (receivers == null) {
18983 receivers = newReceivers;
18984 } else if (newReceivers != null) {
18985 // We need to concatenate the additional receivers
18986 // found with what we have do far. This would be easy,
18987 // but we also need to de-dup any receivers that are
18989 if (!scannedFirstReceivers) {
18990 // Collect any single user receivers we had already retrieved.
18991 scannedFirstReceivers = true;
18992 for (int i=0; i<receivers.size(); i++) {
18993 ResolveInfo ri = receivers.get(i);
18994 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18995 ComponentName cn = new ComponentName(
18996 ri.activityInfo.packageName, ri.activityInfo.name);
18997 if (singleUserReceivers == null) {
18998 singleUserReceivers = new HashSet<ComponentName>();
19000 singleUserReceivers.add(cn);
19004 // Add the new results to the existing results, tracking
19005 // and de-dupping single user receivers.
19006 for (int i=0; i<newReceivers.size(); i++) {
19007 ResolveInfo ri = newReceivers.get(i);
19008 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19009 ComponentName cn = new ComponentName(
19010 ri.activityInfo.packageName, ri.activityInfo.name);
19011 if (singleUserReceivers == null) {
19012 singleUserReceivers = new HashSet<ComponentName>();
19014 if (!singleUserReceivers.contains(cn)) {
19015 singleUserReceivers.add(cn);
19024 } catch (RemoteException ex) {
19025 // pm is in same process, this will never happen.
19030 private boolean isPermittedShellBroadcast(Intent intent) {
19031 // remote bugreport should always be allowed to be taken
19032 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19035 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19036 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19037 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19038 // Don't yell about broadcasts sent via shell
19042 final String action = intent.getAction();
19043 if (isProtectedBroadcast
19044 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19045 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19046 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19047 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19048 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19049 || Intent.ACTION_MASTER_CLEAR.equals(action)
19050 || Intent.ACTION_FACTORY_RESET.equals(action)
19051 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19052 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19053 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19054 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19055 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19056 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19057 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19058 // Broadcast is either protected, or it's a public action that
19059 // we've relaxed, so it's fine for system internals to send.
19063 // This broadcast may be a problem... but there are often system components that
19064 // want to send an internal broadcast to themselves, which is annoying to have to
19065 // explicitly list each action as a protected broadcast, so we will check for that
19066 // one safe case and allow it: an explicit broadcast, only being received by something
19067 // that has protected itself.
19068 if (receivers != null && receivers.size() > 0
19069 && (intent.getPackage() != null || intent.getComponent() != null)) {
19070 boolean allProtected = true;
19071 for (int i = receivers.size()-1; i >= 0; i--) {
19072 Object target = receivers.get(i);
19073 if (target instanceof ResolveInfo) {
19074 ResolveInfo ri = (ResolveInfo)target;
19075 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19076 allProtected = false;
19080 BroadcastFilter bf = (BroadcastFilter)target;
19081 if (bf.requiredPermission == null) {
19082 allProtected = false;
19087 if (allProtected) {
19093 // The vast majority of broadcasts sent from system internals
19094 // should be protected to avoid security holes, so yell loudly
19095 // to ensure we examine these cases.
19096 if (callerApp != null) {
19097 Log.wtf(TAG, "Sending non-protected broadcast " + action
19098 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19101 Log.wtf(TAG, "Sending non-protected broadcast " + action
19102 + " from system uid " + UserHandle.formatUid(callingUid)
19103 + " pkg " + callerPackage,
19108 final int broadcastIntentLocked(ProcessRecord callerApp,
19109 String callerPackage, Intent intent, String resolvedType,
19110 IIntentReceiver resultTo, int resultCode, String resultData,
19111 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19112 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19113 intent = new Intent(intent);
19115 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19116 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19117 if (callerInstantApp) {
19118 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19121 // By default broadcasts do not go to stopped apps.
19122 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19124 // If we have not finished booting, don't allow this to launch new processes.
19125 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19126 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19129 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19130 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19131 + " ordered=" + ordered + " userid=" + userId);
19132 if ((resultTo != null) && !ordered) {
19133 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19136 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19137 ALLOW_NON_FULL, "broadcast", callerPackage);
19139 // Make sure that the user who is receiving this broadcast is running.
19140 // If not, we will just skip it. Make an exception for shutdown broadcasts
19141 // and upgrade steps.
19143 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19144 if ((callingUid != SYSTEM_UID
19145 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19146 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19147 Slog.w(TAG, "Skipping broadcast of " + intent
19148 + ": user " + userId + " is stopped");
19149 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19153 BroadcastOptions brOptions = null;
19154 if (bOptions != null) {
19155 brOptions = new BroadcastOptions(bOptions);
19156 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19157 // See if the caller is allowed to do this. Note we are checking against
19158 // the actual real caller (not whoever provided the operation as say a
19159 // PendingIntent), because that who is actually supplied the arguments.
19160 if (checkComponentPermission(
19161 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19162 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19163 != PackageManager.PERMISSION_GRANTED) {
19164 String msg = "Permission Denial: " + intent.getAction()
19165 + " broadcast from " + callerPackage + " (pid=" + callingPid
19166 + ", uid=" + callingUid + ")"
19168 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19170 throw new SecurityException(msg);
19175 // Verify that protected broadcasts are only being sent by system code,
19176 // and that system code is only sending protected broadcasts.
19177 final String action = intent.getAction();
19178 final boolean isProtectedBroadcast;
19180 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19181 } catch (RemoteException e) {
19182 Slog.w(TAG, "Remote exception", e);
19183 return ActivityManager.BROADCAST_SUCCESS;
19186 final boolean isCallerSystem;
19187 switch (UserHandle.getAppId(callingUid)) {
19191 case BLUETOOTH_UID:
19193 isCallerSystem = true;
19196 isCallerSystem = (callerApp != null) && callerApp.persistent;
19200 // First line security check before anything else: stop non-system apps from
19201 // sending protected broadcasts.
19202 if (!isCallerSystem) {
19203 if (isProtectedBroadcast) {
19204 String msg = "Permission Denial: not allowed to send broadcast "
19205 + action + " from pid="
19206 + callingPid + ", uid=" + callingUid;
19208 throw new SecurityException(msg);
19210 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19211 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19212 // Special case for compatibility: we don't want apps to send this,
19213 // but historically it has not been protected and apps may be using it
19214 // to poke their own app widget. So, instead of making it protected,
19215 // just limit it to the caller.
19216 if (callerPackage == null) {
19217 String msg = "Permission Denial: not allowed to send broadcast "
19218 + action + " from unknown caller.";
19220 throw new SecurityException(msg);
19221 } else if (intent.getComponent() != null) {
19222 // They are good enough to send to an explicit component... verify
19223 // it is being sent to the calling app.
19224 if (!intent.getComponent().getPackageName().equals(
19226 String msg = "Permission Denial: not allowed to send broadcast "
19228 + intent.getComponent().getPackageName() + " from "
19231 throw new SecurityException(msg);
19234 // Limit broadcast to their own package.
19235 intent.setPackage(callerPackage);
19240 if (action != null) {
19241 if (getBackgroundLaunchBroadcasts().contains(action)) {
19242 if (DEBUG_BACKGROUND_CHECK) {
19243 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19245 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19249 case Intent.ACTION_UID_REMOVED:
19250 case Intent.ACTION_PACKAGE_REMOVED:
19251 case Intent.ACTION_PACKAGE_CHANGED:
19252 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19253 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19254 case Intent.ACTION_PACKAGES_SUSPENDED:
19255 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19256 // Handle special intents: if this broadcast is from the package
19257 // manager about a package being removed, we need to remove all of
19258 // its activities from the history stack.
19259 if (checkComponentPermission(
19260 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19261 callingPid, callingUid, -1, true)
19262 != PackageManager.PERMISSION_GRANTED) {
19263 String msg = "Permission Denial: " + intent.getAction()
19264 + " broadcast from " + callerPackage + " (pid=" + callingPid
19265 + ", uid=" + callingUid + ")"
19267 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19269 throw new SecurityException(msg);
19272 case Intent.ACTION_UID_REMOVED:
19273 final int uid = getUidFromIntent(intent);
19275 mBatteryStatsService.removeUid(uid);
19276 mAppOpsService.uidRemoved(uid);
19279 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19280 // If resources are unavailable just force stop all those packages
19281 // and flush the attribute cache as well.
19283 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19284 if (list != null && list.length > 0) {
19285 for (int i = 0; i < list.length; i++) {
19286 forceStopPackageLocked(list[i], -1, false, true, true,
19287 false, false, userId, "storage unmount");
19289 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19290 sendPackageBroadcastLocked(
19291 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19295 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19296 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19298 case Intent.ACTION_PACKAGE_REMOVED:
19299 case Intent.ACTION_PACKAGE_CHANGED:
19300 Uri data = intent.getData();
19302 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19303 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19304 final boolean replacing =
19305 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19306 final boolean killProcess =
19307 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19308 final boolean fullUninstall = removed && !replacing;
19311 forceStopPackageLocked(ssp, UserHandle.getAppId(
19312 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19313 false, true, true, false, fullUninstall, userId,
19314 removed ? "pkg removed" : "pkg changed");
19316 final int cmd = killProcess
19317 ? ApplicationThreadConstants.PACKAGE_REMOVED
19318 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19319 sendPackageBroadcastLocked(cmd,
19320 new String[] {ssp}, userId);
19321 if (fullUninstall) {
19322 mAppOpsService.packageRemoved(
19323 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19325 // Remove all permissions granted from/to this package
19326 removeUriPermissionsForPackageLocked(ssp, userId, true);
19328 removeTasksByPackageNameLocked(ssp, userId);
19330 mServices.forceStopPackageLocked(ssp, userId);
19332 // Hide the "unsupported display" dialog if necessary.
19333 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19334 mUnsupportedDisplaySizeDialog.getPackageName())) {
19335 mUnsupportedDisplaySizeDialog.dismiss();
19336 mUnsupportedDisplaySizeDialog = null;
19338 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19339 mBatteryStatsService.notePackageUninstalled(ssp);
19343 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19344 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19345 userId, ProcessList.INVALID_ADJ,
19346 false, true, true, false, "change " + ssp);
19348 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19349 intent.getStringArrayExtra(
19350 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19354 case Intent.ACTION_PACKAGES_SUSPENDED:
19355 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19356 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19357 intent.getAction());
19358 final String[] packageNames = intent.getStringArrayExtra(
19359 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19360 final int userHandle = intent.getIntExtra(
19361 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19363 synchronized(ActivityManagerService.this) {
19364 mRecentTasks.onPackagesSuspendedChanged(
19365 packageNames, suspended, userHandle);
19370 case Intent.ACTION_PACKAGE_REPLACED:
19372 final Uri data = intent.getData();
19374 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19375 ApplicationInfo aInfo = null;
19377 aInfo = AppGlobals.getPackageManager()
19378 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19379 } catch (RemoteException ignore) {}
19380 if (aInfo == null) {
19381 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19382 + " ssp=" + ssp + " data=" + data);
19383 return ActivityManager.BROADCAST_SUCCESS;
19385 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19386 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19387 new String[] {ssp}, userId);
19391 case Intent.ACTION_PACKAGE_ADDED:
19393 // Special case for adding a package: by default turn on compatibility mode.
19394 Uri data = intent.getData();
19396 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19397 final boolean replacing =
19398 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19399 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19402 ApplicationInfo ai = AppGlobals.getPackageManager().
19403 getApplicationInfo(ssp, 0, 0);
19404 mBatteryStatsService.notePackageInstalled(ssp,
19405 ai != null ? ai.versionCode : 0);
19406 } catch (RemoteException e) {
19411 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19413 Uri data = intent.getData();
19415 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19416 // Hide the "unsupported display" dialog if necessary.
19417 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19418 mUnsupportedDisplaySizeDialog.getPackageName())) {
19419 mUnsupportedDisplaySizeDialog.dismiss();
19420 mUnsupportedDisplaySizeDialog = null;
19422 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19426 case Intent.ACTION_TIMEZONE_CHANGED:
19427 // If this is the time zone changed action, queue up a message that will reset
19428 // the timezone of all currently running processes. This message will get
19429 // queued up before the broadcast happens.
19430 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19432 case Intent.ACTION_TIME_CHANGED:
19433 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19434 // the tri-state value it may contain and "unknown".
19435 // For convenience we re-use the Intent extra values.
19436 final int NO_EXTRA_VALUE_FOUND = -1;
19437 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19438 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19439 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19440 // Only send a message if the time preference is available.
19441 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19442 Message updateTimePreferenceMsg =
19443 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19444 timeFormatPreferenceMsgValue, 0);
19445 mHandler.sendMessage(updateTimePreferenceMsg);
19447 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19448 synchronized (stats) {
19449 stats.noteCurrentTimeChangedLocked();
19452 case Intent.ACTION_CLEAR_DNS_CACHE:
19453 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19455 case Proxy.PROXY_CHANGE_ACTION:
19456 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19457 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19459 case android.hardware.Camera.ACTION_NEW_PICTURE:
19460 case android.hardware.Camera.ACTION_NEW_VIDEO:
19461 // In N we just turned these off; in O we are turing them back on partly,
19462 // only for registered receivers. This will still address the main problem
19463 // (a spam of apps waking up when a picture is taken putting significant
19464 // memory pressure on the system at a bad point), while still allowing apps
19465 // that are already actively running to know about this happening.
19466 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19468 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19469 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19471 case "com.android.launcher.action.INSTALL_SHORTCUT":
19472 // As of O, we no longer support this broadcasts, even for pre-O apps.
19473 // Apps should now be using ShortcutManager.pinRequestShortcut().
19474 Log.w(TAG, "Broadcast " + action
19475 + " no longer supported. It will not be delivered.");
19476 return ActivityManager.BROADCAST_SUCCESS;
19479 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19480 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19481 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19482 final int uid = getUidFromIntent(intent);
19484 final UidRecord uidRec = mActiveUids.get(uid);
19485 if (uidRec != null) {
19486 uidRec.updateHasInternetPermission();
19492 // Add to the sticky list if requested.
19494 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19495 callingPid, callingUid)
19496 != PackageManager.PERMISSION_GRANTED) {
19497 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19498 + callingPid + ", uid=" + callingUid
19499 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19501 throw new SecurityException(msg);
19503 if (requiredPermissions != null && requiredPermissions.length > 0) {
19504 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19505 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19506 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19508 if (intent.getComponent() != null) {
19509 throw new SecurityException(
19510 "Sticky broadcasts can't target a specific component");
19512 // We use userId directly here, since the "all" target is maintained
19513 // as a separate set of sticky broadcasts.
19514 if (userId != UserHandle.USER_ALL) {
19515 // But first, if this is not a broadcast to all users, then
19516 // make sure it doesn't conflict with an existing broadcast to
19518 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19519 UserHandle.USER_ALL);
19520 if (stickies != null) {
19521 ArrayList<Intent> list = stickies.get(intent.getAction());
19522 if (list != null) {
19523 int N = list.size();
19525 for (i=0; i<N; i++) {
19526 if (intent.filterEquals(list.get(i))) {
19527 throw new IllegalArgumentException(
19528 "Sticky broadcast " + intent + " for user "
19529 + userId + " conflicts with existing global broadcast");
19535 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19536 if (stickies == null) {
19537 stickies = new ArrayMap<>();
19538 mStickyBroadcasts.put(userId, stickies);
19540 ArrayList<Intent> list = stickies.get(intent.getAction());
19541 if (list == null) {
19542 list = new ArrayList<>();
19543 stickies.put(intent.getAction(), list);
19545 final int stickiesCount = list.size();
19547 for (i = 0; i < stickiesCount; i++) {
19548 if (intent.filterEquals(list.get(i))) {
19549 // This sticky already exists, replace it.
19550 list.set(i, new Intent(intent));
19554 if (i >= stickiesCount) {
19555 list.add(new Intent(intent));
19560 if (userId == UserHandle.USER_ALL) {
19561 // Caller wants broadcast to go to all started users.
19562 users = mUserController.getStartedUserArrayLocked();
19564 // Caller wants broadcast to go to one specific user.
19565 users = new int[] {userId};
19568 // Figure out who all will receive this broadcast.
19569 List receivers = null;
19570 List<BroadcastFilter> registeredReceivers = null;
19571 // Need to resolve the intent to interested receivers...
19572 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19574 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19576 if (intent.getComponent() == null) {
19577 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19578 // Query one target user at a time, excluding shell-restricted users
19579 for (int i = 0; i < users.length; i++) {
19580 if (mUserController.hasUserRestriction(
19581 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19584 List<BroadcastFilter> registeredReceiversForUser =
19585 mReceiverResolver.queryIntent(intent,
19586 resolvedType, false /*defaultOnly*/, users[i]);
19587 if (registeredReceivers == null) {
19588 registeredReceivers = registeredReceiversForUser;
19589 } else if (registeredReceiversForUser != null) {
19590 registeredReceivers.addAll(registeredReceiversForUser);
19594 registeredReceivers = mReceiverResolver.queryIntent(intent,
19595 resolvedType, false /*defaultOnly*/, userId);
19599 final boolean replacePending =
19600 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19602 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19603 + " replacePending=" + replacePending);
19605 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19606 if (!ordered && NR > 0) {
19607 // If we are not serializing this broadcast, then send the
19608 // registered receivers separately so they don't wait for the
19609 // components to be launched.
19610 if (isCallerSystem) {
19611 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19612 isProtectedBroadcast, registeredReceivers);
19614 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19615 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19616 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19617 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19618 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19619 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19620 final boolean replaced = replacePending
19621 && (queue.replaceParallelBroadcastLocked(r) != null);
19622 // Note: We assume resultTo is null for non-ordered broadcasts.
19624 queue.enqueueParallelBroadcastLocked(r);
19625 queue.scheduleBroadcastsLocked();
19627 registeredReceivers = null;
19631 // Merge into one list.
19633 if (receivers != null) {
19634 // A special case for PACKAGE_ADDED: do not allow the package
19635 // being added to see this broadcast. This prevents them from
19636 // using this as a back door to get run as soon as they are
19637 // installed. Maybe in the future we want to have a special install
19638 // broadcast or such for apps, but we'd like to deliberately make
19640 String skipPackages[] = null;
19641 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19642 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19643 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19644 Uri data = intent.getData();
19645 if (data != null) {
19646 String pkgName = data.getSchemeSpecificPart();
19647 if (pkgName != null) {
19648 skipPackages = new String[] { pkgName };
19651 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19652 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19654 if (skipPackages != null && (skipPackages.length > 0)) {
19655 for (String skipPackage : skipPackages) {
19656 if (skipPackage != null) {
19657 int NT = receivers.size();
19658 for (int it=0; it<NT; it++) {
19659 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19660 if (curt.activityInfo.packageName.equals(skipPackage)) {
19661 receivers.remove(it);
19670 int NT = receivers != null ? receivers.size() : 0;
19672 ResolveInfo curt = null;
19673 BroadcastFilter curr = null;
19674 while (it < NT && ir < NR) {
19675 if (curt == null) {
19676 curt = (ResolveInfo)receivers.get(it);
19678 if (curr == null) {
19679 curr = registeredReceivers.get(ir);
19681 if (curr.getPriority() >= curt.priority) {
19682 // Insert this broadcast record into the final list.
19683 receivers.add(it, curr);
19689 // Skip to the next ResolveInfo in the final list.
19696 if (receivers == null) {
19697 receivers = new ArrayList();
19699 receivers.add(registeredReceivers.get(ir));
19703 if (isCallerSystem) {
19704 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19705 isProtectedBroadcast, receivers);
19708 if ((receivers != null && receivers.size() > 0)
19709 || resultTo != null) {
19710 BroadcastQueue queue = broadcastQueueForIntent(intent);
19711 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19712 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19713 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19714 resultData, resultExtras, ordered, sticky, false, userId);
19716 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19717 + ": prev had " + queue.mOrderedBroadcasts.size());
19718 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19719 "Enqueueing broadcast " + r.intent.getAction());
19721 final BroadcastRecord oldRecord =
19722 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19723 if (oldRecord != null) {
19724 // Replaced, fire the result-to receiver.
19725 if (oldRecord.resultTo != null) {
19726 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19728 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19730 Activity.RESULT_CANCELED, null, null,
19731 false, false, oldRecord.userId);
19732 } catch (RemoteException e) {
19733 Slog.w(TAG, "Failure ["
19734 + queue.mQueueName + "] sending broadcast result of "
19740 queue.enqueueOrderedBroadcastLocked(r);
19741 queue.scheduleBroadcastsLocked();
19744 // There was nobody interested in the broadcast, but we still want to record
19745 // that it happened.
19746 if (intent.getComponent() == null && intent.getPackage() == null
19747 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19748 // This was an implicit broadcast... let's record it for posterity.
19749 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19753 return ActivityManager.BROADCAST_SUCCESS;
19757 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19759 private int getUidFromIntent(Intent intent) {
19760 if (intent == null) {
19763 final Bundle intentExtras = intent.getExtras();
19764 return intent.hasExtra(Intent.EXTRA_UID)
19765 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19768 final void rotateBroadcastStatsIfNeededLocked() {
19769 final long now = SystemClock.elapsedRealtime();
19770 if (mCurBroadcastStats == null ||
19771 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19772 mLastBroadcastStats = mCurBroadcastStats;
19773 if (mLastBroadcastStats != null) {
19774 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19775 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19777 mCurBroadcastStats = new BroadcastStats();
19781 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19782 int skipCount, long dispatchTime) {
19783 rotateBroadcastStatsIfNeededLocked();
19784 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19787 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19788 rotateBroadcastStatsIfNeededLocked();
19789 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19792 final Intent verifyBroadcastLocked(Intent intent) {
19793 // Refuse possible leaked file descriptors
19794 if (intent != null && intent.hasFileDescriptors() == true) {
19795 throw new IllegalArgumentException("File descriptors passed in Intent");
19798 int flags = intent.getFlags();
19800 if (!mProcessesReady) {
19801 // if the caller really truly claims to know what they're doing, go
19802 // ahead and allow the broadcast without launching any receivers
19803 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19804 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19805 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19806 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19807 + " before boot completion");
19808 throw new IllegalStateException("Cannot broadcast before boot completed");
19812 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19813 throw new IllegalArgumentException(
19814 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19817 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19818 switch (Binder.getCallingUid()) {
19823 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19824 + Binder.getCallingUid());
19825 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19833 public final int broadcastIntent(IApplicationThread caller,
19834 Intent intent, String resolvedType, IIntentReceiver resultTo,
19835 int resultCode, String resultData, Bundle resultExtras,
19836 String[] requiredPermissions, int appOp, Bundle bOptions,
19837 boolean serialized, boolean sticky, int userId) {
19838 enforceNotIsolatedCaller("broadcastIntent");
19839 synchronized(this) {
19840 intent = verifyBroadcastLocked(intent);
19842 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19843 final int callingPid = Binder.getCallingPid();
19844 final int callingUid = Binder.getCallingUid();
19845 final long origId = Binder.clearCallingIdentity();
19846 int res = broadcastIntentLocked(callerApp,
19847 callerApp != null ? callerApp.info.packageName : null,
19848 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19849 requiredPermissions, appOp, bOptions, serialized, sticky,
19850 callingPid, callingUid, userId);
19851 Binder.restoreCallingIdentity(origId);
19857 int broadcastIntentInPackage(String packageName, int uid,
19858 Intent intent, String resolvedType, IIntentReceiver resultTo,
19859 int resultCode, String resultData, Bundle resultExtras,
19860 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19862 synchronized(this) {
19863 intent = verifyBroadcastLocked(intent);
19865 final long origId = Binder.clearCallingIdentity();
19866 String[] requiredPermissions = requiredPermission == null ? null
19867 : new String[] {requiredPermission};
19868 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19869 resultTo, resultCode, resultData, resultExtras,
19870 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19871 sticky, -1, uid, userId);
19872 Binder.restoreCallingIdentity(origId);
19877 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19878 // Refuse possible leaked file descriptors
19879 if (intent != null && intent.hasFileDescriptors() == true) {
19880 throw new IllegalArgumentException("File descriptors passed in Intent");
19883 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19884 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19886 synchronized(this) {
19887 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19888 != PackageManager.PERMISSION_GRANTED) {
19889 String msg = "Permission Denial: unbroadcastIntent() from pid="
19890 + Binder.getCallingPid()
19891 + ", uid=" + Binder.getCallingUid()
19892 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19894 throw new SecurityException(msg);
19896 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19897 if (stickies != null) {
19898 ArrayList<Intent> list = stickies.get(intent.getAction());
19899 if (list != null) {
19900 int N = list.size();
19902 for (i=0; i<N; i++) {
19903 if (intent.filterEquals(list.get(i))) {
19908 if (list.size() <= 0) {
19909 stickies.remove(intent.getAction());
19912 if (stickies.size() <= 0) {
19913 mStickyBroadcasts.remove(userId);
19919 void backgroundServicesFinishedLocked(int userId) {
19920 for (BroadcastQueue queue : mBroadcastQueues) {
19921 queue.backgroundServicesFinishedLocked(userId);
19925 public void finishReceiver(IBinder who, int resultCode, String resultData,
19926 Bundle resultExtras, boolean resultAbort, int flags) {
19927 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19929 // Refuse possible leaked file descriptors
19930 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19931 throw new IllegalArgumentException("File descriptors passed in Bundle");
19934 final long origId = Binder.clearCallingIdentity();
19936 boolean doNext = false;
19939 synchronized(this) {
19940 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19941 ? mFgBroadcastQueue : mBgBroadcastQueue;
19942 r = queue.getMatchingOrderedReceiver(who);
19944 doNext = r.queue.finishReceiverLocked(r, resultCode,
19945 resultData, resultExtras, resultAbort, true);
19950 r.queue.processNextBroadcast(false);
19952 trimApplications();
19954 Binder.restoreCallingIdentity(origId);
19958 // =========================================================
19960 // =========================================================
19962 public boolean startInstrumentation(ComponentName className,
19963 String profileFile, int flags, Bundle arguments,
19964 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19965 int userId, String abiOverride) {
19966 enforceNotIsolatedCaller("startInstrumentation");
19967 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19968 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19969 // Refuse possible leaked file descriptors
19970 if (arguments != null && arguments.hasFileDescriptors()) {
19971 throw new IllegalArgumentException("File descriptors passed in Bundle");
19974 synchronized(this) {
19975 InstrumentationInfo ii = null;
19976 ApplicationInfo ai = null;
19978 ii = mContext.getPackageManager().getInstrumentationInfo(
19979 className, STOCK_PM_FLAGS);
19980 ai = AppGlobals.getPackageManager().getApplicationInfo(
19981 ii.targetPackage, STOCK_PM_FLAGS, userId);
19982 } catch (PackageManager.NameNotFoundException e) {
19983 } catch (RemoteException e) {
19986 reportStartInstrumentationFailureLocked(watcher, className,
19987 "Unable to find instrumentation info for: " + className);
19991 reportStartInstrumentationFailureLocked(watcher, className,
19992 "Unable to find instrumentation target package: " + ii.targetPackage);
19995 if (!ai.hasCode()) {
19996 reportStartInstrumentationFailureLocked(watcher, className,
19997 "Instrumentation target has no code: " + ii.targetPackage);
20001 int match = mContext.getPackageManager().checkSignatures(
20002 ii.targetPackage, ii.packageName);
20003 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20004 String msg = "Permission Denial: starting instrumentation "
20005 + className + " from pid="
20006 + Binder.getCallingPid()
20007 + ", uid=" + Binder.getCallingPid()
20008 + " not allowed because package " + ii.packageName
20009 + " does not have a signature matching the target "
20010 + ii.targetPackage;
20011 reportStartInstrumentationFailureLocked(watcher, className, msg);
20012 throw new SecurityException(msg);
20015 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20016 activeInstr.mClass = className;
20017 String defProcess = ai.processName;;
20018 if (ii.targetProcesses == null) {
20019 activeInstr.mTargetProcesses = new String[]{ai.processName};
20020 } else if (ii.targetProcesses.equals("*")) {
20021 activeInstr.mTargetProcesses = new String[0];
20023 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20024 defProcess = activeInstr.mTargetProcesses[0];
20026 activeInstr.mTargetInfo = ai;
20027 activeInstr.mProfileFile = profileFile;
20028 activeInstr.mArguments = arguments;
20029 activeInstr.mWatcher = watcher;
20030 activeInstr.mUiAutomationConnection = uiAutomationConnection;
20031 activeInstr.mResultClass = className;
20033 final long origId = Binder.clearCallingIdentity();
20034 // Instrumentation can kill and relaunch even persistent processes
20035 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20037 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20038 app.instr = activeInstr;
20039 activeInstr.mFinished = false;
20040 activeInstr.mRunningProcesses.add(app);
20041 if (!mActiveInstrumentation.contains(activeInstr)) {
20042 mActiveInstrumentation.add(activeInstr);
20044 Binder.restoreCallingIdentity(origId);
20051 * Report errors that occur while attempting to start Instrumentation. Always writes the
20052 * error to the logs, but if somebody is watching, send the report there too. This enables
20053 * the "am" command to report errors with more information.
20055 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
20056 * @param cn The component name of the instrumentation.
20057 * @param report The error report.
20059 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20060 ComponentName cn, String report) {
20061 Slog.w(TAG, report);
20062 if (watcher != null) {
20063 Bundle results = new Bundle();
20064 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20065 results.putString("Error", report);
20066 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20070 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20071 if (app.instr == null) {
20072 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20076 if (!app.instr.mFinished && results != null) {
20077 if (app.instr.mCurResults == null) {
20078 app.instr.mCurResults = new Bundle(results);
20080 app.instr.mCurResults.putAll(results);
20085 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20086 int userId = UserHandle.getCallingUserId();
20087 // Refuse possible leaked file descriptors
20088 if (results != null && results.hasFileDescriptors()) {
20089 throw new IllegalArgumentException("File descriptors passed in Intent");
20092 synchronized(this) {
20093 ProcessRecord app = getRecordForAppLocked(target);
20095 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20098 final long origId = Binder.clearCallingIdentity();
20099 addInstrumentationResultsLocked(app, results);
20100 Binder.restoreCallingIdentity(origId);
20104 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20105 if (app.instr == null) {
20106 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20110 if (!app.instr.mFinished) {
20111 if (app.instr.mWatcher != null) {
20112 Bundle finalResults = app.instr.mCurResults;
20113 if (finalResults != null) {
20114 if (app.instr.mCurResults != null && results != null) {
20115 finalResults.putAll(results);
20118 finalResults = results;
20120 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20121 app.instr.mClass, resultCode, finalResults);
20124 // Can't call out of the system process with a lock held, so post a message.
20125 if (app.instr.mUiAutomationConnection != null) {
20126 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20127 app.instr.mUiAutomationConnection).sendToTarget();
20129 app.instr.mFinished = true;
20132 app.instr.removeProcess(app);
20135 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20139 public void finishInstrumentation(IApplicationThread target,
20140 int resultCode, Bundle results) {
20141 int userId = UserHandle.getCallingUserId();
20142 // Refuse possible leaked file descriptors
20143 if (results != null && results.hasFileDescriptors()) {
20144 throw new IllegalArgumentException("File descriptors passed in Intent");
20147 synchronized(this) {
20148 ProcessRecord app = getRecordForAppLocked(target);
20150 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20153 final long origId = Binder.clearCallingIdentity();
20154 finishInstrumentationLocked(app, resultCode, results);
20155 Binder.restoreCallingIdentity(origId);
20159 // =========================================================
20161 // =========================================================
20163 public ConfigurationInfo getDeviceConfigurationInfo() {
20164 ConfigurationInfo config = new ConfigurationInfo();
20165 synchronized (this) {
20166 final Configuration globalConfig = getGlobalConfiguration();
20167 config.reqTouchScreen = globalConfig.touchscreen;
20168 config.reqKeyboardType = globalConfig.keyboard;
20169 config.reqNavigation = globalConfig.navigation;
20170 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20171 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20172 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20174 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20175 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20176 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20178 config.reqGlEsVersion = GL_ES_VERSION;
20183 ActivityStack getFocusedStack() {
20184 return mStackSupervisor.getFocusedStack();
20188 public int getFocusedStackId() throws RemoteException {
20189 ActivityStack focusedStack = getFocusedStack();
20190 if (focusedStack != null) {
20191 return focusedStack.getStackId();
20196 public Configuration getConfiguration() {
20198 synchronized(this) {
20199 ci = new Configuration(getGlobalConfiguration());
20200 ci.userSetLocale = false;
20206 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20207 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20208 synchronized (this) {
20209 mSuppressResizeConfigChanges = suppress;
20214 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20215 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20216 * activity and clearing the task at the same time.
20219 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20220 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20221 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20222 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20224 synchronized (this) {
20225 final long origId = Binder.clearCallingIdentity();
20227 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20229 Binder.restoreCallingIdentity(origId);
20235 public void updatePersistentConfiguration(Configuration values) {
20236 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20237 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20238 if (values == null) {
20239 throw new NullPointerException("Configuration must not be null");
20242 int userId = UserHandle.getCallingUserId();
20244 synchronized(this) {
20245 updatePersistentConfigurationLocked(values, userId);
20249 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20250 final long origId = Binder.clearCallingIdentity();
20252 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20254 Binder.restoreCallingIdentity(origId);
20258 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20259 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20260 FONT_SCALE, 1.0f, userId);
20262 synchronized (this) {
20263 if (getGlobalConfiguration().fontScale == scaleFactor) {
20267 final Configuration configuration
20268 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20269 configuration.fontScale = scaleFactor;
20270 updatePersistentConfigurationLocked(configuration, userId);
20274 private void enforceWriteSettingsPermission(String func) {
20275 int uid = Binder.getCallingUid();
20276 if (uid == ROOT_UID) {
20280 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20281 Settings.getPackageNameForUid(mContext, uid), false)) {
20285 String msg = "Permission Denial: " + func + " from pid="
20286 + Binder.getCallingPid()
20288 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20290 throw new SecurityException(msg);
20294 public boolean updateConfiguration(Configuration values) {
20295 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20297 synchronized(this) {
20298 if (values == null && mWindowManager != null) {
20299 // sentinel: fetch the current configuration from the window manager
20300 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20303 if (mWindowManager != null) {
20304 // Update OOM levels based on display size.
20305 mProcessList.applyDisplaySize(mWindowManager);
20308 final long origId = Binder.clearCallingIdentity();
20310 if (values != null) {
20311 Settings.System.clearConfiguration(values);
20313 updateConfigurationLocked(values, null, false, false /* persistent */,
20314 UserHandle.USER_NULL, false /* deferResume */,
20315 mTmpUpdateConfigurationResult);
20316 return mTmpUpdateConfigurationResult.changes != 0;
20318 Binder.restoreCallingIdentity(origId);
20323 void updateUserConfigurationLocked() {
20324 final Configuration configuration = new Configuration(getGlobalConfiguration());
20325 final int currentUserId = mUserController.getCurrentUserIdLocked();
20326 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20327 currentUserId, Settings.System.canWrite(mContext));
20328 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20329 false /* persistent */, currentUserId, false /* deferResume */);
20332 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20333 boolean initLocale) {
20334 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20337 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20338 boolean initLocale, boolean deferResume) {
20339 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20340 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20341 UserHandle.USER_NULL, deferResume);
20344 // To cache the list of supported system locales
20345 private String[] mSupportedSystemLocales = null;
20347 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20348 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20349 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20350 deferResume, null /* result */);
20354 * Do either or both things: (1) change the current configuration, and (2)
20355 * make sure the given activity is running with the (now) current
20356 * configuration. Returns true if the activity has been left running, or
20357 * false if <var>starting</var> is being destroyed to match the new
20360 * @param userId is only used when persistent parameter is set to true to persist configuration
20361 * for that particular user
20363 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20364 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20365 UpdateConfigurationResult result) {
20367 boolean kept = true;
20369 if (mWindowManager != null) {
20370 mWindowManager.deferSurfaceLayout();
20373 if (values != null) {
20374 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20378 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20380 if (mWindowManager != null) {
20381 mWindowManager.continueSurfaceLayout();
20385 if (result != null) {
20386 result.changes = changes;
20387 result.activityRelaunched = !kept;
20392 /** Update default (global) configuration and notify listeners about changes. */
20393 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20394 boolean persistent, int userId, boolean deferResume) {
20395 mTempConfig.setTo(getGlobalConfiguration());
20396 final int changes = mTempConfig.updateFrom(values);
20397 if (changes == 0) {
20398 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20399 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20400 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20401 // (even if there are no actual changes) to unfreeze the window.
20402 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20406 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20407 "Updating global configuration to: " + values);
20409 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20411 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20412 final LocaleList locales = values.getLocales();
20413 int bestLocaleIndex = 0;
20414 if (locales.size() > 1) {
20415 if (mSupportedSystemLocales == null) {
20416 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20418 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20420 SystemProperties.set("persist.sys.locale",
20421 locales.get(bestLocaleIndex).toLanguageTag());
20422 LocaleList.setDefault(locales, bestLocaleIndex);
20423 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20424 locales.get(bestLocaleIndex)));
20427 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20428 mTempConfig.seq = mConfigurationSeq;
20430 // Update stored global config and notify everyone about the change.
20431 mStackSupervisor.onConfigurationChanged(mTempConfig);
20433 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20434 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20435 mUsageStatsService.reportConfigurationChange(mTempConfig,
20436 mUserController.getCurrentUserIdLocked());
20438 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20439 mShowDialogs = shouldShowDialogs(mTempConfig);
20441 AttributeCache ac = AttributeCache.instance();
20443 ac.updateConfiguration(mTempConfig);
20446 // Make sure all resources in our process are updated right now, so that anyone who is going
20447 // to retrieve resource values after we return will be sure to get the new ones. This is
20448 // especially important during boot, where the first config change needs to guarantee all
20449 // resources have that config before following boot code is executed.
20450 mSystemThread.applyConfigurationToResources(mTempConfig);
20452 // We need another copy of global config because we're scheduling some calls instead of
20453 // running them in place. We need to be sure that object we send will be handled unchanged.
20454 final Configuration configCopy = new Configuration(mTempConfig);
20455 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20456 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20457 msg.obj = configCopy;
20459 mHandler.sendMessage(msg);
20462 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20463 ProcessRecord app = mLruProcesses.get(i);
20465 if (app.thread != null) {
20466 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20467 + app.processName + " new config " + configCopy);
20468 app.thread.scheduleConfigurationChanged(configCopy);
20470 } catch (Exception e) {
20474 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20475 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20476 | Intent.FLAG_RECEIVER_FOREGROUND
20477 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20478 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20479 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20480 UserHandle.USER_ALL);
20481 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20482 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20483 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20484 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20485 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20486 if (initLocale || !mProcessesReady) {
20487 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20489 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20490 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20491 UserHandle.USER_ALL);
20494 // Override configuration of the default display duplicates global config, so we need to
20495 // update it also. This will also notify WindowManager about changes.
20496 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20503 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20504 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20506 synchronized (this) {
20507 // Check if display is initialized in AM.
20508 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20509 // Call might come when display is not yet added or has already been removed.
20510 if (DEBUG_CONFIGURATION) {
20511 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20517 if (values == null && mWindowManager != null) {
20518 // sentinel: fetch the current configuration from the window manager
20519 values = mWindowManager.computeNewConfiguration(displayId);
20522 if (mWindowManager != null) {
20523 // Update OOM levels based on display size.
20524 mProcessList.applyDisplaySize(mWindowManager);
20527 final long origId = Binder.clearCallingIdentity();
20529 if (values != null) {
20530 Settings.System.clearConfiguration(values);
20532 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20533 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20534 return mTmpUpdateConfigurationResult.changes != 0;
20536 Binder.restoreCallingIdentity(origId);
20541 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20542 boolean deferResume, int displayId) {
20543 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20544 displayId, null /* result */);
20548 * Updates override configuration specific for the selected display. If no config is provided,
20549 * new one will be computed in WM based on current display info.
20551 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20552 ActivityRecord starting, boolean deferResume, int displayId,
20553 UpdateConfigurationResult result) {
20555 boolean kept = true;
20557 if (mWindowManager != null) {
20558 mWindowManager.deferSurfaceLayout();
20561 if (values != null) {
20562 if (displayId == DEFAULT_DISPLAY) {
20563 // Override configuration of the default display duplicates global config, so
20564 // we're calling global config update instead for default display. It will also
20565 // apply the correct override config.
20566 changes = updateGlobalConfiguration(values, false /* initLocale */,
20567 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20569 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20573 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20575 if (mWindowManager != null) {
20576 mWindowManager.continueSurfaceLayout();
20580 if (result != null) {
20581 result.changes = changes;
20582 result.activityRelaunched = !kept;
20587 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20589 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20590 final int changes = mTempConfig.updateFrom(values);
20591 if (changes != 0) {
20592 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20593 + mTempConfig + " for displayId=" + displayId);
20594 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20596 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20597 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20598 // Reset the unsupported display size dialog.
20599 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20601 killAllBackgroundProcessesExcept(N,
20602 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20606 // Update the configuration with WM first and check if any of the stacks need to be resized
20607 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20608 // necessary. This way we don't need to relaunch again afterwards in
20609 // ensureActivityConfigurationLocked().
20610 if (mWindowManager != null) {
20611 final int[] resizedStacks =
20612 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20613 if (resizedStacks != null) {
20614 for (int stackId : resizedStacks) {
20615 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20623 /** Applies latest configuration and/or visibility updates if needed. */
20624 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20625 boolean kept = true;
20626 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20627 // mainStack is null during startup.
20628 if (mainStack != null) {
20629 if (changes != 0 && starting == null) {
20630 // If the configuration changed, and the caller is not already
20631 // in the process of starting an activity, then find the top
20632 // activity to check if its configuration needs to change.
20633 starting = mainStack.topRunningActivityLocked();
20636 if (starting != null) {
20637 kept = starting.ensureActivityConfigurationLocked(changes,
20638 false /* preserveWindow */);
20639 // And we need to make sure at this point that all other activities
20640 // are made visible with the correct configuration.
20641 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20642 !PRESERVE_WINDOWS);
20649 /** Helper method that requests bounds from WM and applies them to stack. */
20650 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20651 final Rect newStackBounds = new Rect();
20652 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20653 mStackSupervisor.resizeStackLocked(
20654 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20655 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20656 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20660 * Decide based on the configuration whether we should show the ANR,
20661 * crash, etc dialogs. The idea is that if there is no affordance to
20662 * press the on-screen buttons, or the user experience would be more
20663 * greatly impacted than the crash itself, we shouldn't show the dialog.
20665 * A thought: SystemUI might also want to get told about this, the Power
20666 * dialog / global actions also might want different behaviors.
20668 private static boolean shouldShowDialogs(Configuration config) {
20669 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20670 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20671 && config.navigation == Configuration.NAVIGATION_NONAV);
20672 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20673 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20674 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20675 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20676 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20677 return inputMethodExists && uiModeSupportsDialogs;
20681 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20682 synchronized (this) {
20683 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20684 if (srec != null) {
20685 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20691 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20692 Intent resultData) {
20694 synchronized (this) {
20695 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20697 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20703 public int getLaunchedFromUid(IBinder activityToken) {
20704 ActivityRecord srec;
20705 synchronized (this) {
20706 srec = ActivityRecord.forTokenLocked(activityToken);
20708 if (srec == null) {
20711 return srec.launchedFromUid;
20714 public String getLaunchedFromPackage(IBinder activityToken) {
20715 ActivityRecord srec;
20716 synchronized (this) {
20717 srec = ActivityRecord.forTokenLocked(activityToken);
20719 if (srec == null) {
20722 return srec.launchedFromPackage;
20725 // =========================================================
20726 // LIFETIME MANAGEMENT
20727 // =========================================================
20729 // Returns whether the app is receiving broadcast.
20730 // If receiving, fetch all broadcast queues which the app is
20731 // the current [or imminent] receiver on.
20732 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20733 ArraySet<BroadcastQueue> receivingQueues) {
20734 if (!app.curReceivers.isEmpty()) {
20735 for (BroadcastRecord r : app.curReceivers) {
20736 receivingQueues.add(r.queue);
20741 // It's not the current receiver, but it might be starting up to become one
20742 for (BroadcastQueue queue : mBroadcastQueues) {
20743 final BroadcastRecord r = queue.mPendingBroadcast;
20744 if (r != null && r.curApp == app) {
20745 // found it; report which queue it's in
20746 receivingQueues.add(queue);
20750 return !receivingQueues.isEmpty();
20753 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20754 int targetUid, ComponentName targetComponent, String targetProcess) {
20755 if (!mTrackingAssociations) {
20758 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20759 = mAssociations.get(targetUid);
20760 if (components == null) {
20761 components = new ArrayMap<>();
20762 mAssociations.put(targetUid, components);
20764 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20765 if (sourceUids == null) {
20766 sourceUids = new SparseArray<>();
20767 components.put(targetComponent, sourceUids);
20769 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20770 if (sourceProcesses == null) {
20771 sourceProcesses = new ArrayMap<>();
20772 sourceUids.put(sourceUid, sourceProcesses);
20774 Association ass = sourceProcesses.get(sourceProcess);
20776 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20778 sourceProcesses.put(sourceProcess, ass);
20782 if (ass.mNesting == 1) {
20783 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20784 ass.mLastState = sourceState;
20789 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20790 ComponentName targetComponent) {
20791 if (!mTrackingAssociations) {
20794 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20795 = mAssociations.get(targetUid);
20796 if (components == null) {
20799 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20800 if (sourceUids == null) {
20803 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20804 if (sourceProcesses == null) {
20807 Association ass = sourceProcesses.get(sourceProcess);
20808 if (ass == null || ass.mNesting <= 0) {
20812 if (ass.mNesting == 0) {
20813 long uptime = SystemClock.uptimeMillis();
20814 ass.mTime += uptime - ass.mStartTime;
20815 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20816 += uptime - ass.mLastStateUptime;
20817 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20821 private void noteUidProcessState(final int uid, final int state) {
20822 mBatteryStatsService.noteUidProcessState(uid, state);
20823 if (mTrackingAssociations) {
20824 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20825 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20826 = mAssociations.valueAt(i1);
20827 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20828 SparseArray<ArrayMap<String, Association>> sourceUids
20829 = targetComponents.valueAt(i2);
20830 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20831 if (sourceProcesses != null) {
20832 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20833 Association ass = sourceProcesses.valueAt(i4);
20834 if (ass.mNesting >= 1) {
20835 // currently associated
20836 long uptime = SystemClock.uptimeMillis();
20837 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20838 += uptime - ass.mLastStateUptime;
20839 ass.mLastState = state;
20840 ass.mLastStateUptime = uptime;
20849 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20850 boolean doingAll, long now) {
20851 if (mAdjSeq == app.adjSeq) {
20852 // This adjustment has already been computed.
20853 return app.curRawAdj;
20856 if (app.thread == null) {
20857 app.adjSeq = mAdjSeq;
20858 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20859 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20860 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20863 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20864 app.adjSource = null;
20865 app.adjTarget = null;
20867 app.cached = false;
20869 final int activitiesSize = app.activities.size();
20871 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20872 // The max adjustment doesn't allow this app to be anything
20873 // below foreground, so it is not worth doing work for it.
20874 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20875 app.adjType = "fixed";
20876 app.adjSeq = mAdjSeq;
20877 app.curRawAdj = app.maxAdj;
20878 app.foregroundActivities = false;
20879 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20880 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20881 // System processes can do UI, and when they do we want to have
20882 // them trim their memory after the user leaves the UI. To
20883 // facilitate this, here we need to determine whether or not it
20884 // is currently showing UI.
20885 app.systemNoUi = true;
20886 if (app == TOP_APP) {
20887 app.systemNoUi = false;
20888 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20889 app.adjType = "pers-top-activity";
20890 } else if (app.hasTopUi) {
20891 app.systemNoUi = false;
20892 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20893 app.adjType = "pers-top-ui";
20894 } else if (activitiesSize > 0) {
20895 for (int j = 0; j < activitiesSize; j++) {
20896 final ActivityRecord r = app.activities.get(j);
20898 app.systemNoUi = false;
20902 if (!app.systemNoUi) {
20903 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20905 return (app.curAdj=app.maxAdj);
20908 app.systemNoUi = false;
20910 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20912 // Determine the importance of the process, starting with most
20913 // important to least, and assign an appropriate OOM adjustment.
20917 boolean foregroundActivities = false;
20918 mTmpBroadcastQueue.clear();
20919 if (app == TOP_APP) {
20920 // The last app on the list is the foreground app.
20921 adj = ProcessList.FOREGROUND_APP_ADJ;
20922 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20923 app.adjType = "top-activity";
20924 foregroundActivities = true;
20925 procState = PROCESS_STATE_CUR_TOP;
20926 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20927 } else if (app.instr != null) {
20928 // Don't want to kill running instrumentation.
20929 adj = ProcessList.FOREGROUND_APP_ADJ;
20930 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20931 app.adjType = "instrumentation";
20932 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20933 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20934 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20935 // An app that is currently receiving a broadcast also
20936 // counts as being in the foreground for OOM killer purposes.
20937 // It's placed in a sched group based on the nature of the
20938 // broadcast as reflected by which queue it's active in.
20939 adj = ProcessList.FOREGROUND_APP_ADJ;
20940 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20941 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20942 app.adjType = "broadcast";
20943 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20944 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20945 } else if (app.executingServices.size() > 0) {
20946 // An app that is currently executing a service callback also
20947 // counts as being in the foreground.
20948 adj = ProcessList.FOREGROUND_APP_ADJ;
20949 schedGroup = app.execServicesFg ?
20950 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20951 app.adjType = "exec-service";
20952 procState = ActivityManager.PROCESS_STATE_SERVICE;
20953 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20954 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20956 // As far as we know the process is empty. We may change our mind later.
20957 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20958 // At this point we don't actually know the adjustment. Use the cached adj
20959 // value that the caller wants us to.
20961 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20964 app.adjType = "cch-empty";
20965 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20968 // Examine all activities if not already foreground.
20969 if (!foregroundActivities && activitiesSize > 0) {
20970 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20971 for (int j = 0; j < activitiesSize; j++) {
20972 final ActivityRecord r = app.activities.get(j);
20973 if (r.app != app) {
20974 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20975 + " instead of expected " + app);
20976 if (r.app == null || (r.app.uid == app.uid)) {
20977 // Only fix things up when they look sane
20984 // App has a visible activity; only upgrade adjustment.
20985 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20986 adj = ProcessList.VISIBLE_APP_ADJ;
20987 app.adjType = "vis-activity";
20988 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20990 if (procState > PROCESS_STATE_CUR_TOP) {
20991 procState = PROCESS_STATE_CUR_TOP;
20992 app.adjType = "vis-activity";
20993 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20995 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20996 app.cached = false;
20998 foregroundActivities = true;
20999 final TaskRecord task = r.getTask();
21000 if (task != null && minLayer > 0) {
21001 final int layer = task.mLayerRank;
21002 if (layer >= 0 && minLayer > layer) {
21007 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21008 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21009 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21010 app.adjType = "pause-activity";
21011 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21013 if (procState > PROCESS_STATE_CUR_TOP) {
21014 procState = PROCESS_STATE_CUR_TOP;
21015 app.adjType = "pause-activity";
21016 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21018 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21019 app.cached = false;
21021 foregroundActivities = true;
21022 } else if (r.state == ActivityState.STOPPING) {
21023 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21024 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21025 app.adjType = "stop-activity";
21026 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21028 // For the process state, we will at this point consider the
21029 // process to be cached. It will be cached either as an activity
21030 // or empty depending on whether the activity is finishing. We do
21031 // this so that we can treat the process as cached for purposes of
21032 // memory trimming (determing current memory level, trim command to
21033 // send to process) since there can be an arbitrary number of stopping
21034 // processes and they should soon all go into the cached state.
21035 if (!r.finishing) {
21036 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21037 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21038 app.adjType = "stop-activity";
21039 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21042 app.cached = false;
21044 foregroundActivities = true;
21046 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21047 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21048 app.adjType = "cch-act";
21049 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21053 if (adj == ProcessList.VISIBLE_APP_ADJ) {
21058 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21059 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21060 if (app.foregroundServices) {
21061 // The user is aware of this app, so make it visible.
21062 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21063 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21064 app.cached = false;
21065 app.adjType = "fg-service";
21066 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21067 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21068 } else if (app.hasOverlayUi) {
21069 // The process is display an overlay UI.
21070 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21071 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21072 app.cached = false;
21073 app.adjType = "has-overlay-ui";
21074 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21075 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21079 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21080 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21081 if (app.forcingToImportant != null) {
21082 // This is currently used for toasts... they are not interactive, and
21083 // we don't want them to cause the app to become fully foreground (and
21084 // thus out of background check), so we yes the best background level we can.
21085 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21086 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21087 app.cached = false;
21088 app.adjType = "force-imp";
21089 app.adjSource = app.forcingToImportant;
21090 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21091 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21095 if (app == mHeavyWeightProcess) {
21096 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21097 // We don't want to kill the current heavy-weight process.
21098 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21099 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21100 app.cached = false;
21101 app.adjType = "heavy";
21102 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21104 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21105 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21106 app.adjType = "heavy";
21107 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21111 if (app == mHomeProcess) {
21112 if (adj > ProcessList.HOME_APP_ADJ) {
21113 // This process is hosting what we currently consider to be the
21114 // home app, so we don't want to let it go into the background.
21115 adj = ProcessList.HOME_APP_ADJ;
21116 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21117 app.cached = false;
21118 app.adjType = "home";
21119 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21121 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21122 procState = ActivityManager.PROCESS_STATE_HOME;
21123 app.adjType = "home";
21124 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21128 if (app == mPreviousProcess && app.activities.size() > 0) {
21129 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21130 // This was the previous process that showed UI to the user.
21131 // We want to try to keep it around more aggressively, to give
21132 // a good experience around switching between two apps.
21133 adj = ProcessList.PREVIOUS_APP_ADJ;
21134 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21135 app.cached = false;
21136 app.adjType = "previous";
21137 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21139 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21140 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21141 app.adjType = "previous";
21142 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21146 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21147 + " reason=" + app.adjType);
21149 // By default, we use the computed adjustment. It may be changed if
21150 // there are applications dependent on our services or providers, but
21151 // this gives us a baseline and makes sure we don't get into an
21152 // infinite recursion.
21153 app.adjSeq = mAdjSeq;
21154 app.curRawAdj = adj;
21155 app.hasStartedServices = false;
21157 if (mBackupTarget != null && app == mBackupTarget.app) {
21158 // If possible we want to avoid killing apps while they're being backed up
21159 if (adj > ProcessList.BACKUP_APP_ADJ) {
21160 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21161 adj = ProcessList.BACKUP_APP_ADJ;
21162 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21163 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21165 app.adjType = "backup";
21166 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21167 app.cached = false;
21169 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21170 procState = ActivityManager.PROCESS_STATE_BACKUP;
21171 app.adjType = "backup";
21172 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21176 boolean mayBeTop = false;
21177 String mayBeTopType = null;
21178 Object mayBeTopSource = null;
21179 Object mayBeTopTarget = null;
21181 for (int is = app.services.size()-1;
21182 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21183 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21184 || procState > ActivityManager.PROCESS_STATE_TOP);
21186 ServiceRecord s = app.services.valueAt(is);
21187 if (s.startRequested) {
21188 app.hasStartedServices = true;
21189 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21190 procState = ActivityManager.PROCESS_STATE_SERVICE;
21191 app.adjType = "started-services";
21192 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21194 if (app.hasShownUi && app != mHomeProcess) {
21195 // If this process has shown some UI, let it immediately
21196 // go to the LRU list because it may be pretty heavy with
21197 // UI stuff. We'll tag it with a label just to help
21198 // debug and understand what is going on.
21199 if (adj > ProcessList.SERVICE_ADJ) {
21200 app.adjType = "cch-started-ui-services";
21203 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21204 // This service has seen some activity within
21205 // recent memory, so we will keep its process ahead
21206 // of the background processes.
21207 if (adj > ProcessList.SERVICE_ADJ) {
21208 adj = ProcessList.SERVICE_ADJ;
21209 app.adjType = "started-services";
21210 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21211 app.cached = false;
21214 // If we have let the service slide into the background
21215 // state, still have some text describing what it is doing
21216 // even though the service no longer has an impact.
21217 if (adj > ProcessList.SERVICE_ADJ) {
21218 app.adjType = "cch-started-services";
21223 for (int conni = s.connections.size()-1;
21224 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21225 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21226 || procState > ActivityManager.PROCESS_STATE_TOP);
21228 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21230 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21231 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21232 || procState > ActivityManager.PROCESS_STATE_TOP);
21234 // XXX should compute this based on the max of
21235 // all connected clients.
21236 ConnectionRecord cr = clist.get(i);
21237 if (cr.binding.client == app) {
21238 // Binding to ourself is not interesting.
21242 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21243 ProcessRecord client = cr.binding.client;
21244 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21245 TOP_APP, doingAll, now);
21246 int clientProcState = client.curProcState;
21247 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21248 // If the other app is cached for any reason, for purposes here
21249 // we are going to consider it empty. The specific cached state
21250 // doesn't propagate except under certain conditions.
21251 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21253 String adjType = null;
21254 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21255 // Not doing bind OOM management, so treat
21256 // this guy more like a started service.
21257 if (app.hasShownUi && app != mHomeProcess) {
21258 // If this process has shown some UI, let it immediately
21259 // go to the LRU list because it may be pretty heavy with
21260 // UI stuff. We'll tag it with a label just to help
21261 // debug and understand what is going on.
21262 if (adj > clientAdj) {
21263 adjType = "cch-bound-ui-services";
21265 app.cached = false;
21267 clientProcState = procState;
21269 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21270 // This service has not seen activity within
21271 // recent memory, so allow it to drop to the
21272 // LRU list if there is no other reason to keep
21273 // it around. We'll also tag it with a label just
21274 // to help debug and undertand what is going on.
21275 if (adj > clientAdj) {
21276 adjType = "cch-bound-services";
21282 if (adj > clientAdj) {
21283 // If this process has recently shown UI, and
21284 // the process that is binding to it is less
21285 // important than being visible, then we don't
21286 // care about the binding as much as we care
21287 // about letting this process get into the LRU
21288 // list to be killed and restarted if needed for
21290 if (app.hasShownUi && app != mHomeProcess
21291 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21292 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21293 adjType = "cch-bound-ui-services";
21297 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21298 |Context.BIND_IMPORTANT)) != 0) {
21299 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21300 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21301 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21302 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21303 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21304 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21305 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21306 newAdj = clientAdj;
21308 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21309 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21314 if (!client.cached) {
21315 app.cached = false;
21317 if (adj > newAdj) {
21319 adjType = "service";
21323 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21324 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21325 // This will treat important bound services identically to
21326 // the top app, which may behave differently than generic
21327 // foreground work.
21328 if (client.curSchedGroup > schedGroup) {
21329 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21330 schedGroup = client.curSchedGroup;
21332 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21335 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21336 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21337 // Special handling of clients who are in the top state.
21338 // We *may* want to consider this process to be in the
21339 // top state as well, but only if there is not another
21340 // reason for it to be running. Being on the top is a
21341 // special state, meaning you are specifically running
21342 // for the current top app. If the process is already
21343 // running in the background for some other reason, it
21344 // is more important to continue considering it to be
21345 // in the background state.
21347 mayBeTopType = "service";
21348 mayBeTopSource = cr.binding.client;
21349 mayBeTopTarget = s.name;
21350 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21352 // Special handling for above-top states (persistent
21353 // processes). These should not bring the current process
21354 // into the top state, since they are not on top. Instead
21355 // give them the best state after that.
21356 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21358 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21359 } else if (mWakefulness
21360 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21361 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21364 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21367 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21371 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21372 if (clientProcState <
21373 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21375 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21378 if (clientProcState <
21379 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21381 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21384 if (procState > clientProcState) {
21385 procState = clientProcState;
21386 if (adjType == null) {
21387 adjType = "service";
21390 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21391 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21392 app.pendingUiClean = true;
21394 if (adjType != null) {
21395 app.adjType = adjType;
21396 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21397 .REASON_SERVICE_IN_USE;
21398 app.adjSource = cr.binding.client;
21399 app.adjSourceProcState = clientProcState;
21400 app.adjTarget = s.name;
21401 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21402 + ": " + app + ", due to " + cr.binding.client
21403 + " adj=" + adj + " procState=" + procState);
21406 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21407 app.treatLikeActivity = true;
21409 final ActivityRecord a = cr.activity;
21410 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21411 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21412 (a.visible || a.state == ActivityState.RESUMED ||
21413 a.state == ActivityState.PAUSING)) {
21414 adj = ProcessList.FOREGROUND_APP_ADJ;
21415 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21416 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21417 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21419 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21422 app.cached = false;
21423 app.adjType = "service";
21424 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21425 .REASON_SERVICE_IN_USE;
21427 app.adjSourceProcState = procState;
21428 app.adjTarget = s.name;
21429 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21437 for (int provi = app.pubProviders.size()-1;
21438 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21439 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21440 || procState > ActivityManager.PROCESS_STATE_TOP);
21442 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21443 for (int i = cpr.connections.size()-1;
21444 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21445 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21446 || procState > ActivityManager.PROCESS_STATE_TOP);
21448 ContentProviderConnection conn = cpr.connections.get(i);
21449 ProcessRecord client = conn.client;
21450 if (client == app) {
21451 // Being our own client is not interesting.
21454 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21455 int clientProcState = client.curProcState;
21456 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21457 // If the other app is cached for any reason, for purposes here
21458 // we are going to consider it empty.
21459 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21461 String adjType = null;
21462 if (adj > clientAdj) {
21463 if (app.hasShownUi && app != mHomeProcess
21464 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21465 adjType = "cch-ui-provider";
21467 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21468 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21469 adjType = "provider";
21471 app.cached &= client.cached;
21473 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21474 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21475 // Special handling of clients who are in the top state.
21476 // We *may* want to consider this process to be in the
21477 // top state as well, but only if there is not another
21478 // reason for it to be running. Being on the top is a
21479 // special state, meaning you are specifically running
21480 // for the current top app. If the process is already
21481 // running in the background for some other reason, it
21482 // is more important to continue considering it to be
21483 // in the background state.
21485 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21486 mayBeTopType = adjType = "provider-top";
21487 mayBeTopSource = client;
21488 mayBeTopTarget = cpr.name;
21490 // Special handling for above-top states (persistent
21491 // processes). These should not bring the current process
21492 // into the top state, since they are not on top. Instead
21493 // give them the best state after that.
21495 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21496 if (adjType == null) {
21497 adjType = "provider";
21501 if (procState > clientProcState) {
21502 procState = clientProcState;
21504 if (client.curSchedGroup > schedGroup) {
21505 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21507 if (adjType != null) {
21508 app.adjType = adjType;
21509 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21510 .REASON_PROVIDER_IN_USE;
21511 app.adjSource = client;
21512 app.adjSourceProcState = clientProcState;
21513 app.adjTarget = cpr.name;
21514 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21515 + ": " + app + ", due to " + client
21516 + " adj=" + adj + " procState=" + procState);
21519 // If the provider has external (non-framework) process
21520 // dependencies, ensure that its adjustment is at least
21521 // FOREGROUND_APP_ADJ.
21522 if (cpr.hasExternalProcessHandles()) {
21523 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21524 adj = ProcessList.FOREGROUND_APP_ADJ;
21525 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21526 app.cached = false;
21527 app.adjType = "ext-provider";
21528 app.adjTarget = cpr.name;
21529 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21531 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21532 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21537 if (app.lastProviderTime > 0 &&
21538 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21539 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21540 adj = ProcessList.PREVIOUS_APP_ADJ;
21541 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21542 app.cached = false;
21543 app.adjType = "recent-provider";
21544 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21546 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21547 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21548 app.adjType = "recent-provider";
21549 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21553 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21554 // A client of one of our services or providers is in the top state. We
21555 // *may* want to be in the top state, but not if we are already running in
21556 // the background for some other reason. For the decision here, we are going
21557 // to pick out a few specific states that we want to remain in when a client
21558 // is top (states that tend to be longer-term) and otherwise allow it to go
21559 // to the top state.
21560 switch (procState) {
21561 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21562 // Something else is keeping it at this level, just leave it.
21564 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21565 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21566 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21567 case ActivityManager.PROCESS_STATE_SERVICE:
21568 // These all are longer-term states, so pull them up to the top
21569 // of the background states, but not all the way to the top state.
21570 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21571 app.adjType = mayBeTopType;
21572 app.adjSource = mayBeTopSource;
21573 app.adjTarget = mayBeTopTarget;
21574 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21575 + ": " + app + ", due to " + mayBeTopSource
21576 + " adj=" + adj + " procState=" + procState);
21579 // Otherwise, top is a better choice, so take it.
21580 procState = ActivityManager.PROCESS_STATE_TOP;
21581 app.adjType = mayBeTopType;
21582 app.adjSource = mayBeTopSource;
21583 app.adjTarget = mayBeTopTarget;
21584 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21585 + ": " + app + ", due to " + mayBeTopSource
21586 + " adj=" + adj + " procState=" + procState);
21591 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21592 if (app.hasClientActivities) {
21593 // This is a cached process, but with client activities. Mark it so.
21594 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21595 app.adjType = "cch-client-act";
21596 } else if (app.treatLikeActivity) {
21597 // This is a cached process, but somebody wants us to treat it like it has
21598 // an activity, okay!
21599 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21600 app.adjType = "cch-as-act";
21604 if (adj == ProcessList.SERVICE_ADJ) {
21606 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21607 mNewNumServiceProcs++;
21608 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21609 if (!app.serviceb) {
21610 // This service isn't far enough down on the LRU list to
21611 // normally be a B service, but if we are low on RAM and it
21612 // is large we want to force it down since we would prefer to
21613 // keep launcher over it.
21614 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21615 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21616 app.serviceHighRam = true;
21617 app.serviceb = true;
21618 //Slog.i(TAG, "ADJ " + app + " high ram!");
21620 mNewNumAServiceProcs++;
21621 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21624 app.serviceHighRam = false;
21627 if (app.serviceb) {
21628 adj = ProcessList.SERVICE_B_ADJ;
21632 app.curRawAdj = adj;
21634 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21635 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21636 if (adj > app.maxAdj) {
21638 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21639 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21643 // Do final modification to adj. Everything we do between here and applying
21644 // the final setAdj must be done in this function, because we will also use
21645 // it when computing the final cached adj later. Note that we don't need to
21646 // worry about this for max adj above, since max adj will always be used to
21647 // keep it out of the cached vaues.
21648 app.curAdj = app.modifyRawOomAdj(adj);
21649 app.curSchedGroup = schedGroup;
21650 app.curProcState = procState;
21651 app.foregroundActivities = foregroundActivities;
21653 return app.curRawAdj;
21657 * Record new PSS sample for a process.
21659 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21661 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21663 proc.lastPssTime = now;
21664 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21665 if (DEBUG_PSS) Slog.d(TAG_PSS,
21666 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21667 + " state=" + ProcessList.makeProcStateString(procState));
21668 if (proc.initialIdlePss == 0) {
21669 proc.initialIdlePss = pss;
21671 proc.lastPss = pss;
21672 proc.lastSwapPss = swapPss;
21673 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21674 proc.lastCachedPss = pss;
21675 proc.lastCachedSwapPss = swapPss;
21678 final SparseArray<Pair<Long, String>> watchUids
21679 = mMemWatchProcesses.getMap().get(proc.processName);
21681 if (watchUids != null) {
21682 Pair<Long, String> val = watchUids.get(proc.uid);
21684 val = watchUids.get(0);
21690 if (check != null) {
21691 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21692 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21693 if (!isDebuggable) {
21694 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21695 isDebuggable = true;
21698 if (isDebuggable) {
21699 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21700 final ProcessRecord myProc = proc;
21701 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21702 mMemWatchDumpProcName = proc.processName;
21703 mMemWatchDumpFile = heapdumpFile.toString();
21704 mMemWatchDumpPid = proc.pid;
21705 mMemWatchDumpUid = proc.uid;
21706 BackgroundThread.getHandler().post(new Runnable() {
21708 public void run() {
21709 revokeUriPermission(ActivityThread.currentActivityThread()
21710 .getApplicationThread(),
21711 null, DumpHeapActivity.JAVA_URI,
21712 Intent.FLAG_GRANT_READ_URI_PERMISSION
21713 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21714 UserHandle.myUserId());
21715 ParcelFileDescriptor fd = null;
21717 heapdumpFile.delete();
21718 fd = ParcelFileDescriptor.open(heapdumpFile,
21719 ParcelFileDescriptor.MODE_CREATE |
21720 ParcelFileDescriptor.MODE_TRUNCATE |
21721 ParcelFileDescriptor.MODE_WRITE_ONLY |
21722 ParcelFileDescriptor.MODE_APPEND);
21723 IApplicationThread thread = myProc.thread;
21724 if (thread != null) {
21726 if (DEBUG_PSS) Slog.d(TAG_PSS,
21727 "Requesting dump heap from "
21728 + myProc + " to " + heapdumpFile);
21729 thread.dumpHeap(/* managed= */ true,
21730 /* mallocInfo= */ false, /* runGc= */ false,
21731 heapdumpFile.toString(), fd);
21732 } catch (RemoteException e) {
21735 } catch (FileNotFoundException e) {
21736 e.printStackTrace();
21741 } catch (IOException e) {
21748 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21749 + ", but debugging not enabled");
21756 * Schedule PSS collection of a process.
21758 void requestPssLocked(ProcessRecord proc, int procState) {
21759 if (mPendingPssProcesses.contains(proc)) {
21762 if (mPendingPssProcesses.size() == 0) {
21763 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21765 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21766 proc.pssProcState = procState;
21767 mPendingPssProcesses.add(proc);
21771 * Schedule PSS collection of all processes.
21773 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21775 if (now < (mLastFullPssTime +
21776 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21777 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21781 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21782 mLastFullPssTime = now;
21783 mFullPssPending = true;
21784 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21785 mPendingPssProcesses.clear();
21786 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21787 ProcessRecord app = mLruProcesses.get(i);
21788 if (app.thread == null
21789 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21792 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21793 app.pssProcState = app.setProcState;
21794 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21795 mTestPssMode, isSleepingLocked(), now);
21796 mPendingPssProcesses.add(app);
21799 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21802 public void setTestPssMode(boolean enabled) {
21803 synchronized (this) {
21804 mTestPssMode = enabled;
21806 // Whenever we enable the mode, we want to take a snapshot all of current
21807 // process mem use.
21808 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21814 * Ask a given process to GC right now.
21816 final void performAppGcLocked(ProcessRecord app) {
21818 app.lastRequestedGc = SystemClock.uptimeMillis();
21819 if (app.thread != null) {
21820 if (app.reportLowMemory) {
21821 app.reportLowMemory = false;
21822 app.thread.scheduleLowMemory();
21824 app.thread.processInBackground();
21827 } catch (Exception e) {
21833 * Returns true if things are idle enough to perform GCs.
21835 private final boolean canGcNowLocked() {
21836 boolean processingBroadcasts = false;
21837 for (BroadcastQueue q : mBroadcastQueues) {
21838 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21839 processingBroadcasts = true;
21842 return !processingBroadcasts
21843 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21847 * Perform GCs on all processes that are waiting for it, but only
21848 * if things are idle.
21850 final void performAppGcsLocked() {
21851 final int N = mProcessesToGc.size();
21855 if (canGcNowLocked()) {
21856 while (mProcessesToGc.size() > 0) {
21857 ProcessRecord proc = mProcessesToGc.remove(0);
21858 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21859 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21860 <= SystemClock.uptimeMillis()) {
21861 // To avoid spamming the system, we will GC processes one
21862 // at a time, waiting a few seconds between each.
21863 performAppGcLocked(proc);
21864 scheduleAppGcsLocked();
21867 // It hasn't been long enough since we last GCed this
21868 // process... put it in the list to wait for its time.
21869 addProcessToGcListLocked(proc);
21875 scheduleAppGcsLocked();
21880 * If all looks good, perform GCs on all processes waiting for them.
21882 final void performAppGcsIfAppropriateLocked() {
21883 if (canGcNowLocked()) {
21884 performAppGcsLocked();
21887 // Still not idle, wait some more.
21888 scheduleAppGcsLocked();
21892 * Schedule the execution of all pending app GCs.
21894 final void scheduleAppGcsLocked() {
21895 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21897 if (mProcessesToGc.size() > 0) {
21898 // Schedule a GC for the time to the next process.
21899 ProcessRecord proc = mProcessesToGc.get(0);
21900 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21902 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21903 long now = SystemClock.uptimeMillis();
21904 if (when < (now+mConstants.GC_TIMEOUT)) {
21905 when = now + mConstants.GC_TIMEOUT;
21907 mHandler.sendMessageAtTime(msg, when);
21912 * Add a process to the array of processes waiting to be GCed. Keeps the
21913 * list in sorted order by the last GC time. The process can't already be
21916 final void addProcessToGcListLocked(ProcessRecord proc) {
21917 boolean added = false;
21918 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21919 if (mProcessesToGc.get(i).lastRequestedGc <
21920 proc.lastRequestedGc) {
21922 mProcessesToGc.add(i+1, proc);
21927 mProcessesToGc.add(0, proc);
21932 * Set up to ask a process to GC itself. This will either do it
21933 * immediately, or put it on the list of processes to gc the next
21934 * time things are idle.
21936 final void scheduleAppGcLocked(ProcessRecord app) {
21937 long now = SystemClock.uptimeMillis();
21938 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21941 if (!mProcessesToGc.contains(app)) {
21942 addProcessToGcListLocked(app);
21943 scheduleAppGcsLocked();
21947 final void checkExcessivePowerUsageLocked() {
21948 updateCpuStatsNow();
21950 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21951 boolean doCpuKills = true;
21952 if (mLastPowerCheckUptime == 0) {
21953 doCpuKills = false;
21955 final long curUptime = SystemClock.uptimeMillis();
21956 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21957 mLastPowerCheckUptime = curUptime;
21958 int i = mLruProcesses.size();
21961 ProcessRecord app = mLruProcesses.get(i);
21962 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21963 if (app.lastCpuTime <= 0) {
21966 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21968 StringBuilder sb = new StringBuilder(128);
21969 sb.append("CPU for ");
21970 app.toShortString(sb);
21971 sb.append(": over ");
21972 TimeUtils.formatDuration(uptimeSince, sb);
21973 sb.append(" used ");
21974 TimeUtils.formatDuration(cputimeUsed, sb);
21976 sb.append((cputimeUsed*100)/uptimeSince);
21978 Slog.i(TAG_POWER, sb.toString());
21980 // If the process has used too much CPU over the last duration, the
21981 // user probably doesn't want this, so kill!
21982 if (doCpuKills && uptimeSince > 0) {
21983 // What is the limit for this process?
21985 long checkDur = curUptime - app.whenUnimportant;
21986 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21987 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21988 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21989 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21990 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21991 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21992 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21994 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21996 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21997 synchronized (stats) {
21998 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21999 uptimeSince, cputimeUsed);
22001 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
22002 + " dur=" + checkDur + " limit=" + cpuLimit, true);
22003 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22006 app.lastCpuTime = app.curCpuTime;
22011 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22013 boolean success = true;
22015 if (app.curRawAdj != app.setRawAdj) {
22016 app.setRawAdj = app.curRawAdj;
22021 if (app.curAdj != app.setAdj) {
22022 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22023 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22024 String msg = "Set " + app.pid + " " + app.processName + " adj "
22025 + app.curAdj + ": " + app.adjType;
22026 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22028 app.setAdj = app.curAdj;
22029 app.verifiedAdj = ProcessList.INVALID_ADJ;
22032 if (app.setSchedGroup != app.curSchedGroup) {
22033 int oldSchedGroup = app.setSchedGroup;
22034 app.setSchedGroup = app.curSchedGroup;
22035 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22036 String msg = "Setting sched group of " + app.processName
22037 + " to " + app.curSchedGroup;
22038 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22040 if (app.waitingToKill != null && app.curReceivers.isEmpty()
22041 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22042 app.kill(app.waitingToKill, true);
22046 switch (app.curSchedGroup) {
22047 case ProcessList.SCHED_GROUP_BACKGROUND:
22048 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22050 case ProcessList.SCHED_GROUP_TOP_APP:
22051 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22052 processGroup = THREAD_GROUP_TOP_APP;
22055 processGroup = THREAD_GROUP_DEFAULT;
22058 long oldId = Binder.clearCallingIdentity();
22060 setProcessGroup(app.pid, processGroup);
22061 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22062 // do nothing if we already switched to RT
22063 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22064 mVrController.onTopProcChangedLocked(app);
22065 if (mUseFifoUiScheduling) {
22066 // Switch UI pipeline for app to SCHED_FIFO
22067 app.savedPriority = Process.getThreadPriority(app.pid);
22068 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22069 if (app.renderThreadTid != 0) {
22070 scheduleAsFifoPriority(app.renderThreadTid,
22071 /* suppressLogs */true);
22072 if (DEBUG_OOM_ADJ) {
22073 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22074 app.renderThreadTid + ") to FIFO");
22077 if (DEBUG_OOM_ADJ) {
22078 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22082 // Boost priority for top app UI and render threads
22083 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22084 if (app.renderThreadTid != 0) {
22086 setThreadPriority(app.renderThreadTid,
22087 TOP_APP_PRIORITY_BOOST);
22088 } catch (IllegalArgumentException e) {
22089 // thread died, ignore
22094 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22095 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22096 mVrController.onTopProcChangedLocked(app);
22097 if (mUseFifoUiScheduling) {
22099 // Reset UI pipeline to SCHED_OTHER
22100 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22101 setThreadPriority(app.pid, app.savedPriority);
22102 if (app.renderThreadTid != 0) {
22103 setThreadScheduler(app.renderThreadTid,
22105 setThreadPriority(app.renderThreadTid, -4);
22107 } catch (IllegalArgumentException e) {
22109 "Failed to set scheduling policy, thread does not exist:\n"
22111 } catch (SecurityException e) {
22112 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22115 // Reset priority for top app UI and render threads
22116 setThreadPriority(app.pid, 0);
22117 if (app.renderThreadTid != 0) {
22118 setThreadPriority(app.renderThreadTid, 0);
22122 } catch (Exception e) {
22124 Slog.w(TAG, "Failed setting process group of " + app.pid
22125 + " to " + app.curSchedGroup);
22126 Slog.w(TAG, "at location", e);
22129 Binder.restoreCallingIdentity(oldId);
22133 if (app.repForegroundActivities != app.foregroundActivities) {
22134 app.repForegroundActivities = app.foregroundActivities;
22135 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22137 if (app.repProcState != app.curProcState) {
22138 app.repProcState = app.curProcState;
22139 if (app.thread != null) {
22142 //RuntimeException h = new RuntimeException("here");
22143 Slog.i(TAG, "Sending new process state " + app.repProcState
22144 + " to " + app /*, h*/);
22146 app.thread.setProcessState(app.repProcState);
22147 } catch (RemoteException e) {
22151 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22152 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22153 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22154 // Experimental code to more aggressively collect pss while
22155 // running test... the problem is that this tends to collect
22156 // the data right when a process is transitioning between process
22157 // states, which well tend to give noisy data.
22158 long start = SystemClock.uptimeMillis();
22159 long pss = Debug.getPss(app.pid, mTmpLong, null);
22160 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22161 mPendingPssProcesses.remove(app);
22162 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22163 + " to " + app.curProcState + ": "
22164 + (SystemClock.uptimeMillis()-start) + "ms");
22166 app.lastStateTime = now;
22167 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22168 mTestPssMode, isSleepingLocked(), now);
22169 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22170 + ProcessList.makeProcStateString(app.setProcState) + " to "
22171 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22172 + (app.nextPssTime-now) + ": " + app);
22174 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22175 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22177 requestPssLocked(app, app.setProcState);
22178 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22179 mTestPssMode, isSleepingLocked(), now);
22180 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22181 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22183 if (app.setProcState != app.curProcState) {
22184 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22185 String msg = "Proc state change of " + app.processName
22186 + " to " + app.curProcState;
22187 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22189 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22190 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22191 if (setImportant && !curImportant) {
22192 // This app is no longer something we consider important enough to allow to
22193 // use arbitrary amounts of battery power. Note
22194 // its current CPU time to later know to kill it if
22195 // it is not behaving well.
22196 app.whenUnimportant = now;
22197 app.lastCpuTime = 0;
22199 // Inform UsageStats of important process state change
22200 // Must be called before updating setProcState
22201 maybeUpdateUsageStatsLocked(app, nowElapsed);
22203 app.setProcState = app.curProcState;
22204 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22205 app.notCachedSinceIdle = false;
22208 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22210 app.procStateChanged = true;
22212 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22213 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22214 // For apps that sit around for a long time in the interactive state, we need
22215 // to report this at least once a day so they don't go idle.
22216 maybeUpdateUsageStatsLocked(app, nowElapsed);
22219 if (changes != 0) {
22220 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22221 "Changes in " + app + ": " + changes);
22222 int i = mPendingProcessChanges.size()-1;
22223 ProcessChangeItem item = null;
22225 item = mPendingProcessChanges.get(i);
22226 if (item.pid == app.pid) {
22227 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22228 "Re-using existing item: " + item);
22234 // No existing item in pending changes; need a new one.
22235 final int NA = mAvailProcessChanges.size();
22237 item = mAvailProcessChanges.remove(NA-1);
22238 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22239 "Retrieving available item: " + item);
22241 item = new ProcessChangeItem();
22242 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22243 "Allocating new item: " + item);
22246 item.pid = app.pid;
22247 item.uid = app.info.uid;
22248 if (mPendingProcessChanges.size() == 0) {
22249 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22250 "*** Enqueueing dispatch processes changed!");
22251 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22253 mPendingProcessChanges.add(item);
22255 item.changes |= changes;
22256 item.foregroundActivities = app.repForegroundActivities;
22257 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22258 "Item " + Integer.toHexString(System.identityHashCode(item))
22259 + " " + app.toShortString() + ": changes=" + item.changes
22260 + " foreground=" + item.foregroundActivities
22261 + " type=" + app.adjType + " source=" + app.adjSource
22262 + " target=" + app.adjTarget);
22268 private boolean isEphemeralLocked(int uid) {
22269 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22270 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22273 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22278 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22279 final UidRecord.ChangeItem pendingChange;
22280 if (uidRec == null || uidRec.pendingChange == null) {
22281 if (mPendingUidChanges.size() == 0) {
22282 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22283 "*** Enqueueing dispatch uid changed!");
22284 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22286 final int NA = mAvailUidChanges.size();
22288 pendingChange = mAvailUidChanges.remove(NA-1);
22289 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22290 "Retrieving available item: " + pendingChange);
22292 pendingChange = new UidRecord.ChangeItem();
22293 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22294 "Allocating new item: " + pendingChange);
22296 if (uidRec != null) {
22297 uidRec.pendingChange = pendingChange;
22298 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22299 // If this uid is going away, and we haven't yet reported it is gone,
22301 change |= UidRecord.CHANGE_IDLE;
22303 } else if (uid < 0) {
22304 throw new IllegalArgumentException("No UidRecord or uid");
22306 pendingChange.uidRecord = uidRec;
22307 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22308 mPendingUidChanges.add(pendingChange);
22310 pendingChange = uidRec.pendingChange;
22311 // If there is no change in idle or active state, then keep whatever was pending.
22312 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22313 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22314 | UidRecord.CHANGE_ACTIVE));
22316 // If there is no change in cached or uncached state, then keep whatever was pending.
22317 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22318 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22319 | UidRecord.CHANGE_UNCACHED));
22321 // If this is a report of the UID being gone, then we shouldn't keep any previous
22322 // report of it being active or cached. (That is, a gone uid is never active,
22323 // and never cached.)
22324 if ((change & UidRecord.CHANGE_GONE) != 0) {
22325 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22326 if (!uidRec.idle) {
22327 // If this uid is going away, and we haven't yet reported it is gone,
22329 change |= UidRecord.CHANGE_IDLE;
22333 pendingChange.change = change;
22334 pendingChange.processState = uidRec != null
22335 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22336 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22337 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22338 if (uidRec != null) {
22339 uidRec.lastReportedChange = change;
22340 uidRec.updateLastDispatchedProcStateSeq(change);
22343 // Directly update the power manager, since we sit on top of it and it is critical
22344 // it be kept in sync (so wake locks will be held as soon as appropriate).
22345 if (mLocalPowerManager != null) {
22346 // TO DO: dispatch cached/uncached changes here, so we don't need to report
22347 // all proc state changes.
22348 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22349 mLocalPowerManager.uidActive(pendingChange.uid);
22351 if ((change & UidRecord.CHANGE_IDLE) != 0) {
22352 mLocalPowerManager.uidIdle(pendingChange.uid);
22354 if ((change & UidRecord.CHANGE_GONE) != 0) {
22355 mLocalPowerManager.uidGone(pendingChange.uid);
22357 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22358 pendingChange.processState);
22363 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22364 String authority) {
22365 if (app == null) return;
22366 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22367 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22368 if (userState == null) return;
22369 final long now = SystemClock.elapsedRealtime();
22370 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22371 if (lastReported == null || lastReported < now - 60 * 1000L) {
22372 if (mSystemReady) {
22373 // Cannot touch the user stats if not system ready
22374 mUsageStatsService.reportContentProviderUsage(
22375 authority, providerPkgName, app.userId);
22377 userState.mProviderLastReportedFg.put(authority, now);
22382 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22383 if (DEBUG_USAGE_STATS) {
22384 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22385 + "] state changes: old = " + app.setProcState + ", new = "
22386 + app.curProcState);
22388 if (mUsageStatsService == null) {
22391 boolean isInteraction;
22392 // To avoid some abuse patterns, we are going to be careful about what we consider
22393 // to be an app interaction. Being the top activity doesn't count while the display
22394 // is sleeping, nor do short foreground services.
22395 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22396 isInteraction = true;
22397 app.fgInteractionTime = 0;
22398 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22399 if (app.fgInteractionTime == 0) {
22400 app.fgInteractionTime = nowElapsed;
22401 isInteraction = false;
22403 isInteraction = nowElapsed > app.fgInteractionTime
22404 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22407 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22408 app.fgInteractionTime = 0;
22410 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22411 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22412 app.interactionEventTime = nowElapsed;
22413 String[] packages = app.getPackageList();
22414 if (packages != null) {
22415 for (int i = 0; i < packages.length; i++) {
22416 mUsageStatsService.reportEvent(packages[i], app.userId,
22417 UsageEvents.Event.SYSTEM_INTERACTION);
22421 app.reportedInteraction = isInteraction;
22422 if (!isInteraction) {
22423 app.interactionEventTime = 0;
22427 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22428 if (proc.thread != null) {
22429 if (proc.baseProcessTracker != null) {
22430 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22435 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22436 ProcessRecord TOP_APP, boolean doingAll, long now) {
22437 if (app.thread == null) {
22441 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22443 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22446 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22448 if (isForeground != proc.foregroundServices) {
22449 proc.foregroundServices = isForeground;
22450 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22452 if (isForeground) {
22453 if (curProcs == null) {
22454 curProcs = new ArrayList<ProcessRecord>();
22455 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22457 if (!curProcs.contains(proc)) {
22458 curProcs.add(proc);
22459 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22460 proc.info.packageName, proc.info.uid);
22463 if (curProcs != null) {
22464 if (curProcs.remove(proc)) {
22465 mBatteryStatsService.noteEvent(
22466 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22467 proc.info.packageName, proc.info.uid);
22468 if (curProcs.size() <= 0) {
22469 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22475 updateOomAdjLocked();
22480 private final ActivityRecord resumedAppLocked() {
22481 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22485 pkg = act.packageName;
22486 uid = act.info.applicationInfo.uid;
22491 // Has the UID or resumed package name changed?
22492 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22493 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22494 if (mCurResumedPackage != null) {
22495 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22496 mCurResumedPackage, mCurResumedUid);
22498 mCurResumedPackage = pkg;
22499 mCurResumedUid = uid;
22500 if (mCurResumedPackage != null) {
22501 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22502 mCurResumedPackage, mCurResumedUid);
22509 * Update OomAdj for a specific process.
22510 * @param app The process to update
22511 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22512 * if necessary, or skip.
22513 * @return whether updateOomAdjLocked(app) was successful.
22515 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22516 final ActivityRecord TOP_ACT = resumedAppLocked();
22517 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22518 final boolean wasCached = app.cached;
22522 // This is the desired cached adjusment we want to tell it to use.
22523 // If our app is currently cached, we know it, and that is it. Otherwise,
22524 // we don't know it yet, and it needs to now be cached we will then
22525 // need to do a complete oom adj.
22526 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22527 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22528 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22529 SystemClock.uptimeMillis());
22531 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22532 // Changed to/from cached state, so apps after it in the LRU
22533 // list may also be changed.
22534 updateOomAdjLocked();
22539 final void updateOomAdjLocked() {
22540 final ActivityRecord TOP_ACT = resumedAppLocked();
22541 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22542 final long now = SystemClock.uptimeMillis();
22543 final long nowElapsed = SystemClock.elapsedRealtime();
22544 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22545 final int N = mLruProcesses.size();
22548 RuntimeException e = new RuntimeException();
22549 e.fillInStackTrace();
22550 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22553 // Reset state in all uid records.
22554 for (int i=mActiveUids.size()-1; i>=0; i--) {
22555 final UidRecord uidRec = mActiveUids.valueAt(i);
22556 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22557 "Starting update of " + uidRec);
22561 mStackSupervisor.rankTaskLayersIfNeeded();
22564 mNewNumServiceProcs = 0;
22565 mNewNumAServiceProcs = 0;
22567 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22568 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22570 // Let's determine how many processes we have running vs.
22571 // how many slots we have for background processes; we may want
22572 // to put multiple processes in a slot of there are enough of
22574 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22575 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22576 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22577 if (numEmptyProcs > cachedProcessLimit) {
22578 // If there are more empty processes than our limit on cached
22579 // processes, then use the cached process limit for the factor.
22580 // This ensures that the really old empty processes get pushed
22581 // down to the bottom, so if we are running low on memory we will
22582 // have a better chance at keeping around more cached processes
22583 // instead of a gazillion empty processes.
22584 numEmptyProcs = cachedProcessLimit;
22586 int emptyFactor = numEmptyProcs/numSlots;
22587 if (emptyFactor < 1) emptyFactor = 1;
22588 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22589 if (cachedFactor < 1) cachedFactor = 1;
22590 int stepCached = 0;
22594 int numTrimming = 0;
22596 mNumNonCachedProcs = 0;
22597 mNumCachedHiddenProcs = 0;
22599 // First update the OOM adjustment for each of the
22600 // application processes based on their current state.
22601 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22602 int nextCachedAdj = curCachedAdj+1;
22603 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22604 int nextEmptyAdj = curEmptyAdj+2;
22605 for (int i=N-1; i>=0; i--) {
22606 ProcessRecord app = mLruProcesses.get(i);
22607 if (!app.killedByAm && app.thread != null) {
22608 app.procStateChanged = false;
22609 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22611 // If we haven't yet assigned the final cached adj
22612 // to the process, do that now.
22613 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22614 switch (app.curProcState) {
22615 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22616 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22617 // This process is a cached process holding activities...
22618 // assign it the next cached value for that type, and then
22619 // step that cached level.
22620 app.curRawAdj = curCachedAdj;
22621 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22622 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22623 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22625 if (curCachedAdj != nextCachedAdj) {
22627 if (stepCached >= cachedFactor) {
22629 curCachedAdj = nextCachedAdj;
22630 nextCachedAdj += 2;
22631 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22632 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22638 // For everything else, assign next empty cached process
22639 // level and bump that up. Note that this means that
22640 // long-running services that have dropped down to the
22641 // cached level will be treated as empty (since their process
22642 // state is still as a service), which is what we want.
22643 app.curRawAdj = curEmptyAdj;
22644 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22645 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22646 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22648 if (curEmptyAdj != nextEmptyAdj) {
22650 if (stepEmpty >= emptyFactor) {
22652 curEmptyAdj = nextEmptyAdj;
22654 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22655 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22663 applyOomAdjLocked(app, true, now, nowElapsed);
22665 // Count the number of process types.
22666 switch (app.curProcState) {
22667 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22668 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22669 mNumCachedHiddenProcs++;
22671 if (numCached > cachedProcessLimit) {
22672 app.kill("cached #" + numCached, true);
22675 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22676 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22677 && app.lastActivityTime < oldTime) {
22678 app.kill("empty for "
22679 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22680 / 1000) + "s", true);
22683 if (numEmpty > emptyProcessLimit) {
22684 app.kill("empty #" + numEmpty, true);
22689 mNumNonCachedProcs++;
22693 if (app.isolated && app.services.size() <= 0) {
22694 // If this is an isolated process, and there are no
22695 // services running in it, then the process is no longer
22696 // needed. We agressively kill these because we can by
22697 // definition not re-use the same process again, and it is
22698 // good to avoid having whatever code was running in them
22699 // left sitting around after no longer needed.
22700 app.kill("isolated not needed", true);
22702 // Keeping this process, update its uid.
22703 final UidRecord uidRec = app.uidRecord;
22704 if (uidRec != null) {
22705 uidRec.ephemeral = app.info.isInstantApp();
22706 if (uidRec.curProcState > app.curProcState) {
22707 uidRec.curProcState = app.curProcState;
22709 if (app.foregroundServices) {
22710 uidRec.foregroundServices = true;
22715 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22716 && !app.killedByAm) {
22722 incrementProcStateSeqAndNotifyAppsLocked();
22724 mNumServiceProcs = mNewNumServiceProcs;
22726 // Now determine the memory trimming level of background processes.
22727 // Unfortunately we need to start at the back of the list to do this
22728 // properly. We only do this if the number of background apps we
22729 // are managing to keep around is less than half the maximum we desire;
22730 // if we are keeping a good number around, we'll let them use whatever
22731 // memory they want.
22732 final int numCachedAndEmpty = numCached + numEmpty;
22734 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22735 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22736 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22737 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22738 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22739 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22741 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22744 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22746 // We always allow the memory level to go up (better). We only allow it to go
22747 // down if we are in a state where that is allowed, *and* the total number of processes
22748 // has gone down since last time.
22749 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22750 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22751 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22752 if (memFactor > mLastMemoryLevel) {
22753 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22754 memFactor = mLastMemoryLevel;
22755 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22758 if (memFactor != mLastMemoryLevel) {
22759 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22761 mLastMemoryLevel = memFactor;
22762 mLastNumProcesses = mLruProcesses.size();
22763 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22764 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22765 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22766 if (mLowRamStartTime == 0) {
22767 mLowRamStartTime = now;
22771 switch (memFactor) {
22772 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22773 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22775 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22776 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22779 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22782 int factor = numTrimming/3;
22784 if (mHomeProcess != null) minFactor++;
22785 if (mPreviousProcess != null) minFactor++;
22786 if (factor < minFactor) factor = minFactor;
22787 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22788 for (int i=N-1; i>=0; i--) {
22789 ProcessRecord app = mLruProcesses.get(i);
22790 if (allChanged || app.procStateChanged) {
22791 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22792 app.procStateChanged = false;
22794 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22795 && !app.killedByAm) {
22796 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22798 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22799 "Trimming memory of " + app.processName + " to " + curLevel);
22800 app.thread.scheduleTrimMemory(curLevel);
22801 } catch (RemoteException e) {
22804 // For now we won't do this; our memory trimming seems
22805 // to be good enough at this point that destroying
22806 // activities causes more harm than good.
22807 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22808 && app != mHomeProcess && app != mPreviousProcess) {
22809 // Need to do this on its own message because the stack may not
22810 // be in a consistent state at this point.
22811 // For these apps we will also finish their activities
22812 // to help them free memory.
22813 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22817 app.trimMemoryLevel = curLevel;
22819 if (step >= factor) {
22821 switch (curLevel) {
22822 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22823 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22825 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22826 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22830 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22831 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22832 && app.thread != null) {
22834 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22835 "Trimming memory of heavy-weight " + app.processName
22836 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22837 app.thread.scheduleTrimMemory(
22838 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22839 } catch (RemoteException e) {
22842 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22844 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22845 || app.systemNoUi) && app.pendingUiClean) {
22846 // If this application is now in the background and it
22847 // had done UI, then give it the special trim level to
22848 // have it free UI resources.
22849 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22850 if (app.trimMemoryLevel < level && app.thread != null) {
22852 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22853 "Trimming memory of bg-ui " + app.processName
22855 app.thread.scheduleTrimMemory(level);
22856 } catch (RemoteException e) {
22859 app.pendingUiClean = false;
22861 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22863 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22864 "Trimming memory of fg " + app.processName
22865 + " to " + fgTrimLevel);
22866 app.thread.scheduleTrimMemory(fgTrimLevel);
22867 } catch (RemoteException e) {
22870 app.trimMemoryLevel = fgTrimLevel;
22874 if (mLowRamStartTime != 0) {
22875 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22876 mLowRamStartTime = 0;
22878 for (int i=N-1; i>=0; i--) {
22879 ProcessRecord app = mLruProcesses.get(i);
22880 if (allChanged || app.procStateChanged) {
22881 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22882 app.procStateChanged = false;
22884 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22885 || app.systemNoUi) && app.pendingUiClean) {
22886 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22887 && app.thread != null) {
22889 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22890 "Trimming memory of ui hidden " + app.processName
22891 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22892 app.thread.scheduleTrimMemory(
22893 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22894 } catch (RemoteException e) {
22897 app.pendingUiClean = false;
22899 app.trimMemoryLevel = 0;
22903 if (mAlwaysFinishActivities) {
22904 // Need to do this on its own message because the stack may not
22905 // be in a consistent state at this point.
22906 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22910 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22913 ArrayList<UidRecord> becameIdle = null;
22915 // Update from any uid changes.
22916 if (mLocalPowerManager != null) {
22917 mLocalPowerManager.startUidChanges();
22919 for (int i=mActiveUids.size()-1; i>=0; i--) {
22920 final UidRecord uidRec = mActiveUids.valueAt(i);
22921 int uidChange = UidRecord.CHANGE_PROCSTATE;
22922 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22923 && (uidRec.setProcState != uidRec.curProcState
22924 || uidRec.setWhitelist != uidRec.curWhitelist)) {
22925 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22926 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22927 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22928 + " to " + uidRec.curWhitelist);
22929 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22930 && !uidRec.curWhitelist) {
22931 // UID is now in the background (and not on the temp whitelist). Was it
22932 // previously in the foreground (or on the temp whitelist)?
22933 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22934 || uidRec.setWhitelist) {
22935 uidRec.lastBackgroundTime = nowElapsed;
22936 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22937 // Note: the background settle time is in elapsed realtime, while
22938 // the handler time base is uptime. All this means is that we may
22939 // stop background uids later than we had intended, but that only
22940 // happens because the device was sleeping so we are okay anyway.
22941 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22942 mConstants.BACKGROUND_SETTLE_TIME);
22945 if (uidRec.idle && !uidRec.setIdle) {
22946 uidChange = UidRecord.CHANGE_IDLE;
22947 if (becameIdle == null) {
22948 becameIdle = new ArrayList<>();
22950 becameIdle.add(uidRec);
22954 uidChange = UidRecord.CHANGE_ACTIVE;
22955 EventLogTags.writeAmUidActive(uidRec.uid);
22956 uidRec.idle = false;
22958 uidRec.lastBackgroundTime = 0;
22960 final boolean wasCached = uidRec.setProcState
22961 > ActivityManager.PROCESS_STATE_RECEIVER;
22962 final boolean isCached = uidRec.curProcState
22963 > ActivityManager.PROCESS_STATE_RECEIVER;
22964 if (wasCached != isCached ||
22965 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22966 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22968 uidRec.setProcState = uidRec.curProcState;
22969 uidRec.setWhitelist = uidRec.curWhitelist;
22970 uidRec.setIdle = uidRec.idle;
22971 enqueueUidChangeLocked(uidRec, -1, uidChange);
22972 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22973 if (uidRec.foregroundServices) {
22974 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22978 if (mLocalPowerManager != null) {
22979 mLocalPowerManager.finishUidChanges();
22982 if (becameIdle != null) {
22983 // If we have any new uids that became idle this time, we need to make sure
22984 // they aren't left with running services.
22985 for (int i = becameIdle.size() - 1; i >= 0; i--) {
22986 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22990 if (mProcessStats.shouldWriteNowLocked(now)) {
22991 mHandler.post(new Runnable() {
22992 @Override public void run() {
22993 synchronized (ActivityManagerService.this) {
22994 mProcessStats.writeStateAsyncLocked();
23000 if (DEBUG_OOM_ADJ) {
23001 final long duration = SystemClock.uptimeMillis() - now;
23003 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23004 new RuntimeException("here").fillInStackTrace());
23006 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23012 public void makePackageIdle(String packageName, int userId) {
23013 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23014 != PackageManager.PERMISSION_GRANTED) {
23015 String msg = "Permission Denial: makePackageIdle() from pid="
23016 + Binder.getCallingPid()
23017 + ", uid=" + Binder.getCallingUid()
23018 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23020 throw new SecurityException(msg);
23022 final int callingPid = Binder.getCallingPid();
23023 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23024 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23025 long callingId = Binder.clearCallingIdentity();
23026 synchronized(this) {
23028 IPackageManager pm = AppGlobals.getPackageManager();
23031 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23032 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23033 } catch (RemoteException e) {
23035 if (pkgUid == -1) {
23036 throw new IllegalArgumentException("Unknown package name " + packageName);
23039 if (mLocalPowerManager != null) {
23040 mLocalPowerManager.startUidChanges();
23042 final int appId = UserHandle.getAppId(pkgUid);
23043 final int N = mActiveUids.size();
23044 for (int i=N-1; i>=0; i--) {
23045 final UidRecord uidRec = mActiveUids.valueAt(i);
23046 final long bgTime = uidRec.lastBackgroundTime;
23047 if (bgTime > 0 && !uidRec.idle) {
23048 if (UserHandle.getAppId(uidRec.uid) == appId) {
23049 if (userId == UserHandle.USER_ALL ||
23050 userId == UserHandle.getUserId(uidRec.uid)) {
23051 EventLogTags.writeAmUidIdle(uidRec.uid);
23052 uidRec.idle = true;
23053 uidRec.setIdle = true;
23054 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23055 + " from package " + packageName + " user " + userId);
23056 doStopUidLocked(uidRec.uid, uidRec);
23062 if (mLocalPowerManager != null) {
23063 mLocalPowerManager.finishUidChanges();
23065 Binder.restoreCallingIdentity(callingId);
23070 final void idleUids() {
23071 synchronized (this) {
23072 final int N = mActiveUids.size();
23076 final long nowElapsed = SystemClock.elapsedRealtime();
23077 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23079 if (mLocalPowerManager != null) {
23080 mLocalPowerManager.startUidChanges();
23082 for (int i=N-1; i>=0; i--) {
23083 final UidRecord uidRec = mActiveUids.valueAt(i);
23084 final long bgTime = uidRec.lastBackgroundTime;
23085 if (bgTime > 0 && !uidRec.idle) {
23086 if (bgTime <= maxBgTime) {
23087 EventLogTags.writeAmUidIdle(uidRec.uid);
23088 uidRec.idle = true;
23089 uidRec.setIdle = true;
23090 doStopUidLocked(uidRec.uid, uidRec);
23092 if (nextTime == 0 || nextTime > bgTime) {
23098 if (mLocalPowerManager != null) {
23099 mLocalPowerManager.finishUidChanges();
23101 if (nextTime > 0) {
23102 mHandler.removeMessages(IDLE_UIDS_MSG);
23103 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23104 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23110 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23111 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23112 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23116 void incrementProcStateSeqAndNotifyAppsLocked() {
23117 if (mWaitForNetworkTimeoutMs <= 0) {
23120 // Used for identifying which uids need to block for network.
23121 ArrayList<Integer> blockingUids = null;
23122 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23123 final UidRecord uidRec = mActiveUids.valueAt(i);
23124 // If the network is not restricted for uid, then nothing to do here.
23125 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23128 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23131 // If process state is not changed, then there's nothing to do.
23132 if (uidRec.setProcState == uidRec.curProcState) {
23135 final int blockState = getBlockStateForUid(uidRec);
23136 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23137 // there's nothing the app needs to do in this scenario.
23138 if (blockState == NETWORK_STATE_NO_CHANGE) {
23141 synchronized (uidRec.networkStateLock) {
23142 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23143 if (blockState == NETWORK_STATE_BLOCK) {
23144 if (blockingUids == null) {
23145 blockingUids = new ArrayList<>();
23147 blockingUids.add(uidRec.uid);
23149 if (DEBUG_NETWORK) {
23150 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23151 + " threads for uid: " + uidRec);
23153 if (uidRec.waitingForNetwork) {
23154 uidRec.networkStateLock.notifyAll();
23160 // There are no uids that need to block, so nothing more to do.
23161 if (blockingUids == null) {
23165 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23166 final ProcessRecord app = mLruProcesses.get(i);
23167 if (!blockingUids.contains(app.uid)) {
23170 if (!app.killedByAm && app.thread != null) {
23171 final UidRecord uidRec = mActiveUids.get(app.uid);
23173 if (DEBUG_NETWORK) {
23174 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23177 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23178 } catch (RemoteException ignored) {
23185 * Checks if the uid is coming from background to foreground or vice versa and returns
23186 * appropriate block state based on this.
23188 * @return blockState based on whether the uid is coming from background to foreground or
23189 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23190 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23191 * {@link #NETWORK_STATE_NO_CHANGE}.
23194 int getBlockStateForUid(UidRecord uidRec) {
23195 // Denotes whether uid's process state is currently allowed network access.
23196 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23197 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23198 // Denotes whether uid's process state was previously allowed network access.
23199 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23200 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23202 // When the uid is coming to foreground, AMS should inform the app thread that it should
23203 // block for the network rules to get updated before launching an activity.
23204 if (!wasAllowed && isAllowed) {
23205 return NETWORK_STATE_BLOCK;
23207 // When the uid is going to background, AMS should inform the app thread that if an
23208 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23209 if (wasAllowed && !isAllowed) {
23210 return NETWORK_STATE_UNBLOCK;
23212 return NETWORK_STATE_NO_CHANGE;
23215 final void runInBackgroundDisabled(int uid) {
23216 synchronized (this) {
23217 UidRecord uidRec = mActiveUids.get(uid);
23218 if (uidRec != null) {
23219 // This uid is actually running... should it be considered background now?
23221 doStopUidLocked(uidRec.uid, uidRec);
23224 // This uid isn't actually running... still send a report about it being "stopped".
23225 doStopUidLocked(uid, null);
23230 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23231 mServices.stopInBackgroundLocked(uid);
23232 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23236 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23238 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23239 long duration, String tag) {
23240 if (DEBUG_WHITELISTS) {
23241 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23242 + targetUid + ", " + duration + ")");
23245 synchronized (mPidsSelfLocked) {
23246 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23248 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23252 if (!pr.whitelistManager) {
23253 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23254 != PackageManager.PERMISSION_GRANTED) {
23255 if (DEBUG_WHITELISTS) {
23256 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23257 + ": pid " + callerPid + " is not allowed");
23264 tempWhitelistUidLocked(targetUid, duration, tag);
23268 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23270 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23271 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23272 setUidTempWhitelistStateLocked(targetUid, true);
23273 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23276 void pushTempWhitelist() {
23278 final PendingTempWhitelist[] list;
23280 // First copy out the pending changes... we need to leave them in the map for now,
23281 // in case someone needs to check what is coming up while we don't have the lock held.
23282 synchronized(this) {
23283 N = mPendingTempWhitelist.size();
23284 list = new PendingTempWhitelist[N];
23285 for (int i = 0; i < N; i++) {
23286 list[i] = mPendingTempWhitelist.valueAt(i);
23290 // Now safely dispatch changes to device idle controller.
23291 for (int i = 0; i < N; i++) {
23292 PendingTempWhitelist ptw = list[i];
23293 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23294 ptw.duration, true, ptw.tag);
23297 // And now we can safely remove them from the map.
23298 synchronized(this) {
23299 for (int i = 0; i < N; i++) {
23300 PendingTempWhitelist ptw = list[i];
23301 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23302 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23303 mPendingTempWhitelist.removeAt(index);
23309 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23310 boolean changed = false;
23311 for (int i=mActiveUids.size()-1; i>=0; i--) {
23312 final UidRecord uidRec = mActiveUids.valueAt(i);
23313 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23314 uidRec.curWhitelist = onWhitelist;
23319 updateOomAdjLocked();
23323 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23324 boolean changed = false;
23325 final UidRecord uidRec = mActiveUids.get(uid);
23326 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23327 uidRec.curWhitelist = onWhitelist;
23328 updateOomAdjLocked();
23332 final void trimApplications() {
23333 synchronized (this) {
23336 // First remove any unused application processes whose package
23337 // has been removed.
23338 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23339 final ProcessRecord app = mRemovedProcesses.get(i);
23340 if (app.activities.size() == 0
23341 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23343 TAG, "Exiting empty application process "
23344 + app.toShortString() + " ("
23345 + (app.thread != null ? app.thread.asBinder() : null)
23347 if (app.pid > 0 && app.pid != MY_PID) {
23348 app.kill("empty", false);
23351 app.thread.scheduleExit();
23352 } catch (Exception e) {
23353 // Ignore exceptions.
23356 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23357 mRemovedProcesses.remove(i);
23359 if (app.persistent) {
23360 addAppLocked(app.info, null, false, null /* ABI override */);
23365 // Now update the oom adj for all processes.
23366 updateOomAdjLocked();
23370 /** This method sends the specified signal to each of the persistent apps */
23371 public void signalPersistentProcesses(int sig) throws RemoteException {
23372 if (sig != SIGNAL_USR1) {
23373 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23376 synchronized (this) {
23377 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23378 != PackageManager.PERMISSION_GRANTED) {
23379 throw new SecurityException("Requires permission "
23380 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23383 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23384 ProcessRecord r = mLruProcesses.get(i);
23385 if (r.thread != null && r.persistent) {
23386 sendSignal(r.pid, sig);
23392 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23393 if (proc == null || proc == mProfileProc) {
23394 proc = mProfileProc;
23395 profileType = mProfileType;
23396 clearProfilerLocked();
23398 if (proc == null) {
23402 proc.thread.profilerControl(false, null, profileType);
23403 } catch (RemoteException e) {
23404 throw new IllegalStateException("Process disappeared");
23408 private void clearProfilerLocked() {
23409 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23411 mProfilerInfo.profileFd.close();
23412 } catch (IOException e) {
23415 mProfileApp = null;
23416 mProfileProc = null;
23417 mProfilerInfo = null;
23420 public boolean profileControl(String process, int userId, boolean start,
23421 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23424 synchronized (this) {
23425 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23426 // its own permission.
23427 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23428 != PackageManager.PERMISSION_GRANTED) {
23429 throw new SecurityException("Requires permission "
23430 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23433 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23434 throw new IllegalArgumentException("null profile info or fd");
23437 ProcessRecord proc = null;
23438 if (process != null) {
23439 proc = findProcessLocked(process, userId, "profileControl");
23442 if (start && (proc == null || proc.thread == null)) {
23443 throw new IllegalArgumentException("Unknown process: " + process);
23447 stopProfilerLocked(null, 0);
23448 setProfileApp(proc.info, proc.processName, profilerInfo);
23449 mProfileProc = proc;
23450 mProfileType = profileType;
23451 ParcelFileDescriptor fd = profilerInfo.profileFd;
23454 } catch (IOException e) {
23457 profilerInfo.profileFd = fd;
23458 proc.thread.profilerControl(start, profilerInfo, profileType);
23461 mProfilerInfo.profileFd.close();
23462 } catch (IOException e) {
23464 mProfilerInfo.profileFd = null;
23466 stopProfilerLocked(proc, profileType);
23467 if (profilerInfo != null && profilerInfo.profileFd != null) {
23469 profilerInfo.profileFd.close();
23470 } catch (IOException e) {
23477 } catch (RemoteException e) {
23478 throw new IllegalStateException("Process disappeared");
23480 if (profilerInfo != null && profilerInfo.profileFd != null) {
23482 profilerInfo.profileFd.close();
23483 } catch (IOException e) {
23489 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23490 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23491 userId, true, ALLOW_FULL_ONLY, callName, null);
23492 ProcessRecord proc = null;
23494 int pid = Integer.parseInt(process);
23495 synchronized (mPidsSelfLocked) {
23496 proc = mPidsSelfLocked.get(pid);
23498 } catch (NumberFormatException e) {
23501 if (proc == null) {
23502 ArrayMap<String, SparseArray<ProcessRecord>> all
23503 = mProcessNames.getMap();
23504 SparseArray<ProcessRecord> procs = all.get(process);
23505 if (procs != null && procs.size() > 0) {
23506 proc = procs.valueAt(0);
23507 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23508 for (int i=1; i<procs.size(); i++) {
23509 ProcessRecord thisProc = procs.valueAt(i);
23510 if (thisProc.userId == userId) {
23522 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23523 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23526 synchronized (this) {
23527 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23528 // its own permission (same as profileControl).
23529 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23530 != PackageManager.PERMISSION_GRANTED) {
23531 throw new SecurityException("Requires permission "
23532 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23536 throw new IllegalArgumentException("null fd");
23539 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23540 if (proc == null || proc.thread == null) {
23541 throw new IllegalArgumentException("Unknown process: " + process);
23544 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23545 if (!isDebuggable) {
23546 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23547 throw new SecurityException("Process not debuggable: " + proc);
23551 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23555 } catch (RemoteException e) {
23556 throw new IllegalStateException("Process disappeared");
23561 } catch (IOException e) {
23568 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23569 String reportPackage) {
23570 if (processName != null) {
23571 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23572 "setDumpHeapDebugLimit()");
23574 synchronized (mPidsSelfLocked) {
23575 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23576 if (proc == null) {
23577 throw new SecurityException("No process found for calling pid "
23578 + Binder.getCallingPid());
23580 if (!Build.IS_DEBUGGABLE
23581 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23582 throw new SecurityException("Not running a debuggable build");
23584 processName = proc.processName;
23586 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23587 throw new SecurityException("Package " + reportPackage + " is not running in "
23592 synchronized (this) {
23593 if (maxMemSize > 0) {
23594 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23597 mMemWatchProcesses.remove(processName, uid);
23599 mMemWatchProcesses.getMap().remove(processName);
23606 public void dumpHeapFinished(String path) {
23607 synchronized (this) {
23608 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23609 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23610 + " does not match last pid " + mMemWatchDumpPid);
23613 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23614 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23615 + " does not match last path " + mMemWatchDumpFile);
23618 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23619 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23621 // Forced gc to clean up the remnant hprof fd.
23622 Runtime.getRuntime().gc();
23626 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23627 public void monitor() {
23628 synchronized (this) { }
23631 void onCoreSettingsChange(Bundle settings) {
23632 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23633 ProcessRecord processRecord = mLruProcesses.get(i);
23635 if (processRecord.thread != null) {
23636 processRecord.thread.setCoreSettings(settings);
23638 } catch (RemoteException re) {
23644 // Multi-user methods
23647 * Start user, if its not already running, but don't bring it to foreground.
23650 public boolean startUserInBackground(final int userId) {
23651 return mUserController.startUser(userId, /* foreground */ false);
23655 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23656 return mUserController.unlockUser(userId, token, secret, listener);
23660 public boolean switchUser(final int targetUserId) {
23661 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23663 UserInfo targetUserInfo;
23664 synchronized (this) {
23665 currentUserId = mUserController.getCurrentUserIdLocked();
23666 targetUserInfo = mUserController.getUserInfo(targetUserId);
23667 if (targetUserId == currentUserId) {
23668 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23671 if (targetUserInfo == null) {
23672 Slog.w(TAG, "No user info for user #" + targetUserId);
23675 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23676 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23677 + " when device is in demo mode");
23680 if (!targetUserInfo.supportsSwitchTo()) {
23681 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23684 if (targetUserInfo.isManagedProfile()) {
23685 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23688 mUserController.setTargetUserIdLocked(targetUserId);
23690 if (mUserController.mUserSwitchUiEnabled) {
23691 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23692 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23693 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23694 mUiHandler.sendMessage(mHandler.obtainMessage(
23695 START_USER_SWITCH_UI_MSG, userNames));
23697 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23698 mHandler.sendMessage(mHandler.obtainMessage(
23699 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23704 void scheduleStartProfilesLocked() {
23705 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23706 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23707 DateUtils.SECOND_IN_MILLIS);
23712 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23713 return mUserController.stopUser(userId, force, callback);
23717 public UserInfo getCurrentUser() {
23718 return mUserController.getCurrentUser();
23721 String getStartedUserState(int userId) {
23722 synchronized (this) {
23723 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23724 return UserState.stateToString(userState.state);
23729 public boolean isUserRunning(int userId, int flags) {
23730 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23731 && checkCallingPermission(INTERACT_ACROSS_USERS)
23732 != PackageManager.PERMISSION_GRANTED) {
23733 String msg = "Permission Denial: isUserRunning() from pid="
23734 + Binder.getCallingPid()
23735 + ", uid=" + Binder.getCallingUid()
23736 + " requires " + INTERACT_ACROSS_USERS;
23738 throw new SecurityException(msg);
23740 synchronized (this) {
23741 return mUserController.isUserRunningLocked(userId, flags);
23746 public int[] getRunningUserIds() {
23747 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23748 != PackageManager.PERMISSION_GRANTED) {
23749 String msg = "Permission Denial: isUserRunning() from pid="
23750 + Binder.getCallingPid()
23751 + ", uid=" + Binder.getCallingUid()
23752 + " requires " + INTERACT_ACROSS_USERS;
23754 throw new SecurityException(msg);
23756 synchronized (this) {
23757 return mUserController.getStartedUserArrayLocked();
23762 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23763 mUserController.registerUserSwitchObserver(observer, name);
23767 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23768 mUserController.unregisterUserSwitchObserver(observer);
23771 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23772 if (info == null) return null;
23773 ApplicationInfo newInfo = new ApplicationInfo(info);
23774 newInfo.initForUser(userId);
23778 public boolean isUserStopped(int userId) {
23779 synchronized (this) {
23780 return mUserController.getStartedUserStateLocked(userId) == null;
23784 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23786 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23790 ActivityInfo info = new ActivityInfo(aInfo);
23791 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23795 private boolean processSanityChecksLocked(ProcessRecord process) {
23796 if (process == null || process.thread == null) {
23800 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23801 if (!isDebuggable) {
23802 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23810 public boolean startBinderTracking() throws RemoteException {
23811 synchronized (this) {
23812 mBinderTransactionTrackingEnabled = true;
23813 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23814 // permission (same as profileControl).
23815 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23816 != PackageManager.PERMISSION_GRANTED) {
23817 throw new SecurityException("Requires permission "
23818 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23821 for (int i = 0; i < mLruProcesses.size(); i++) {
23822 ProcessRecord process = mLruProcesses.get(i);
23823 if (!processSanityChecksLocked(process)) {
23827 process.thread.startBinderTracking();
23828 } catch (RemoteException e) {
23829 Log.v(TAG, "Process disappared");
23836 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23838 synchronized (this) {
23839 mBinderTransactionTrackingEnabled = false;
23840 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23841 // permission (same as profileControl).
23842 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23843 != PackageManager.PERMISSION_GRANTED) {
23844 throw new SecurityException("Requires permission "
23845 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23849 throw new IllegalArgumentException("null fd");
23852 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23853 pw.println("Binder transaction traces for all processes.\n");
23854 for (ProcessRecord process : mLruProcesses) {
23855 if (!processSanityChecksLocked(process)) {
23859 pw.println("Traces for process: " + process.processName);
23862 TransferPipe tp = new TransferPipe();
23864 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23865 tp.go(fd.getFileDescriptor());
23869 } catch (IOException e) {
23870 pw.println("Failure while dumping IPC traces from " + process +
23871 ". Exception: " + e);
23873 } catch (RemoteException e) {
23874 pw.println("Got a RemoteException while dumping IPC traces from " +
23875 process + ". Exception: " + e);
23886 } catch (IOException e) {
23893 final class LocalService extends ActivityManagerInternal {
23895 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23896 int targetUserId) {
23897 synchronized (ActivityManagerService.this) {
23898 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23899 targetPkg, intent, null, targetUserId);
23904 public String checkContentProviderAccess(String authority, int userId) {
23905 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23909 public void onWakefulnessChanged(int wakefulness) {
23910 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23914 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23915 String processName, String abiOverride, int uid, Runnable crashHandler) {
23916 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23917 processName, abiOverride, uid, crashHandler);
23921 public SleepToken acquireSleepToken(String tag, int displayId) {
23922 Preconditions.checkNotNull(tag);
23923 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23927 public ComponentName getHomeActivityForUser(int userId) {
23928 synchronized (ActivityManagerService.this) {
23929 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23930 return homeActivity == null ? null : homeActivity.realActivity;
23935 public void onUserRemoved(int userId) {
23936 synchronized (ActivityManagerService.this) {
23937 ActivityManagerService.this.onUserStoppedLocked(userId);
23939 mBatteryStatsService.onUserRemoved(userId);
23943 public void onLocalVoiceInteractionStarted(IBinder activity,
23944 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23945 synchronized (ActivityManagerService.this) {
23946 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23947 voiceSession, voiceInteractor);
23952 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23953 synchronized (ActivityManagerService.this) {
23954 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23955 reasons, timestamp);
23960 public void notifyAppTransitionFinished() {
23961 synchronized (ActivityManagerService.this) {
23962 mStackSupervisor.notifyAppTransitionDone();
23967 public void notifyAppTransitionCancelled() {
23968 synchronized (ActivityManagerService.this) {
23969 mStackSupervisor.notifyAppTransitionDone();
23974 public List<IBinder> getTopVisibleActivities() {
23975 synchronized (ActivityManagerService.this) {
23976 return mStackSupervisor.getTopVisibleActivities();
23981 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23982 synchronized (ActivityManagerService.this) {
23983 mStackSupervisor.setDockedStackMinimized(minimized);
23988 public void killForegroundAppsForUser(int userHandle) {
23989 synchronized (ActivityManagerService.this) {
23990 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23991 final int NP = mProcessNames.getMap().size();
23992 for (int ip = 0; ip < NP; ip++) {
23993 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23994 final int NA = apps.size();
23995 for (int ia = 0; ia < NA; ia++) {
23996 final ProcessRecord app = apps.valueAt(ia);
23997 if (app.persistent) {
23998 // We don't kill persistent processes.
24003 } else if (app.userId == userHandle && app.foregroundActivities) {
24004 app.removed = true;
24010 final int N = procs.size();
24011 for (int i = 0; i < N; i++) {
24012 removeProcessLocked(procs.get(i), false, true, "kill all fg");
24018 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24020 if (!(target instanceof PendingIntentRecord)) {
24021 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24024 synchronized (ActivityManagerService.this) {
24025 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24030 public void setDeviceIdleWhitelist(int[] appids) {
24031 synchronized (ActivityManagerService.this) {
24032 mDeviceIdleWhitelist = appids;
24037 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24038 synchronized (ActivityManagerService.this) {
24039 mDeviceIdleTempWhitelist = appids;
24040 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24045 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24047 Preconditions.checkNotNull(values, "Configuration must not be null");
24048 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24049 synchronized (ActivityManagerService.this) {
24050 updateConfigurationLocked(values, null, false, true, userId,
24051 false /* deferResume */);
24056 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24058 Preconditions.checkNotNull(intents, "intents");
24059 final String[] resolvedTypes = new String[intents.length];
24060 for (int i = 0; i < intents.length; i++) {
24061 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24064 // UID of the package on user userId.
24065 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24066 // packageUid may not be initialized.
24067 int packageUid = 0;
24069 packageUid = AppGlobals.getPackageManager().getPackageUid(
24070 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24071 } catch (RemoteException e) {
24072 // Shouldn't happen.
24075 synchronized (ActivityManagerService.this) {
24076 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24077 /*resultTo*/ null, bOptions, userId);
24082 public int getUidProcessState(int uid) {
24083 return getUidState(uid);
24087 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24088 synchronized (ActivityManagerService.this) {
24090 // We might change the visibilities here, so prepare an empty app transition which
24091 // might be overridden later if we actually change visibilities.
24092 final boolean wasTransitionSet =
24093 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24094 if (!wasTransitionSet) {
24095 mWindowManager.prepareAppTransition(TRANSIT_NONE,
24096 false /* alwaysKeepCurrent */);
24098 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24100 // If there was a transition set already we don't want to interfere with it as we
24101 // might be starting it too early.
24102 if (!wasTransitionSet) {
24103 mWindowManager.executeAppTransition();
24106 if (callback != null) {
24112 public boolean isSystemReady() {
24113 // no need to synchronize(this) just to read & return the value
24114 return mSystemReady;
24118 public void notifyKeyguardTrustedChanged() {
24119 synchronized (ActivityManagerService.this) {
24120 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24121 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24127 * Sets if the given pid has an overlay UI or not.
24129 * @param pid The pid we are setting overlay UI for.
24130 * @param hasOverlayUi True if the process has overlay UI.
24131 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24134 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24135 synchronized (ActivityManagerService.this) {
24136 final ProcessRecord pr;
24137 synchronized (mPidsSelfLocked) {
24138 pr = mPidsSelfLocked.get(pid);
24140 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24144 if (pr.hasOverlayUi == hasOverlayUi) {
24147 pr.hasOverlayUi = hasOverlayUi;
24148 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24149 updateOomAdjLocked(pr, true);
24154 * Called after the network policy rules are updated by
24155 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24156 * and {@param procStateSeq}.
24159 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24160 if (DEBUG_NETWORK) {
24161 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24162 + uid + " seq: " + procStateSeq);
24165 synchronized (ActivityManagerService.this) {
24166 record = mActiveUids.get(uid);
24167 if (record == null) {
24168 if (DEBUG_NETWORK) {
24169 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24170 + " procStateSeq: " + procStateSeq);
24175 synchronized (record.networkStateLock) {
24176 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24177 if (DEBUG_NETWORK) {
24178 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24179 + " been handled for uid: " + uid);
24183 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24184 if (record.curProcStateSeq > procStateSeq) {
24185 if (DEBUG_NETWORK) {
24186 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24187 + ", curProcstateSeq: " + record.curProcStateSeq
24188 + ", procStateSeq: " + procStateSeq);
24192 if (record.waitingForNetwork) {
24193 if (DEBUG_NETWORK) {
24194 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24195 + ", procStateSeq: " + procStateSeq);
24197 record.networkStateLock.notifyAll();
24203 * Called after virtual display Id is updated by
24204 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24205 * {@param vrVr2dDisplayId}.
24208 public void setVr2dDisplayId(int vr2dDisplayId) {
24210 Slog.d(TAG, "setVr2dDisplayId called for: " +
24213 synchronized (ActivityManagerService.this) {
24214 mVr2dDisplayId = vr2dDisplayId;
24219 public void saveANRState(String reason) {
24220 synchronized (ActivityManagerService.this) {
24221 final StringWriter sw = new StringWriter();
24222 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24223 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24224 if (reason != null) {
24225 pw.println(" Reason: " + reason);
24228 mActivityStarter.dump(pw, " ", null);
24230 pw.println("-------------------------------------------------------------------------------");
24231 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24232 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24237 mLastANRState = sw.toString();
24242 public void clearSavedANRState() {
24243 synchronized (ActivityManagerService.this) {
24244 mLastANRState = null;
24249 public void setFocusedActivity(IBinder token) {
24250 synchronized (ActivityManagerService.this) {
24251 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24253 throw new IllegalArgumentException(
24254 "setFocusedActivity: No activity record matching token=" + token);
24256 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24257 r, "setFocusedActivity")) {
24258 mStackSupervisor.resumeFocusedStackTopActivityLocked();
24264 public void registerScreenObserver(ScreenObserver observer) {
24265 mScreenObservers.add(observer);
24270 * Called by app main thread to wait for the network policy rules to get updated.
24272 * @param procStateSeq The sequence number indicating the process state change that the main
24273 * thread is interested in.
24276 public void waitForNetworkStateUpdate(long procStateSeq) {
24277 final int callingUid = Binder.getCallingUid();
24278 if (DEBUG_NETWORK) {
24279 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24282 synchronized (this) {
24283 record = mActiveUids.get(callingUid);
24284 if (record == null) {
24288 synchronized (record.networkStateLock) {
24289 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24290 if (DEBUG_NETWORK) {
24291 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24292 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24293 + " lastProcStateSeqDispatchedToObservers: "
24294 + record.lastDispatchedProcStateSeq);
24298 if (record.curProcStateSeq > procStateSeq) {
24299 if (DEBUG_NETWORK) {
24300 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24301 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24302 + ", procStateSeq: " + procStateSeq);
24306 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24307 if (DEBUG_NETWORK) {
24308 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24309 + procStateSeq + ", so no need to wait. Uid: "
24310 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24311 + record.lastNetworkUpdatedProcStateSeq);
24316 if (DEBUG_NETWORK) {
24317 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24318 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24320 final long startTime = SystemClock.uptimeMillis();
24321 record.waitingForNetwork = true;
24322 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24323 record.waitingForNetwork = false;
24324 final long totalTime = SystemClock.uptimeMillis() - startTime;
24325 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24326 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24327 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24328 + procStateSeq + " UidRec: " + record
24329 + " validateUidRec: " + mValidateUids.get(callingUid));
24331 } catch (InterruptedException e) {
24332 Thread.currentThread().interrupt();
24337 public void waitForBroadcastIdle(PrintWriter pw) {
24338 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24340 boolean idle = true;
24341 synchronized (this) {
24342 for (BroadcastQueue queue : mBroadcastQueues) {
24343 if (!queue.isIdle()) {
24344 final String msg = "Waiting for queue " + queue + " to become idle...";
24354 final String msg = "All broadcast queues are idle!";
24360 SystemClock.sleep(1000);
24366 * Return the user id of the last resumed activity.
24369 public @UserIdInt int getLastResumedActivityUserId() {
24370 enforceCallingPermission(
24371 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24372 synchronized (this) {
24373 if (mLastResumedActivity == null) {
24374 return mUserController.getCurrentUserIdLocked();
24376 return mLastResumedActivity.userId;
24381 * An implementation of IAppTask, that allows an app to manage its own tasks via
24382 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24383 * only the process that calls getAppTasks() can call the AppTask methods.
24385 class AppTaskImpl extends IAppTask.Stub {
24386 private int mTaskId;
24387 private int mCallingUid;
24389 public AppTaskImpl(int taskId, int callingUid) {
24391 mCallingUid = callingUid;
24394 private void checkCaller() {
24395 if (mCallingUid != Binder.getCallingUid()) {
24396 throw new SecurityException("Caller " + mCallingUid
24397 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24402 public void finishAndRemoveTask() {
24405 synchronized (ActivityManagerService.this) {
24406 long origId = Binder.clearCallingIdentity();
24408 // We remove the task from recents to preserve backwards
24409 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24410 REMOVE_FROM_RECENTS)) {
24411 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24414 Binder.restoreCallingIdentity(origId);
24420 public ActivityManager.RecentTaskInfo getTaskInfo() {
24423 synchronized (ActivityManagerService.this) {
24424 long origId = Binder.clearCallingIdentity();
24426 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24428 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24430 return createRecentTaskInfoFromTaskRecord(tr);
24432 Binder.restoreCallingIdentity(origId);
24438 public void moveToFront() {
24440 // Will bring task to front if it already has a root activity.
24441 final long origId = Binder.clearCallingIdentity();
24443 synchronized (this) {
24444 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24447 Binder.restoreCallingIdentity(origId);
24452 public int startActivity(IBinder whoThread, String callingPackage,
24453 Intent intent, String resolvedType, Bundle bOptions) {
24456 int callingUser = UserHandle.getCallingUserId();
24458 IApplicationThread appThread;
24459 synchronized (ActivityManagerService.this) {
24460 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24462 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24464 appThread = IApplicationThread.Stub.asInterface(whoThread);
24465 if (appThread == null) {
24466 throw new IllegalArgumentException("Bad app thread " + appThread);
24469 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24470 resolvedType, null, null, null, null, 0, 0, null, null,
24471 null, bOptions, false, callingUser, tr, "AppTaskImpl");
24475 public void setExcludeFromRecents(boolean exclude) {
24478 synchronized (ActivityManagerService.this) {
24479 long origId = Binder.clearCallingIdentity();
24481 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24483 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24485 Intent intent = tr.getBaseIntent();
24487 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24489 intent.setFlags(intent.getFlags()
24490 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24493 Binder.restoreCallingIdentity(origId);
24500 * Kill processes for the user with id userId and that depend on the package named packageName
24503 public void killPackageDependents(String packageName, int userId) {
24504 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24505 if (packageName == null) {
24506 throw new NullPointerException(
24507 "Cannot kill the dependents of a package without its name.");
24510 long callingId = Binder.clearCallingIdentity();
24511 IPackageManager pm = AppGlobals.getPackageManager();
24514 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24515 } catch (RemoteException e) {
24517 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24518 throw new IllegalArgumentException(
24519 "Cannot kill dependents of non-existing package " + packageName);
24522 synchronized(this) {
24523 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24524 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24525 "dep: " + packageName);
24528 Binder.restoreCallingIdentity(callingId);
24533 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24534 throws RemoteException {
24535 final long callingId = Binder.clearCallingIdentity();
24537 mKeyguardController.dismissKeyguard(token, callback);
24539 Binder.restoreCallingIdentity(callingId);
24544 public int restartUserInBackground(final int userId) {
24545 return mUserController.restartUser(userId, /* foreground */ false);
24549 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24550 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24551 "scheduleApplicationInfoChanged()");
24553 synchronized (this) {
24554 final long origId = Binder.clearCallingIdentity();
24556 updateApplicationInfoLocked(packageNames, userId);
24558 Binder.restoreCallingIdentity(origId);
24563 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24564 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24565 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24566 final ProcessRecord app = mLruProcesses.get(i);
24567 if (app.thread == null) {
24571 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24575 final int packageCount = app.pkgList.size();
24576 for (int j = 0; j < packageCount; j++) {
24577 final String packageName = app.pkgList.keyAt(j);
24578 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24580 final ApplicationInfo ai = AppGlobals.getPackageManager()
24581 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24583 app.thread.scheduleApplicationInfoChanged(ai);
24585 } catch (RemoteException e) {
24586 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24587 packageName, app));
24595 * Attach an agent to the specified process (proces name or PID)
24597 public void attachAgent(String process, String path) {
24599 synchronized (this) {
24600 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24601 if (proc == null || proc.thread == null) {
24602 throw new IllegalArgumentException("Unknown process: " + process);
24605 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24606 if (!isDebuggable) {
24607 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24608 throw new SecurityException("Process not debuggable: " + proc);
24612 proc.thread.attachAgent(path);
24614 } catch (RemoteException e) {
24615 throw new IllegalStateException("Process disappeared");
24620 public static class Injector {
24621 private NetworkManagementInternal mNmi;
24623 public Context getContext() {
24627 public AppOpsService getAppOpsService(File file, Handler handler) {
24628 return new AppOpsService(file, handler);
24631 public Handler getUiHandler(ActivityManagerService service) {
24632 return service.new UiHandler();
24635 public boolean isNetworkRestrictedForUid(int uid) {
24636 if (ensureHasNetworkManagementInternal()) {
24637 return mNmi.isNetworkRestrictedForUid(uid);
24642 private boolean ensureHasNetworkManagementInternal() {
24643 if (mNmi == null) {
24644 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24646 return mNmi != null;
24651 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24652 throws RemoteException {
24653 synchronized (this) {
24654 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24658 final long origId = Binder.clearCallingIdentity();
24660 r.setShowWhenLocked(showWhenLocked);
24662 Binder.restoreCallingIdentity(origId);
24668 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24669 synchronized (this) {
24670 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24674 final long origId = Binder.clearCallingIdentity();
24676 r.setTurnScreenOn(turnScreenOn);
24678 Binder.restoreCallingIdentity(origId);