2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import static android.Manifest.permission.CHANGE_CONFIGURATION;
20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25 import static android.Manifest.permission.READ_FRAME_BUFFER;
26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
32 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
35 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
36 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
37 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
38 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
39 import static android.content.pm.PackageManager.GET_PROVIDERS;
40 import static android.content.pm.PackageManager.MATCH_ANY_USER;
41 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
43 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
44 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
45 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
46 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
47 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
49 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
50 import static android.os.Build.VERSION_CODES.N;
51 import static android.os.Process.BLUETOOTH_UID;
52 import static android.os.Process.FIRST_APPLICATION_UID;
53 import static android.os.Process.FIRST_ISOLATED_UID;
54 import static android.os.Process.LAST_ISOLATED_UID;
55 import static android.os.Process.NFC_UID;
56 import static android.os.Process.PHONE_UID;
57 import static android.os.Process.PROC_CHAR;
58 import static android.os.Process.PROC_OUT_LONG;
59 import static android.os.Process.PROC_PARENS;
60 import static android.os.Process.PROC_SPACE_TERM;
61 import static android.os.Process.ProcessStartResult;
62 import static android.os.Process.ROOT_UID;
63 import static android.os.Process.SCHED_FIFO;
64 import static android.os.Process.SCHED_OTHER;
65 import static android.os.Process.SCHED_RESET_ON_FORK;
66 import static android.os.Process.SHELL_UID;
67 import static android.os.Process.SIGNAL_QUIT;
68 import static android.os.Process.SIGNAL_USR1;
69 import static android.os.Process.SYSTEM_UID;
70 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
71 import static android.os.Process.THREAD_GROUP_DEFAULT;
72 import static android.os.Process.THREAD_GROUP_TOP_APP;
73 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
74 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
75 import static android.os.Process.getFreeMemory;
76 import static android.os.Process.getTotalMemory;
77 import static android.os.Process.isThreadInProcess;
78 import static android.os.Process.killProcess;
79 import static android.os.Process.killProcessQuiet;
80 import static android.os.Process.myPid;
81 import static android.os.Process.myUid;
82 import static android.os.Process.readProcFile;
83 import static android.os.Process.removeAllProcessGroups;
84 import static android.os.Process.sendSignal;
85 import static android.os.Process.setProcessGroup;
86 import static android.os.Process.setThreadPriority;
87 import static android.os.Process.setThreadScheduler;
88 import static android.os.Process.startWebView;
89 import static android.os.Process.zygoteProcess;
90 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
91 import static android.provider.Settings.Global.DEBUG_APP;
92 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
94 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
95 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
96 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
97 import static android.provider.Settings.System.FONT_SCALE;
98 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
99 import static android.text.format.DateUtils.DAY_IN_MILLIS;
100 import static android.view.Display.DEFAULT_DISPLAY;
101 import static android.view.Display.INVALID_DISPLAY;
102 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
103 import static com.android.internal.util.XmlUtils.readIntAttribute;
104 import static com.android.internal.util.XmlUtils.readLongAttribute;
105 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
106 import static com.android.internal.util.XmlUtils.writeIntAttribute;
107 import static com.android.internal.util.XmlUtils.writeLongAttribute;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
165 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
167 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188 import static org.xmlpull.v1.XmlPullParser.START_TAG;
190 import android.Manifest;
191 import android.Manifest.permission;
192 import android.annotation.NonNull;
193 import android.annotation.Nullable;
194 import android.annotation.UserIdInt;
195 import android.app.Activity;
196 import android.app.ActivityManager;
197 import android.app.ActivityManager.RunningTaskInfo;
198 import android.app.ActivityManager.StackId;
199 import android.app.ActivityManager.StackInfo;
200 import android.app.ActivityManager.TaskSnapshot;
201 import android.app.ActivityManager.TaskThumbnailInfo;
202 import android.app.ActivityManagerInternal;
203 import android.app.ActivityManagerInternal.SleepToken;
204 import android.app.ActivityOptions;
205 import android.app.ActivityThread;
206 import android.app.AlertDialog;
207 import android.app.AppGlobals;
208 import android.app.AppOpsManager;
209 import android.app.ApplicationErrorReport;
210 import android.app.ApplicationThreadConstants;
211 import android.app.BroadcastOptions;
212 import android.app.ContentProviderHolder;
213 import android.app.Dialog;
214 import android.app.IActivityController;
215 import android.app.IActivityManager;
216 import android.app.IAppTask;
217 import android.app.IApplicationThread;
218 import android.app.IInstrumentationWatcher;
219 import android.app.INotificationManager;
220 import android.app.IProcessObserver;
221 import android.app.IServiceConnection;
222 import android.app.IStopUserCallback;
223 import android.app.ITaskStackListener;
224 import android.app.IUiAutomationConnection;
225 import android.app.IUidObserver;
226 import android.app.IUserSwitchObserver;
227 import android.app.Instrumentation;
228 import android.app.Notification;
229 import android.app.NotificationManager;
230 import android.app.PendingIntent;
231 import android.app.PictureInPictureParams;
232 import android.app.ProfilerInfo;
233 import android.app.RemoteAction;
234 import android.app.WaitResult;
235 import android.app.admin.DevicePolicyManager;
236 import android.app.assist.AssistContent;
237 import android.app.assist.AssistStructure;
238 import android.app.backup.IBackupManager;
239 import android.app.usage.UsageEvents;
240 import android.app.usage.UsageStatsManagerInternal;
241 import android.appwidget.AppWidgetManager;
242 import android.content.ActivityNotFoundException;
243 import android.content.BroadcastReceiver;
244 import android.content.ClipData;
245 import android.content.ComponentCallbacks2;
246 import android.content.ComponentName;
247 import android.content.ContentProvider;
248 import android.content.ContentResolver;
249 import android.content.Context;
250 import android.content.DialogInterface;
251 import android.content.IContentProvider;
252 import android.content.IIntentReceiver;
253 import android.content.IIntentSender;
254 import android.content.Intent;
255 import android.content.IntentFilter;
256 import android.content.pm.ActivityInfo;
257 import android.content.pm.ApplicationInfo;
258 import android.content.pm.ConfigurationInfo;
259 import android.content.pm.IPackageDataObserver;
260 import android.content.pm.IPackageManager;
261 import android.content.pm.InstrumentationInfo;
262 import android.content.pm.PackageInfo;
263 import android.content.pm.PackageManager;
264 import android.content.pm.PackageManager.NameNotFoundException;
265 import android.content.pm.PackageManagerInternal;
266 import android.content.pm.ParceledListSlice;
267 import android.content.pm.PathPermission;
268 import android.content.pm.PermissionInfo;
269 import android.content.pm.ProviderInfo;
270 import android.content.pm.ResolveInfo;
271 import android.content.pm.SELinuxUtil;
272 import android.content.pm.ServiceInfo;
273 import android.content.pm.UserInfo;
274 import android.content.res.CompatibilityInfo;
275 import android.content.res.Configuration;
276 import android.content.res.Resources;
277 import android.database.ContentObserver;
278 import android.graphics.Bitmap;
279 import android.graphics.Point;
280 import android.graphics.Rect;
281 import android.location.LocationManager;
282 import android.media.audiofx.AudioEffect;
283 import android.metrics.LogMaker;
284 import android.net.Proxy;
285 import android.net.ProxyInfo;
286 import android.net.Uri;
287 import android.os.BatteryStats;
288 import android.os.Binder;
289 import android.os.Build;
290 import android.os.Bundle;
291 import android.os.Debug;
292 import android.os.DropBoxManager;
293 import android.os.Environment;
294 import android.os.FactoryTest;
295 import android.os.FileObserver;
296 import android.os.FileUtils;
297 import android.os.Handler;
298 import android.os.IBinder;
299 import android.os.IDeviceIdentifiersPolicyService;
300 import android.os.IPermissionController;
301 import android.os.IProcessInfoService;
302 import android.os.IProgressListener;
303 import android.os.LocaleList;
304 import android.os.Looper;
305 import android.os.Message;
306 import android.os.Parcel;
307 import android.os.ParcelFileDescriptor;
308 import android.os.PersistableBundle;
309 import android.os.PowerManager;
310 import android.os.PowerManagerInternal;
311 import android.os.Process;
312 import android.os.RemoteCallbackList;
313 import android.os.RemoteException;
314 import android.os.ResultReceiver;
315 import android.os.ServiceManager;
316 import android.os.ShellCallback;
317 import android.os.StrictMode;
318 import android.os.SystemClock;
319 import android.os.SystemProperties;
320 import android.os.Trace;
321 import android.os.TransactionTooLargeException;
322 import android.os.UpdateLock;
323 import android.os.UserHandle;
324 import android.os.UserManager;
325 import android.os.WorkSource;
326 import android.os.storage.IStorageManager;
327 import android.os.storage.StorageManager;
328 import android.os.storage.StorageManagerInternal;
329 import android.provider.Downloads;
330 import android.provider.Settings;
331 import android.service.voice.IVoiceInteractionSession;
332 import android.service.voice.VoiceInteractionManagerInternal;
333 import android.service.voice.VoiceInteractionSession;
334 import android.telecom.TelecomManager;
335 import android.text.TextUtils;
336 import android.text.format.DateUtils;
337 import android.text.format.Time;
338 import android.text.style.SuggestionSpan;
339 import android.util.ArrayMap;
340 import android.util.ArraySet;
341 import android.util.AtomicFile;
342 import android.util.TimingsTraceLog;
343 import android.util.DebugUtils;
344 import android.util.DisplayMetrics;
345 import android.util.EventLog;
346 import android.util.Log;
347 import android.util.Pair;
348 import android.util.PrintWriterPrinter;
349 import android.util.Slog;
350 import android.util.SparseArray;
351 import android.util.SparseIntArray;
352 import android.util.TimeUtils;
353 import android.util.Xml;
354 import android.view.Gravity;
355 import android.view.LayoutInflater;
356 import android.view.View;
357 import android.view.WindowManager;
359 import com.android.server.job.JobSchedulerInternal;
360 import com.google.android.collect.Lists;
361 import com.google.android.collect.Maps;
363 import com.android.internal.R;
364 import com.android.internal.annotations.GuardedBy;
365 import com.android.internal.annotations.VisibleForTesting;
366 import com.android.internal.app.AssistUtils;
367 import com.android.internal.app.DumpHeapActivity;
368 import com.android.internal.app.IAppOpsCallback;
369 import com.android.internal.app.IAppOpsService;
370 import com.android.internal.app.IVoiceInteractor;
371 import com.android.internal.app.ProcessMap;
372 import com.android.internal.app.SystemUserHomeActivity;
373 import com.android.internal.app.procstats.ProcessStats;
374 import com.android.internal.logging.MetricsLogger;
375 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
376 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
377 import com.android.internal.notification.SystemNotificationChannels;
378 import com.android.internal.os.BackgroundThread;
379 import com.android.internal.os.BatteryStatsImpl;
380 import com.android.internal.os.IResultReceiver;
381 import com.android.internal.os.ProcessCpuTracker;
382 import com.android.internal.os.TransferPipe;
383 import com.android.internal.os.Zygote;
384 import com.android.internal.policy.IKeyguardDismissCallback;
385 import com.android.internal.telephony.TelephonyIntents;
386 import com.android.internal.util.ArrayUtils;
387 import com.android.internal.util.DumpUtils;
388 import com.android.internal.util.FastPrintWriter;
389 import com.android.internal.util.FastXmlSerializer;
390 import com.android.internal.util.MemInfoReader;
391 import com.android.internal.util.Preconditions;
392 import com.android.server.AppOpsService;
393 import com.android.server.AttributeCache;
394 import com.android.server.DeviceIdleController;
395 import com.android.server.IntentResolver;
396 import com.android.server.LocalServices;
397 import com.android.server.LockGuard;
398 import com.android.server.NetworkManagementInternal;
399 import com.android.server.RescueParty;
400 import com.android.server.ServiceThread;
401 import com.android.server.SystemConfig;
402 import com.android.server.SystemService;
403 import com.android.server.SystemServiceManager;
404 import com.android.server.ThreadPriorityBooster;
405 import com.android.server.Watchdog;
406 import com.android.server.am.ActivityStack.ActivityState;
407 import com.android.server.firewall.IntentFirewall;
408 import com.android.server.pm.Installer;
409 import com.android.server.pm.Installer.InstallerException;
410 import com.android.server.statusbar.StatusBarManagerInternal;
411 import com.android.server.vr.VrManagerInternal;
412 import com.android.server.wm.PinnedStackWindowController;
413 import com.android.server.wm.WindowManagerService;
415 import java.text.SimpleDateFormat;
416 import org.xmlpull.v1.XmlPullParser;
417 import org.xmlpull.v1.XmlPullParserException;
418 import org.xmlpull.v1.XmlSerializer;
421 import java.io.FileDescriptor;
422 import java.io.FileInputStream;
423 import java.io.FileNotFoundException;
424 import java.io.FileOutputStream;
425 import java.io.IOException;
426 import java.io.InputStreamReader;
427 import java.io.PrintWriter;
428 import java.io.StringWriter;
429 import java.io.UnsupportedEncodingException;
430 import java.lang.ref.WeakReference;
431 import java.nio.charset.StandardCharsets;
432 import java.text.DateFormat;
433 import java.util.ArrayList;
434 import java.util.Arrays;
435 import java.util.Collections;
436 import java.util.Comparator;
437 import java.util.Date;
438 import java.util.HashMap;
439 import java.util.HashSet;
440 import java.util.Iterator;
441 import java.util.List;
442 import java.util.Locale;
443 import java.util.Map;
444 import java.util.Objects;
445 import java.util.Set;
446 import java.util.concurrent.CountDownLatch;
447 import java.util.concurrent.atomic.AtomicBoolean;
448 import java.util.concurrent.atomic.AtomicLong;
450 import dalvik.system.VMRuntime;
451 import libcore.io.IoUtils;
452 import libcore.util.EmptyArray;
454 public class ActivityManagerService extends IActivityManager.Stub
455 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
458 * Priority we boost main thread and RT of top app to.
460 public static final int TOP_APP_PRIORITY_BOOST = -10;
462 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
463 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
464 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
465 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
466 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
467 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
468 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
469 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
470 private static final String TAG_LRU = TAG + POSTFIX_LRU;
471 private static final String TAG_MU = TAG + POSTFIX_MU;
472 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
473 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
474 private static final String TAG_POWER = TAG + POSTFIX_POWER;
475 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
476 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
477 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
478 private static final String TAG_PSS = TAG + POSTFIX_PSS;
479 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
480 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
481 private static final String TAG_STACK = TAG + POSTFIX_STACK;
482 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
483 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
484 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
485 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
487 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
488 // here so that while the job scheduler can depend on AMS, the other way around
489 // need not be the case.
490 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
492 /** Control over CPU and battery monitoring */
493 // write battery stats every 30 minutes.
494 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
495 static final boolean MONITOR_CPU_USAGE = true;
496 // don't sample cpu less than every 5 seconds.
497 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
498 // wait possibly forever for next cpu sample.
499 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
500 static final boolean MONITOR_THREAD_CPU_USAGE = false;
502 // The flags that are set for all calls we make to the package manager.
503 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
505 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
507 // Amount of time after a call to stopAppSwitches() during which we will
508 // prevent further untrusted switches from happening.
509 static final long APP_SWITCH_DELAY_TIME = 5*1000;
511 // How long we wait for a launched process to attach to the activity manager
512 // before we decide it's never going to come up for real.
513 static final int PROC_START_TIMEOUT = 10*1000;
514 // How long we wait for an attached process to publish its content providers
515 // before we decide it must be hung.
516 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
518 // How long we wait for a launched process to attach to the activity manager
519 // before we decide it's never going to come up for real, when the process was
520 // started with a wrapper for instrumentation (such as Valgrind) because it
521 // could take much longer than usual.
522 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
524 // How long we allow a receiver to run before giving up on it.
525 static final int BROADCAST_FG_TIMEOUT = 10*1000;
526 static final int BROADCAST_BG_TIMEOUT = 60*1000;
528 // How long we wait until we timeout on key dispatching.
529 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
531 // How long we wait until we timeout on key dispatching during instrumentation.
532 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
534 // How long to wait in getAssistContextExtras for the activity and foreground services
535 // to respond with the result.
536 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
538 // How long top wait when going through the modern assist (which doesn't need to block
539 // on getting this result before starting to launch its UI).
540 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
542 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
543 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
545 // Maximum number of persisted Uri grants a package is allowed
546 static final int MAX_PERSISTED_URI_GRANTS = 128;
548 static final int MY_PID = myPid();
550 static final String[] EMPTY_STRING_ARRAY = new String[0];
552 // How many bytes to write into the dropbox log before truncating
553 static final int DROPBOX_MAX_SIZE = 192 * 1024;
554 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
555 // as one line, but close enough for now.
556 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
558 // Access modes for handleIncomingUser.
559 static final int ALLOW_NON_FULL = 0;
560 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
561 static final int ALLOW_FULL_ONLY = 2;
563 // Necessary ApplicationInfo flags to mark an app as persistent
564 private static final int PERSISTENT_MASK =
565 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
567 // Intent sent when remote bugreport collection has been completed
568 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
569 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
571 // Used to indicate that an app transition should be animated.
572 static final boolean ANIMATE = true;
574 // Determines whether to take full screen screenshots
575 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
578 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
580 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
583 * State indicating that there is no need for any blocking for network.
586 static final int NETWORK_STATE_NO_CHANGE = 0;
589 * State indicating that the main thread needs to be informed about the network wait.
592 static final int NETWORK_STATE_BLOCK = 1;
595 * State indicating that any threads waiting for network state to get updated can be unblocked.
598 static final int NETWORK_STATE_UNBLOCK = 2;
600 // Max character limit for a notification title. If the notification title is larger than this
601 // the notification will not be legible to the user.
602 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
604 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
606 /** All system services */
607 SystemServiceManager mSystemServiceManager;
608 AssistUtils mAssistUtils;
610 private Installer mInstaller;
612 /** Run all ActivityStacks through this */
613 final ActivityStackSupervisor mStackSupervisor;
614 private final KeyguardController mKeyguardController;
616 final ActivityStarter mActivityStarter;
618 final TaskChangeNotificationController mTaskChangeNotificationController;
620 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
622 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
624 public final IntentFirewall mIntentFirewall;
626 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
627 // default action automatically. Important for devices without direct input
629 private boolean mShowDialogs = true;
631 private final VrController mVrController;
633 // VR Vr2d Display Id.
634 int mVr2dDisplayId = INVALID_DISPLAY;
636 // Whether we should use SCHED_FIFO for UI and RenderThreads.
637 private boolean mUseFifoUiScheduling = false;
639 BroadcastQueue mFgBroadcastQueue;
640 BroadcastQueue mBgBroadcastQueue;
641 // Convenient for easy iteration over the queues. Foreground is first
642 // so that dispatch of foreground broadcasts gets precedence.
643 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
645 BroadcastStats mLastBroadcastStats;
646 BroadcastStats mCurBroadcastStats;
648 BroadcastQueue broadcastQueueForIntent(Intent intent) {
649 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
650 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
651 "Broadcast intent " + intent + " on "
652 + (isFg ? "foreground" : "background") + " queue");
653 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
657 * The last resumed activity. This is identical to the current resumed activity most
658 * of the time but could be different when we're pausing one activity before we resume
661 private ActivityRecord mLastResumedActivity;
664 * If non-null, we are tracking the time the user spends in the currently focused app.
666 private AppTimeTracker mCurAppTimeTracker;
669 * List of intents that were used to start the most recent tasks.
671 final RecentTasks mRecentTasks;
674 * For addAppTask: cached of the last activity component that was added.
676 ComponentName mLastAddedTaskComponent;
679 * For addAppTask: cached of the last activity uid that was added.
681 int mLastAddedTaskUid;
684 * For addAppTask: cached of the last ActivityInfo that was added.
686 ActivityInfo mLastAddedTaskActivity;
689 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
691 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
694 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
696 String mDeviceOwnerName;
698 final UserController mUserController;
700 final AppErrors mAppErrors;
703 * Dump of the activity state at the time of the last ANR. Cleared after
704 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
706 String mLastANRState;
709 * Indicates the maximum time spent waiting for the network rules to get updated.
712 long mWaitForNetworkTimeoutMs;
714 public boolean canShowErrorDialogs() {
715 return mShowDialogs && !mSleeping && !mShuttingDown
716 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
717 && !(UserManager.isDeviceInDemoMode(mContext)
718 && mUserController.getCurrentUser().isDemo());
721 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
722 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
724 static void boostPriorityForLockedSection() {
725 sThreadPriorityBooster.boost();
728 static void resetPriorityAfterLockedSection() {
729 sThreadPriorityBooster.reset();
732 public class PendingAssistExtras extends Binder implements Runnable {
733 public final ActivityRecord activity;
734 public boolean isHome;
735 public final Bundle extras;
736 public final Intent intent;
737 public final String hint;
738 public final IResultReceiver receiver;
739 public final int userHandle;
740 public boolean haveResult = false;
741 public Bundle result = null;
742 public AssistStructure structure = null;
743 public AssistContent content = null;
744 public Bundle receiverExtras;
746 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
747 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
748 activity = _activity;
752 receiver = _receiver;
753 receiverExtras = _receiverExtras;
754 userHandle = _userHandle;
759 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
760 synchronized (this) {
764 pendingAssistExtrasTimedOut(this);
768 final ArrayList<PendingAssistExtras> mPendingAssistExtras
769 = new ArrayList<PendingAssistExtras>();
772 * Process management.
774 final ProcessList mProcessList = new ProcessList();
777 * All of the applications we currently have running organized by name.
778 * The keys are strings of the application package name (as
779 * returned by the package manager), and the keys are ApplicationRecord
782 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
785 * Tracking long-term execution of processes to look for abuse and other
788 final ProcessStatsService mProcessStats;
791 * The currently running isolated processes.
793 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
796 * Counter for assigning isolated process uids, to avoid frequently reusing the
799 int mNextIsolatedProcessUid = 0;
802 * The currently running heavy-weight process, if any.
804 ProcessRecord mHeavyWeightProcess = null;
807 * Non-persistent appId whitelist for background restrictions
809 int[] mBackgroundAppIdWhitelist = new int[] {
814 * Broadcast actions that will always be deliverable to unlaunched/background apps
816 ArraySet<String> mBackgroundLaunchBroadcasts;
819 * All of the processes we currently have running organized by pid.
820 * The keys are the pid running the application.
822 * <p>NOTE: This object is protected by its own lock, NOT the global
823 * activity manager lock!
825 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
828 * All of the processes that have been forced to be important. The key
829 * is the pid of the caller who requested it (we hold a death
832 abstract class ImportanceToken implements IBinder.DeathRecipient {
837 ImportanceToken(int _pid, IBinder _token, String _reason) {
844 public String toString() {
845 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
846 + " " + reason + " " + pid + " " + token + " }";
849 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
852 * List of records for processes that someone had tried to start before the
853 * system was ready. We don't start them at that point, but ensure they
854 * are started by the time booting is complete.
856 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
859 * List of persistent applications that are in the process
862 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
865 * Processes that are being forcibly torn down.
867 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
870 * List of running applications, sorted by recent usage.
871 * The first entry in the list is the least recently used.
873 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
876 * Where in mLruProcesses that the processes hosting activities start.
878 int mLruProcessActivityStart = 0;
881 * Where in mLruProcesses that the processes hosting services start.
882 * This is after (lower index) than mLruProcessesActivityStart.
884 int mLruProcessServiceStart = 0;
887 * List of processes that should gc as soon as things are idle.
889 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
892 * Processes we want to collect PSS data from.
894 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
896 private boolean mBinderTransactionTrackingEnabled = false;
899 * Last time we requested PSS data of all processes.
901 long mLastFullPssTime = SystemClock.uptimeMillis();
904 * If set, the next time we collect PSS data we should do a full collection
905 * with data from native processes and the kernel.
907 boolean mFullPssPending = false;
910 * This is the process holding what we currently consider to be
911 * the "home" activity.
913 ProcessRecord mHomeProcess;
916 * This is the process holding the activity the user last visited that
917 * is in a different process from the one they are currently in.
919 ProcessRecord mPreviousProcess;
922 * The time at which the previous process was last visible.
924 long mPreviousProcessVisibleTime;
927 * Track all uids that have actively running processes.
929 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
932 * This is for verifying the UID report flow.
934 static final boolean VALIDATE_UID_STATES = true;
935 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
938 * Packages that the user has asked to have run in screen size
939 * compatibility mode instead of filling the screen.
941 final CompatModePackages mCompatModePackages;
944 * Set of IntentSenderRecord objects that are currently active.
946 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
947 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
950 * Fingerprints (hashCode()) of stack traces that we've
951 * already logged DropBox entries for. Guarded by itself. If
952 * something (rogue user app) forces this over
953 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
955 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
956 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
959 * Strict Mode background batched logging state.
961 * The string buffer is guarded by itself, and its lock is also
962 * used to determine if another batched write is already
965 private final StringBuilder mStrictModeBuffer = new StringBuilder();
968 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
969 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
971 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
974 * Resolver for broadcast intents to registered receivers.
975 * Holds BroadcastFilter (subclass of IntentFilter).
977 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
978 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
980 protected boolean allowFilterResult(
981 BroadcastFilter filter, List<BroadcastFilter> dest) {
982 IBinder target = filter.receiverList.receiver.asBinder();
983 for (int i = dest.size() - 1; i >= 0; i--) {
984 if (dest.get(i).receiverList.receiver.asBinder() == target) {
992 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
993 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
994 || userId == filter.owningUserId) {
995 return super.newResult(filter, match, userId);
1001 protected BroadcastFilter[] newArray(int size) {
1002 return new BroadcastFilter[size];
1006 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1007 return packageName.equals(filter.packageName);
1012 * State of all active sticky broadcasts per user. Keys are the action of the
1013 * sticky Intent, values are an ArrayList of all broadcasted intents with
1014 * that action (which should usually be one). The SparseArray is keyed
1015 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1016 * for stickies that are sent to all users.
1018 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1019 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1021 final ActiveServices mServices;
1023 final static class Association {
1024 final int mSourceUid;
1025 final String mSourceProcess;
1026 final int mTargetUid;
1027 final ComponentName mTargetComponent;
1028 final String mTargetProcess;
1036 // states of the source process when the bind occurred.
1037 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1038 long mLastStateUptime;
1039 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1040 - ActivityManager.MIN_PROCESS_STATE+1];
1042 Association(int sourceUid, String sourceProcess, int targetUid,
1043 ComponentName targetComponent, String targetProcess) {
1044 mSourceUid = sourceUid;
1045 mSourceProcess = sourceProcess;
1046 mTargetUid = targetUid;
1047 mTargetComponent = targetComponent;
1048 mTargetProcess = targetProcess;
1053 * When service association tracking is enabled, this is all of the associations we
1054 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1055 * -> association data.
1057 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1058 mAssociations = new SparseArray<>();
1059 boolean mTrackingAssociations;
1062 * Backup/restore process management
1064 String mBackupAppName = null;
1065 BackupRecord mBackupTarget = null;
1067 final ProviderMap mProviderMap;
1070 * List of content providers who have clients waiting for them. The
1071 * application is currently being launched and the provider will be
1072 * removed from this list once it is published.
1074 final ArrayList<ContentProviderRecord> mLaunchingProviders
1075 = new ArrayList<ContentProviderRecord>();
1078 * File storing persisted {@link #mGrantedUriPermissions}.
1080 private final AtomicFile mGrantFile;
1082 /** XML constants used in {@link #mGrantFile} */
1083 private static final String TAG_URI_GRANTS = "uri-grants";
1084 private static final String TAG_URI_GRANT = "uri-grant";
1085 private static final String ATTR_USER_HANDLE = "userHandle";
1086 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1087 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1088 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1089 private static final String ATTR_TARGET_PKG = "targetPkg";
1090 private static final String ATTR_URI = "uri";
1091 private static final String ATTR_MODE_FLAGS = "modeFlags";
1092 private static final String ATTR_CREATED_TIME = "createdTime";
1093 private static final String ATTR_PREFIX = "prefix";
1096 * Global set of specific {@link Uri} permissions that have been granted.
1097 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1098 * to {@link UriPermission#uri} to {@link UriPermission}.
1101 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1102 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1104 public static class GrantUri {
1105 public final int sourceUserId;
1106 public final Uri uri;
1107 public boolean prefix;
1109 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1110 this.sourceUserId = sourceUserId;
1112 this.prefix = prefix;
1116 public int hashCode() {
1118 hashCode = 31 * hashCode + sourceUserId;
1119 hashCode = 31 * hashCode + uri.hashCode();
1120 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1125 public boolean equals(Object o) {
1126 if (o instanceof GrantUri) {
1127 GrantUri other = (GrantUri) o;
1128 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1129 && prefix == other.prefix;
1135 public String toString() {
1136 String result = uri.toString() + " [user " + sourceUserId + "]";
1137 if (prefix) result += " [prefix]";
1141 public String toSafeString() {
1142 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1143 if (prefix) result += " [prefix]";
1147 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1148 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1149 ContentProvider.getUriWithoutUserId(uri), false);
1153 CoreSettingsObserver mCoreSettingsObserver;
1155 FontScaleSettingObserver mFontScaleSettingObserver;
1157 private final class FontScaleSettingObserver extends ContentObserver {
1158 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1160 public FontScaleSettingObserver() {
1162 ContentResolver resolver = mContext.getContentResolver();
1163 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1167 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1168 if (mFontScaleUri.equals(uri)) {
1169 updateFontScaleIfNeeded(userId);
1175 * Thread-local storage used to carry caller permissions over through
1176 * indirect content-provider access.
1178 private class Identity {
1179 public final IBinder token;
1180 public final int pid;
1181 public final int uid;
1183 Identity(IBinder _token, int _pid, int _uid) {
1190 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1193 * All information we have collected about the runtime performance of
1194 * any user id that can impact battery performance.
1196 final BatteryStatsService mBatteryStatsService;
1199 * Information about component usage
1201 UsageStatsManagerInternal mUsageStatsService;
1204 * Access to DeviceIdleController service.
1206 DeviceIdleController.LocalService mLocalDeviceIdleController;
1209 * Set of app ids that are whitelisted for device idle and thus background check.
1211 int[] mDeviceIdleWhitelist = new int[0];
1214 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1216 int[] mDeviceIdleTempWhitelist = new int[0];
1218 static final class PendingTempWhitelist {
1219 final int targetUid;
1220 final long duration;
1223 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1224 targetUid = _targetUid;
1225 duration = _duration;
1230 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1233 * Information about and control over application operations
1235 final AppOpsService mAppOpsService;
1237 /** Current sequencing integer of the configuration, for skipping old configurations. */
1238 private int mConfigurationSeq;
1241 * Temp object used when global and/or display override configuration is updated. It is also
1242 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1245 private Configuration mTempConfig = new Configuration();
1247 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1248 new UpdateConfigurationResult();
1249 private static final class UpdateConfigurationResult {
1250 // Configuration changes that were updated.
1252 // If the activity was relaunched to match the new configuration.
1253 boolean activityRelaunched;
1257 activityRelaunched = false;
1261 boolean mSuppressResizeConfigChanges;
1264 * Hardware-reported OpenGLES version.
1266 final int GL_ES_VERSION;
1269 * List of initialization arguments to pass to all processes when binding applications to them.
1270 * For example, references to the commonly used services.
1272 HashMap<String, IBinder> mAppBindArgs;
1273 HashMap<String, IBinder> mIsolatedAppBindArgs;
1276 * Temporary to avoid allocations. Protected by main lock.
1278 final StringBuilder mStringBuilder = new StringBuilder(256);
1281 * Used to control how we initialize the service.
1283 ComponentName mTopComponent;
1284 String mTopAction = Intent.ACTION_MAIN;
1287 volatile boolean mProcessesReady = false;
1288 volatile boolean mSystemReady = false;
1289 volatile boolean mOnBattery = false;
1290 volatile int mFactoryTest;
1292 @GuardedBy("this") boolean mBooting = false;
1293 @GuardedBy("this") boolean mCallFinishBooting = false;
1294 @GuardedBy("this") boolean mBootAnimationComplete = false;
1295 @GuardedBy("this") boolean mLaunchWarningShown = false;
1296 @GuardedBy("this") boolean mCheckedForSetup = false;
1298 final Context mContext;
1301 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1302 * change at runtime. Use mContext for non-UI purposes.
1304 final Context mUiContext;
1307 * The time at which we will allow normal application switches again,
1308 * after a call to {@link #stopAppSwitches()}.
1310 long mAppSwitchesAllowedTime;
1313 * This is set to true after the first switch after mAppSwitchesAllowedTime
1314 * is set; any switches after that will clear the time.
1316 boolean mDidAppSwitch;
1319 * Last time (in uptime) at which we checked for power usage.
1321 long mLastPowerCheckUptime;
1324 * Set while we are wanting to sleep, to prevent any
1325 * activities from being started/resumed.
1327 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1329 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1330 * while in the sleep state until there is a pending transition out of sleep, in which case
1331 * mSleeping is set to false, and remains false while awake.
1333 * Whether mSleeping can quickly toggled between true/false without the device actually
1334 * display changing states is undefined.
1336 private boolean mSleeping = false;
1339 * The process state used for processes that are running the top activities.
1340 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1342 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1345 * Set while we are running a voice interaction. This overrides
1346 * sleeping while it is active.
1348 IVoiceInteractionSession mRunningVoice;
1351 * For some direct access we need to power manager.
1353 PowerManagerInternal mLocalPowerManager;
1356 * We want to hold a wake lock while running a voice interaction session, since
1357 * this may happen with the screen off and we need to keep the CPU running to
1358 * be able to continue to interact with the user.
1360 PowerManager.WakeLock mVoiceWakeLock;
1363 * State of external calls telling us if the device is awake or asleep.
1365 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1368 * Set if we are shutting down the system, similar to sleeping.
1370 boolean mShuttingDown = false;
1373 * Current sequence id for oom_adj computation traversal.
1378 * Current sequence id for process LRU updating.
1383 * Keep track of the non-cached/empty process we last found, to help
1384 * determine how to distribute cached/empty processes next time.
1386 int mNumNonCachedProcs = 0;
1389 * Keep track of the number of cached hidden procs, to balance oom adj
1390 * distribution between those and empty procs.
1392 int mNumCachedHiddenProcs = 0;
1395 * Keep track of the number of service processes we last found, to
1396 * determine on the next iteration which should be B services.
1398 int mNumServiceProcs = 0;
1399 int mNewNumAServiceProcs = 0;
1400 int mNewNumServiceProcs = 0;
1403 * Allow the current computed overall memory level of the system to go down?
1404 * This is set to false when we are killing processes for reasons other than
1405 * memory management, so that the now smaller process list will not be taken as
1406 * an indication that memory is tighter.
1408 boolean mAllowLowerMemLevel = false;
1411 * The last computed memory level, for holding when we are in a state that
1412 * processes are going away for other reasons.
1414 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1417 * The last total number of process we have, to determine if changes actually look
1418 * like a shrinking number of process due to lower RAM.
1420 int mLastNumProcesses;
1423 * The uptime of the last time we performed idle maintenance.
1425 long mLastIdleTime = SystemClock.uptimeMillis();
1428 * Total time spent with RAM that has been added in the past since the last idle time.
1430 long mLowRamTimeSinceLastIdle = 0;
1433 * If RAM is currently low, when that horrible situation started.
1435 long mLowRamStartTime = 0;
1438 * For reporting to battery stats the current top application.
1440 private String mCurResumedPackage = null;
1441 private int mCurResumedUid = -1;
1444 * For reporting to battery stats the apps currently running foreground
1445 * service. The ProcessMap is package/uid tuples; each of these contain
1446 * an array of the currently foreground processes.
1448 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1449 = new ProcessMap<ArrayList<ProcessRecord>>();
1452 * Set if the systemServer made a call to enterSafeMode.
1457 * If true, we are running under a test environment so will sample PSS from processes
1458 * much more rapidly to try to collect better data when the tests are rapidly
1459 * running through apps.
1461 boolean mTestPssMode = false;
1463 String mDebugApp = null;
1464 boolean mWaitForDebugger = false;
1465 boolean mDebugTransient = false;
1466 String mOrigDebugApp = null;
1467 boolean mOrigWaitForDebugger = false;
1468 boolean mAlwaysFinishActivities = false;
1469 boolean mForceResizableActivities;
1471 * Flag that indicates if multi-window is enabled.
1473 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1474 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1475 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1476 * At least one of the forms of multi-window must be enabled in order for this flag to be
1477 * initialized to 'true'.
1479 * @see #mSupportsSplitScreenMultiWindow
1480 * @see #mSupportsFreeformWindowManagement
1481 * @see #mSupportsPictureInPicture
1482 * @see #mSupportsMultiDisplay
1484 boolean mSupportsMultiWindow;
1485 boolean mSupportsSplitScreenMultiWindow;
1486 boolean mSupportsFreeformWindowManagement;
1487 boolean mSupportsPictureInPicture;
1488 boolean mSupportsMultiDisplay;
1489 boolean mSupportsLeanbackOnly;
1490 IActivityController mController = null;
1491 boolean mControllerIsAMonkey = false;
1492 String mProfileApp = null;
1493 ProcessRecord mProfileProc = null;
1494 ProfilerInfo mProfilerInfo = null;
1495 int mProfileType = 0;
1496 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1497 String mMemWatchDumpProcName;
1498 String mMemWatchDumpFile;
1499 int mMemWatchDumpPid;
1500 int mMemWatchDumpUid;
1501 String mTrackAllocationApp = null;
1502 String mNativeDebuggingApp = null;
1504 final long[] mTmpLong = new long[2];
1506 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1509 * A global counter for generating sequence numbers.
1510 * This value will be used when incrementing sequence numbers in individual uidRecords.
1512 * Having a global counter ensures that seq numbers are monotonically increasing for a
1513 * particular uid even when the uidRecord is re-created.
1517 long mProcStateSeqCounter = 0;
1519 private final Injector mInjector;
1521 static final class ProcessChangeItem {
1522 static final int CHANGE_ACTIVITIES = 1<<0;
1527 boolean foregroundActivities;
1530 static final class UidObserverRegistration {
1536 final SparseIntArray lastProcStates;
1538 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1542 cutpoint = _cutpoint;
1543 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1544 lastProcStates = new SparseIntArray();
1546 lastProcStates = null;
1551 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1552 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1554 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1555 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1557 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1558 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1560 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1561 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1563 OomAdjObserver mCurOomAdjObserver;
1566 interface OomAdjObserver {
1567 void onOomAdjMessage(String msg);
1571 * Runtime CPU use collection thread. This object's lock is used to
1572 * perform synchronization with the thread (notifying it to run).
1574 final Thread mProcessCpuThread;
1577 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1578 * Must acquire this object's lock when accessing it.
1579 * NOTE: this lock will be held while doing long operations (trawling
1580 * through all processes in /proc), so it should never be acquired by
1581 * any critical paths such as when holding the main activity manager lock.
1583 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1584 MONITOR_THREAD_CPU_USAGE);
1585 final AtomicLong mLastCpuTime = new AtomicLong(0);
1586 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1587 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1589 long mLastWriteTime = 0;
1592 * Used to retain an update lock when the foreground activity is in
1595 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1598 * Set to true after the system has finished booting.
1600 boolean mBooted = false;
1602 WindowManagerService mWindowManager;
1603 final ActivityThread mSystemThread;
1605 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1606 final ProcessRecord mApp;
1608 final IApplicationThread mAppThread;
1610 AppDeathRecipient(ProcessRecord app, int pid,
1611 IApplicationThread thread) {
1612 if (DEBUG_ALL) Slog.v(
1613 TAG, "New death recipient " + this
1614 + " for thread " + thread.asBinder());
1617 mAppThread = thread;
1621 public void binderDied() {
1622 if (DEBUG_ALL) Slog.v(
1623 TAG, "Death received in " + this
1624 + " for thread " + mAppThread.asBinder());
1625 synchronized(ActivityManagerService.this) {
1626 appDiedLocked(mApp, mPid, mAppThread, true);
1631 static final int SHOW_ERROR_UI_MSG = 1;
1632 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1633 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1634 static final int UPDATE_CONFIGURATION_MSG = 4;
1635 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1636 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1637 static final int SERVICE_TIMEOUT_MSG = 12;
1638 static final int UPDATE_TIME_ZONE = 13;
1639 static final int SHOW_UID_ERROR_UI_MSG = 14;
1640 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1641 static final int PROC_START_TIMEOUT_MSG = 20;
1642 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1643 static final int KILL_APPLICATION_MSG = 22;
1644 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1645 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1646 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1647 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1648 static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1649 static final int CLEAR_DNS_CACHE_MSG = 28;
1650 static final int UPDATE_HTTP_PROXY_MSG = 29;
1651 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1652 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1653 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1654 static final int REPORT_MEM_USAGE_MSG = 33;
1655 static final int REPORT_USER_SWITCH_MSG = 34;
1656 static final int CONTINUE_USER_SWITCH_MSG = 35;
1657 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1658 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1659 static final int PERSIST_URI_GRANTS_MSG = 38;
1660 static final int REQUEST_ALL_PSS_MSG = 39;
1661 static final int START_PROFILES_MSG = 40;
1662 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1663 static final int SYSTEM_USER_START_MSG = 42;
1664 static final int SYSTEM_USER_CURRENT_MSG = 43;
1665 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1666 static final int FINISH_BOOTING_MSG = 45;
1667 static final int START_USER_SWITCH_UI_MSG = 46;
1668 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1669 static final int DISMISS_DIALOG_UI_MSG = 48;
1670 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1671 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1672 static final int DELETE_DUMPHEAP_MSG = 51;
1673 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1674 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1675 static final int REPORT_TIME_TRACKER_MSG = 54;
1676 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1677 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1678 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1679 static final int IDLE_UIDS_MSG = 58;
1680 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1681 static final int LOG_STACK_STATE = 60;
1682 static final int VR_MODE_CHANGE_MSG = 61;
1683 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1684 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1685 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1686 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1687 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1688 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1689 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1690 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1691 static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1692 static final int START_USER_SWITCH_FG_MSG = 712;
1693 static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1695 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1696 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1697 static final int FIRST_COMPAT_MODE_MSG = 300;
1698 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1700 static ServiceThread sKillThread = null;
1701 static KillHandler sKillHandler = null;
1703 CompatModeDialog mCompatModeDialog;
1704 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1705 long mLastMemUsageReportTime = 0;
1708 * Flag whether the current user is a "monkey", i.e. whether
1709 * the UI is driven by a UI automation tool.
1711 private boolean mUserIsMonkey;
1713 /** Flag whether the device has a Recents UI */
1714 boolean mHasRecents;
1716 /** The dimensions of the thumbnails in the Recents UI. */
1717 int mThumbnailWidth;
1718 int mThumbnailHeight;
1719 float mFullscreenThumbnailScale;
1721 final ServiceThread mHandlerThread;
1722 final MainHandler mHandler;
1723 final Handler mUiHandler;
1725 final ActivityManagerConstants mConstants;
1727 PackageManagerInternal mPackageManagerInt;
1729 // VoiceInteraction session ID that changes for each new request except when
1730 // being called for multiwindow assist in a single session.
1731 private int mViSessionId = 1000;
1733 final boolean mPermissionReviewRequired;
1735 private static String sTheRealBuildSerial = Build.UNKNOWN;
1738 * Current global configuration information. Contains general settings for the entire system,
1739 * also corresponds to the merged configuration of the default display.
1741 Configuration getGlobalConfiguration() {
1742 return mStackSupervisor.getConfiguration();
1745 final class KillHandler extends Handler {
1746 static final int KILL_PROCESS_GROUP_MSG = 4000;
1748 public KillHandler(Looper looper) {
1749 super(looper, null, true);
1753 public void handleMessage(Message msg) {
1755 case KILL_PROCESS_GROUP_MSG:
1757 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1758 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1759 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1764 super.handleMessage(msg);
1769 final class UiHandler extends Handler {
1770 public UiHandler() {
1771 super(com.android.server.UiThread.get().getLooper(), null, true);
1775 public void handleMessage(Message msg) {
1777 case SHOW_ERROR_UI_MSG: {
1778 mAppErrors.handleShowAppErrorUi(msg);
1779 ensureBootCompleted();
1781 case SHOW_NOT_RESPONDING_UI_MSG: {
1782 mAppErrors.handleShowAnrUi(msg);
1783 ensureBootCompleted();
1785 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1786 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1787 synchronized (ActivityManagerService.this) {
1788 ProcessRecord proc = (ProcessRecord) data.get("app");
1790 Slog.e(TAG, "App not found when showing strict mode dialog.");
1793 if (proc.crashDialog != null) {
1794 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1797 AppErrorResult res = (AppErrorResult) data.get("result");
1798 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1799 Dialog d = new StrictModeViolationDialog(mUiContext,
1800 ActivityManagerService.this, res, proc);
1802 proc.crashDialog = d;
1804 // The device is asleep, so just pretend that the user
1805 // saw a crash dialog and hit "force quit".
1809 ensureBootCompleted();
1811 case SHOW_FACTORY_ERROR_UI_MSG: {
1812 Dialog d = new FactoryErrorDialog(
1813 mUiContext, msg.getData().getCharSequence("msg"));
1815 ensureBootCompleted();
1817 case WAIT_FOR_DEBUGGER_UI_MSG: {
1818 synchronized (ActivityManagerService.this) {
1819 ProcessRecord app = (ProcessRecord)msg.obj;
1820 if (msg.arg1 != 0) {
1821 if (!app.waitedForDebugger) {
1822 Dialog d = new AppWaitingForDebuggerDialog(
1823 ActivityManagerService.this,
1826 app.waitedForDebugger = true;
1830 if (app.waitDialog != null) {
1831 app.waitDialog.dismiss();
1832 app.waitDialog = null;
1837 case SHOW_UID_ERROR_UI_MSG: {
1839 AlertDialog d = new BaseErrorDialog(mUiContext);
1840 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1841 d.setCancelable(false);
1842 d.setTitle(mUiContext.getText(R.string.android_system_label));
1843 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1844 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1845 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1849 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1851 AlertDialog d = new BaseErrorDialog(mUiContext);
1852 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1853 d.setCancelable(false);
1854 d.setTitle(mUiContext.getText(R.string.android_system_label));
1855 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1856 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1857 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1861 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1862 synchronized (ActivityManagerService.this) {
1863 ActivityRecord ar = (ActivityRecord) msg.obj;
1864 if (mCompatModeDialog != null) {
1865 if (mCompatModeDialog.mAppInfo.packageName.equals(
1866 ar.info.applicationInfo.packageName)) {
1869 mCompatModeDialog.dismiss();
1870 mCompatModeDialog = null;
1872 if (ar != null && false) {
1873 if (mCompatModePackages.getPackageAskCompatModeLocked(
1875 int mode = mCompatModePackages.computeCompatModeLocked(
1876 ar.info.applicationInfo);
1877 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1878 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1879 mCompatModeDialog = new CompatModeDialog(
1880 ActivityManagerService.this, mUiContext,
1881 ar.info.applicationInfo);
1882 mCompatModeDialog.show();
1889 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1890 synchronized (ActivityManagerService.this) {
1891 final ActivityRecord ar = (ActivityRecord) msg.obj;
1892 if (mUnsupportedDisplaySizeDialog != null) {
1893 mUnsupportedDisplaySizeDialog.dismiss();
1894 mUnsupportedDisplaySizeDialog = null;
1896 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1898 // TODO(multi-display): Show dialog on appropriate display.
1899 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1900 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1901 mUnsupportedDisplaySizeDialog.show();
1906 case START_USER_SWITCH_UI_MSG: {
1907 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1910 case DISMISS_DIALOG_UI_MSG: {
1911 final Dialog d = (Dialog) msg.obj;
1915 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1916 dispatchProcessesChanged();
1919 case DISPATCH_PROCESS_DIED_UI_MSG: {
1920 final int pid = msg.arg1;
1921 final int uid = msg.arg2;
1922 dispatchProcessDied(pid, uid);
1925 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1926 dispatchUidsChanged();
1928 case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1929 dispatchOomAdjObserver((String)msg.obj);
1931 case PUSH_TEMP_WHITELIST_UI_MSG: {
1932 pushTempWhitelist();
1938 final class MainHandler extends Handler {
1939 public MainHandler(Looper looper) {
1940 super(looper, null, true);
1944 public void handleMessage(Message msg) {
1946 case UPDATE_CONFIGURATION_MSG: {
1947 final ContentResolver resolver = mContext.getContentResolver();
1948 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1951 case GC_BACKGROUND_PROCESSES_MSG: {
1952 synchronized (ActivityManagerService.this) {
1953 performAppGcsIfAppropriateLocked();
1956 case SERVICE_TIMEOUT_MSG: {
1957 mServices.serviceTimeout((ProcessRecord)msg.obj);
1959 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1960 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1962 case SERVICE_FOREGROUND_CRASH_MSG: {
1963 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1965 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1966 RemoteCallbackList<IResultReceiver> callbacks
1967 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1968 int N = callbacks.beginBroadcast();
1969 for (int i = 0; i < N; i++) {
1971 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1972 } catch (RemoteException e) {
1975 callbacks.finishBroadcast();
1977 case UPDATE_TIME_ZONE: {
1978 synchronized (ActivityManagerService.this) {
1979 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1980 ProcessRecord r = mLruProcesses.get(i);
1981 if (r.thread != null) {
1983 r.thread.updateTimeZone();
1984 } catch (RemoteException ex) {
1985 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1991 case CLEAR_DNS_CACHE_MSG: {
1992 synchronized (ActivityManagerService.this) {
1993 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1994 ProcessRecord r = mLruProcesses.get(i);
1995 if (r.thread != null) {
1997 r.thread.clearDnsCache();
1998 } catch (RemoteException ex) {
1999 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2005 case UPDATE_HTTP_PROXY_MSG: {
2006 ProxyInfo proxy = (ProxyInfo)msg.obj;
2009 String exclList = "";
2010 Uri pacFileUrl = Uri.EMPTY;
2011 if (proxy != null) {
2012 host = proxy.getHost();
2013 port = Integer.toString(proxy.getPort());
2014 exclList = proxy.getExclusionListAsString();
2015 pacFileUrl = proxy.getPacFileUrl();
2017 synchronized (ActivityManagerService.this) {
2018 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2019 ProcessRecord r = mLruProcesses.get(i);
2020 if (r.thread != null) {
2022 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2023 } catch (RemoteException ex) {
2024 Slog.w(TAG, "Failed to update http proxy for: " +
2025 r.info.processName);
2031 case PROC_START_TIMEOUT_MSG: {
2032 ProcessRecord app = (ProcessRecord)msg.obj;
2033 synchronized (ActivityManagerService.this) {
2034 processStartTimedOutLocked(app);
2037 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2038 ProcessRecord app = (ProcessRecord)msg.obj;
2039 synchronized (ActivityManagerService.this) {
2040 processContentProviderPublishTimedOutLocked(app);
2043 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2044 synchronized (ActivityManagerService.this) {
2045 mActivityStarter.doPendingActivityLaunchesLocked(true);
2048 case KILL_APPLICATION_MSG: {
2049 synchronized (ActivityManagerService.this) {
2050 final int appId = msg.arg1;
2051 final int userId = msg.arg2;
2052 Bundle bundle = (Bundle)msg.obj;
2053 String pkg = bundle.getString("pkg");
2054 String reason = bundle.getString("reason");
2055 forceStopPackageLocked(pkg, appId, false, false, true, false,
2056 false, userId, reason);
2059 case FINALIZE_PENDING_INTENT_MSG: {
2060 ((PendingIntentRecord)msg.obj).completeFinalize();
2062 case POST_HEAVY_NOTIFICATION_MSG: {
2063 INotificationManager inm = NotificationManager.getService();
2068 ActivityRecord root = (ActivityRecord)msg.obj;
2069 ProcessRecord process = root.app;
2070 if (process == null) {
2075 Context context = mContext.createPackageContext(process.info.packageName, 0);
2076 String text = mContext.getString(R.string.heavy_weight_notification,
2077 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2078 Notification notification =
2079 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2080 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2084 .setColor(mContext.getColor(
2085 com.android.internal.R.color.system_notification_accent_color))
2086 .setContentTitle(text)
2088 mContext.getText(R.string.heavy_weight_notification_detail))
2089 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2090 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2091 new UserHandle(root.userId)))
2094 inm.enqueueNotificationWithTag("android", "android", null,
2095 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2096 notification, root.userId);
2097 } catch (RuntimeException e) {
2098 Slog.w(ActivityManagerService.TAG,
2099 "Error showing notification for heavy-weight app", e);
2100 } catch (RemoteException e) {
2102 } catch (NameNotFoundException e) {
2103 Slog.w(TAG, "Unable to create context for heavy notification", e);
2106 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2107 INotificationManager inm = NotificationManager.getService();
2112 inm.cancelNotificationWithTag("android", null,
2113 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2114 } catch (RuntimeException e) {
2115 Slog.w(ActivityManagerService.TAG,
2116 "Error canceling notification for service", e);
2117 } catch (RemoteException e) {
2120 case CHECK_EXCESSIVE_POWER_USE_MSG: {
2121 synchronized (ActivityManagerService.this) {
2122 checkExcessivePowerUsageLocked();
2123 removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2124 Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2125 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2128 case REPORT_MEM_USAGE_MSG: {
2129 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2130 Thread thread = new Thread() {
2131 @Override public void run() {
2132 reportMemUsage(memInfos);
2138 case START_USER_SWITCH_FG_MSG: {
2139 mUserController.startUserInForeground(msg.arg1);
2142 case REPORT_USER_SWITCH_MSG: {
2143 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2146 case CONTINUE_USER_SWITCH_MSG: {
2147 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2150 case USER_SWITCH_TIMEOUT_MSG: {
2151 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2154 case IMMERSIVE_MODE_LOCK_MSG: {
2155 final boolean nextState = (msg.arg1 != 0);
2156 if (mUpdateLock.isHeld() != nextState) {
2157 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2158 "Applying new update lock state '" + nextState
2159 + "' for " + (ActivityRecord)msg.obj);
2161 mUpdateLock.acquire();
2163 mUpdateLock.release();
2168 case PERSIST_URI_GRANTS_MSG: {
2169 writeGrantedUriPermissions();
2172 case REQUEST_ALL_PSS_MSG: {
2173 synchronized (ActivityManagerService.this) {
2174 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2178 case START_PROFILES_MSG: {
2179 synchronized (ActivityManagerService.this) {
2180 mUserController.startProfilesLocked();
2184 case UPDATE_TIME_PREFERENCE_MSG: {
2185 // The user's time format preference might have changed.
2186 // For convenience we re-use the Intent extra values.
2187 synchronized (ActivityManagerService.this) {
2188 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2189 ProcessRecord r = mLruProcesses.get(i);
2190 if (r.thread != null) {
2192 r.thread.updateTimePrefs(msg.arg1);
2193 } catch (RemoteException ex) {
2194 Slog.w(TAG, "Failed to update preferences for: "
2195 + r.info.processName);
2202 case SYSTEM_USER_START_MSG: {
2203 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2204 Integer.toString(msg.arg1), msg.arg1);
2205 mSystemServiceManager.startUser(msg.arg1);
2208 case SYSTEM_USER_UNLOCK_MSG: {
2209 final int userId = msg.arg1;
2210 mSystemServiceManager.unlockUser(userId);
2211 synchronized (ActivityManagerService.this) {
2212 mRecentTasks.loadUserRecentsLocked(userId);
2214 if (userId == UserHandle.USER_SYSTEM) {
2215 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2217 installEncryptionUnawareProviders(userId);
2218 mUserController.finishUserUnlocked((UserState) msg.obj);
2221 case SYSTEM_USER_CURRENT_MSG: {
2222 mBatteryStatsService.noteEvent(
2223 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2224 Integer.toString(msg.arg2), msg.arg2);
2225 mBatteryStatsService.noteEvent(
2226 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2227 Integer.toString(msg.arg1), msg.arg1);
2228 mSystemServiceManager.switchUser(msg.arg1);
2231 case ENTER_ANIMATION_COMPLETE_MSG: {
2232 synchronized (ActivityManagerService.this) {
2233 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2234 if (r != null && r.app != null && r.app.thread != null) {
2236 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2237 } catch (RemoteException e) {
2243 case FINISH_BOOTING_MSG: {
2244 if (msg.arg1 != 0) {
2245 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2247 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2249 if (msg.arg2 != 0) {
2250 enableScreenAfterBoot();
2254 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2256 Locale l = (Locale) msg.obj;
2257 IBinder service = ServiceManager.getService("mount");
2258 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2259 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2260 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2261 } catch (RemoteException e) {
2262 Log.e(TAG, "Error storing locale for decryption UI", e);
2266 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2267 final int uid = msg.arg1;
2268 final byte[] firstPacket = (byte[]) msg.obj;
2270 synchronized (mPidsSelfLocked) {
2271 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2272 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2275 p.thread.notifyCleartextNetwork(firstPacket);
2276 } catch (RemoteException ignored) {
2283 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2284 final String procName;
2286 final long memLimit;
2287 final String reportPackage;
2288 synchronized (ActivityManagerService.this) {
2289 procName = mMemWatchDumpProcName;
2290 uid = mMemWatchDumpUid;
2291 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2293 val = mMemWatchProcesses.get(procName, 0);
2296 memLimit = val.first;
2297 reportPackage = val.second;
2300 reportPackage = null;
2303 if (procName == null) {
2307 if (DEBUG_PSS) Slog.d(TAG_PSS,
2308 "Showing dump heap notification from " + procName + "/" + uid);
2310 INotificationManager inm = NotificationManager.getService();
2315 String text = mContext.getString(R.string.dump_heap_notification, procName);
2318 Intent deleteIntent = new Intent();
2319 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2320 Intent intent = new Intent();
2321 intent.setClassName("android", DumpHeapActivity.class.getName());
2322 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2323 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2324 if (reportPackage != null) {
2325 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2327 int userId = UserHandle.getUserId(uid);
2328 Notification notification =
2329 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2330 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2333 .setAutoCancel(true)
2335 .setColor(mContext.getColor(
2336 com.android.internal.R.color.system_notification_accent_color))
2337 .setContentTitle(text)
2339 mContext.getText(R.string.dump_heap_notification_detail))
2340 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2341 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2342 new UserHandle(userId)))
2343 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2344 deleteIntent, 0, UserHandle.SYSTEM))
2348 inm.enqueueNotificationWithTag("android", "android", null,
2349 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2350 notification, userId);
2351 } catch (RuntimeException e) {
2352 Slog.w(ActivityManagerService.TAG,
2353 "Error showing notification for dump heap", e);
2354 } catch (RemoteException e) {
2357 case DELETE_DUMPHEAP_MSG: {
2358 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2359 null, DumpHeapActivity.JAVA_URI,
2360 Intent.FLAG_GRANT_READ_URI_PERMISSION
2361 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2362 UserHandle.myUserId());
2363 synchronized (ActivityManagerService.this) {
2364 mMemWatchDumpFile = null;
2365 mMemWatchDumpProcName = null;
2366 mMemWatchDumpPid = -1;
2367 mMemWatchDumpUid = -1;
2370 case FOREGROUND_PROFILE_CHANGED_MSG: {
2371 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2373 case REPORT_TIME_TRACKER_MSG: {
2374 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2375 tracker.deliverResult(mContext);
2377 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2378 mUserController.dispatchUserSwitchComplete(msg.arg1);
2380 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2381 mUserController.dispatchLockedBootComplete(msg.arg1);
2383 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2384 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2386 connection.shutdown();
2387 } catch (RemoteException e) {
2388 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2390 // Only a UiAutomation can set this flag and now that
2391 // it is finished we make sure it is reset to its default.
2392 mUserIsMonkey = false;
2394 case IDLE_UIDS_MSG: {
2397 case VR_MODE_CHANGE_MSG: {
2398 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2401 synchronized (ActivityManagerService.this) {
2402 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2403 mWindowManager.disableNonVrUi(disableNonVrUi);
2404 if (disableNonVrUi) {
2405 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2406 // then remove the pinned stack.
2407 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2409 if (pinnedStack != null) {
2410 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2415 case NOTIFY_VR_SLEEPING_MSG: {
2416 notifyVrManagerOfSleepState(msg.arg1 != 0);
2418 case NOTIFY_VR_KEYGUARD_MSG: {
2419 notifyVrManagerOfKeyguardState(msg.arg1 != 0);
2421 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2422 synchronized (ActivityManagerService.this) {
2423 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2424 ProcessRecord r = mLruProcesses.get(i);
2425 if (r.thread != null) {
2427 r.thread.handleTrustStorageUpdate();
2428 } catch (RemoteException ex) {
2429 Slog.w(TAG, "Failed to handle trust storage update for: " +
2430 r.info.processName);
2440 static final int COLLECT_PSS_BG_MSG = 1;
2442 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2444 public void handleMessage(Message msg) {
2446 case COLLECT_PSS_BG_MSG: {
2447 long start = SystemClock.uptimeMillis();
2448 MemInfoReader memInfo = null;
2449 synchronized (ActivityManagerService.this) {
2450 if (mFullPssPending) {
2451 mFullPssPending = false;
2452 memInfo = new MemInfoReader();
2455 if (memInfo != null) {
2456 updateCpuStatsNow();
2457 long nativeTotalPss = 0;
2458 final List<ProcessCpuTracker.Stats> stats;
2459 synchronized (mProcessCpuTracker) {
2460 stats = mProcessCpuTracker.getStats( (st)-> {
2461 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2464 final int N = stats.size();
2465 for (int j = 0; j < N; j++) {
2466 synchronized (mPidsSelfLocked) {
2467 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2468 // This is one of our own processes; skip it.
2472 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2474 memInfo.readMemInfo();
2475 synchronized (ActivityManagerService.this) {
2476 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2477 + (SystemClock.uptimeMillis()-start) + "ms");
2478 final long cachedKb = memInfo.getCachedSizeKb();
2479 final long freeKb = memInfo.getFreeSizeKb();
2480 final long zramKb = memInfo.getZramTotalSizeKb();
2481 final long kernelKb = memInfo.getKernelUsedSizeKb();
2482 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2483 kernelKb*1024, nativeTotalPss*1024);
2484 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2490 long[] tmp = new long[2];
2496 synchronized (ActivityManagerService.this) {
2497 if (mPendingPssProcesses.size() <= 0) {
2498 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2499 "Collected PSS of " + num + " processes in "
2500 + (SystemClock.uptimeMillis() - start) + "ms");
2501 mPendingPssProcesses.clear();
2504 proc = mPendingPssProcesses.remove(0);
2505 procState = proc.pssProcState;
2506 lastPssTime = proc.lastPssTime;
2507 if (proc.thread != null && procState == proc.setProcState
2508 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2509 < SystemClock.uptimeMillis()) {
2517 long pss = Debug.getPss(pid, tmp, null);
2518 synchronized (ActivityManagerService.this) {
2519 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2520 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2522 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2523 SystemClock.uptimeMillis());
2533 public void setSystemProcess() {
2535 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2536 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2537 ServiceManager.addService("meminfo", new MemBinder(this));
2538 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2539 ServiceManager.addService("dbinfo", new DbBinder(this));
2540 if (MONITOR_CPU_USAGE) {
2541 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2543 ServiceManager.addService("permission", new PermissionController(this));
2544 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2546 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2547 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2548 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2550 synchronized (this) {
2551 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2552 app.persistent = true;
2554 app.maxAdj = ProcessList.SYSTEM_ADJ;
2555 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2556 synchronized (mPidsSelfLocked) {
2557 mPidsSelfLocked.put(app.pid, app);
2559 updateLruProcessLocked(app, false, null);
2560 updateOomAdjLocked();
2562 } catch (PackageManager.NameNotFoundException e) {
2563 throw new RuntimeException(
2564 "Unable to find android system package", e);
2568 public void setWindowManager(WindowManagerService wm) {
2569 mWindowManager = wm;
2570 mStackSupervisor.setWindowManager(wm);
2571 mActivityStarter.setWindowManager(wm);
2574 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2575 mUsageStatsService = usageStatsManager;
2578 public void startObservingNativeCrashes() {
2579 final NativeCrashListener ncl = new NativeCrashListener(this);
2583 public IAppOpsService getAppOpsService() {
2584 return mAppOpsService;
2587 static class MemBinder extends Binder {
2588 ActivityManagerService mActivityManagerService;
2589 MemBinder(ActivityManagerService activityManagerService) {
2590 mActivityManagerService = activityManagerService;
2594 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2595 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2596 "meminfo", pw)) return;
2597 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2601 static class GraphicsBinder extends Binder {
2602 ActivityManagerService mActivityManagerService;
2603 GraphicsBinder(ActivityManagerService activityManagerService) {
2604 mActivityManagerService = activityManagerService;
2608 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2609 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2610 "gfxinfo", pw)) return;
2611 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2615 static class DbBinder extends Binder {
2616 ActivityManagerService mActivityManagerService;
2617 DbBinder(ActivityManagerService activityManagerService) {
2618 mActivityManagerService = activityManagerService;
2622 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2623 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2624 "dbinfo", pw)) return;
2625 mActivityManagerService.dumpDbInfo(fd, pw, args);
2629 static class CpuBinder extends Binder {
2630 ActivityManagerService mActivityManagerService;
2631 CpuBinder(ActivityManagerService activityManagerService) {
2632 mActivityManagerService = activityManagerService;
2636 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2637 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2638 "cpuinfo", pw)) return;
2639 synchronized (mActivityManagerService.mProcessCpuTracker) {
2640 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2641 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2642 SystemClock.uptimeMillis()));
2647 public static final class Lifecycle extends SystemService {
2648 private final ActivityManagerService mService;
2650 public Lifecycle(Context context) {
2652 mService = new ActivityManagerService(context);
2656 public void onStart() {
2661 public void onCleanupUser(int userId) {
2662 mService.mBatteryStatsService.onCleanupUser(userId);
2665 public ActivityManagerService getService() {
2671 public ActivityManagerService(Injector injector) {
2672 mInjector = injector;
2673 mContext = mInjector.getContext();
2676 mActivityStarter = null;
2678 mAppOpsService = mInjector.getAppOpsService(null, null);
2679 mBatteryStatsService = null;
2680 mCompatModePackages = null;
2684 mHandlerThread = null;
2685 mIntentFirewall = null;
2686 mKeyguardController = null;
2687 mPermissionReviewRequired = false;
2688 mProcessCpuThread = null;
2689 mProcessStats = null;
2690 mProviderMap = null;
2691 mRecentTasks = null;
2693 mStackSupervisor = null;
2694 mSystemThread = null;
2695 mTaskChangeNotificationController = null;
2696 mUiHandler = injector.getUiHandler(null);
2697 mUserController = null;
2698 mVrController = null;
2701 // Note: This method is invoked on the main thread but may need to attach various
2702 // handlers to other threads. So take care to be explicit about the looper.
2703 public ActivityManagerService(Context systemContext) {
2704 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2705 mInjector = new Injector();
2706 mContext = systemContext;
2708 mFactoryTest = FactoryTest.getMode();
2709 mSystemThread = ActivityThread.currentActivityThread();
2710 mUiContext = mSystemThread.getSystemUiContext();
2712 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2714 mPermissionReviewRequired = mContext.getResources().getBoolean(
2715 com.android.internal.R.bool.config_permissionReviewRequired);
2717 mHandlerThread = new ServiceThread(TAG,
2718 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2719 mHandlerThread.start();
2720 mHandler = new MainHandler(mHandlerThread.getLooper());
2721 mUiHandler = mInjector.getUiHandler(this);
2723 mConstants = new ActivityManagerConstants(this, mHandler);
2725 /* static; one-time init here */
2726 if (sKillHandler == null) {
2727 sKillThread = new ServiceThread(TAG + ":kill",
2728 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2729 sKillThread.start();
2730 sKillHandler = new KillHandler(sKillThread.getLooper());
2733 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2734 "foreground", BROADCAST_FG_TIMEOUT, false);
2735 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2736 "background", BROADCAST_BG_TIMEOUT, true);
2737 mBroadcastQueues[0] = mFgBroadcastQueue;
2738 mBroadcastQueues[1] = mBgBroadcastQueue;
2740 mServices = new ActiveServices(this);
2741 mProviderMap = new ProviderMap(this);
2742 mAppErrors = new AppErrors(mUiContext, this);
2744 // TODO: Move creation of battery stats service outside of activity manager service.
2745 File dataDir = Environment.getDataDirectory();
2746 File systemDir = new File(dataDir, "system");
2748 mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2749 mBatteryStatsService.getActiveStatistics().readLocked();
2750 mBatteryStatsService.scheduleWriteToDisk();
2751 mOnBattery = DEBUG_POWER ? true
2752 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2753 mBatteryStatsService.getActiveStatistics().setCallback(this);
2755 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2757 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2758 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2759 new IAppOpsCallback.Stub() {
2760 @Override public void opChanged(int op, int uid, String packageName) {
2761 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2762 if (mAppOpsService.checkOperation(op, uid, packageName)
2763 != AppOpsManager.MODE_ALLOWED) {
2764 runInBackgroundDisabled(uid);
2770 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2772 mUserController = new UserController(this);
2774 mVrController = new VrController(this);
2776 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2777 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2779 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2780 mUseFifoUiScheduling = true;
2783 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2784 mTempConfig.setToDefaults();
2785 mTempConfig.setLocales(LocaleList.getDefault());
2786 mConfigurationSeq = mTempConfig.seq = 1;
2787 mStackSupervisor = createStackSupervisor();
2788 mStackSupervisor.onConfigurationChanged(mTempConfig);
2789 mKeyguardController = mStackSupervisor.mKeyguardController;
2790 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2791 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2792 mTaskChangeNotificationController =
2793 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2794 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2795 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2797 mProcessCpuThread = new Thread("CpuTracker") {
2800 synchronized (mProcessCpuTracker) {
2801 mProcessCpuInitLatch.countDown();
2802 mProcessCpuTracker.init();
2807 synchronized(this) {
2808 final long now = SystemClock.uptimeMillis();
2809 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2810 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2811 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2812 // + ", write delay=" + nextWriteDelay);
2813 if (nextWriteDelay < nextCpuDelay) {
2814 nextCpuDelay = nextWriteDelay;
2816 if (nextCpuDelay > 0) {
2817 mProcessCpuMutexFree.set(true);
2818 this.wait(nextCpuDelay);
2821 } catch (InterruptedException e) {
2823 updateCpuStatsNow();
2824 } catch (Exception e) {
2825 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2831 Watchdog.getInstance().addMonitor(this);
2832 Watchdog.getInstance().addThread(mHandler);
2835 protected ActivityStackSupervisor createStackSupervisor() {
2836 return new ActivityStackSupervisor(this, mHandler.getLooper());
2839 public void setSystemServiceManager(SystemServiceManager mgr) {
2840 mSystemServiceManager = mgr;
2843 public void setInstaller(Installer installer) {
2844 mInstaller = installer;
2847 private void start() {
2848 removeAllProcessGroups();
2849 mProcessCpuThread.start();
2851 mBatteryStatsService.publish();
2852 mAppOpsService.publish(mContext);
2853 Slog.d("AppOps", "AppOpsService published");
2854 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2855 // Wait for the synchronized block started in mProcessCpuThread,
2856 // so that any other acccess to mProcessCpuTracker from main thread
2857 // will be blocked during mProcessCpuTracker initialization.
2859 mProcessCpuInitLatch.await();
2860 } catch (InterruptedException e) {
2861 Slog.wtf(TAG, "Interrupted wait during start", e);
2862 Thread.currentThread().interrupt();
2863 throw new IllegalStateException("Interrupted wait during start");
2867 void onUserStoppedLocked(int userId) {
2868 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2871 public void initPowerManagement() {
2872 mStackSupervisor.initPowerManagement();
2873 mBatteryStatsService.initPowerManagement();
2874 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2875 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2876 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2877 mVoiceWakeLock.setReferenceCounted(false);
2880 private ArraySet<String> getBackgroundLaunchBroadcasts() {
2881 if (mBackgroundLaunchBroadcasts == null) {
2882 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2884 return mBackgroundLaunchBroadcasts;
2888 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2889 throws RemoteException {
2890 if (code == SYSPROPS_TRANSACTION) {
2891 // We need to tell all apps about the system property change.
2892 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2893 synchronized(this) {
2894 final int NP = mProcessNames.getMap().size();
2895 for (int ip=0; ip<NP; ip++) {
2896 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2897 final int NA = apps.size();
2898 for (int ia=0; ia<NA; ia++) {
2899 ProcessRecord app = apps.valueAt(ia);
2900 if (app.thread != null) {
2901 procs.add(app.thread.asBinder());
2907 int N = procs.size();
2908 for (int i=0; i<N; i++) {
2909 Parcel data2 = Parcel.obtain();
2911 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2912 Binder.FLAG_ONEWAY);
2913 } catch (RemoteException e) {
2919 return super.onTransact(code, data, reply, flags);
2920 } catch (RuntimeException e) {
2921 // The activity manager only throws security exceptions, so let's
2923 if (!(e instanceof SecurityException)) {
2924 Slog.wtf(TAG, "Activity Manager Crash."
2925 + " UID:" + Binder.getCallingUid()
2926 + " PID:" + Binder.getCallingPid()
2927 + " TRANS:" + code, e);
2933 void updateCpuStats() {
2934 final long now = SystemClock.uptimeMillis();
2935 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2938 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2939 synchronized (mProcessCpuThread) {
2940 mProcessCpuThread.notify();
2945 void updateCpuStatsNow() {
2946 synchronized (mProcessCpuTracker) {
2947 mProcessCpuMutexFree.set(false);
2948 final long now = SystemClock.uptimeMillis();
2949 boolean haveNewCpuStats = false;
2951 if (MONITOR_CPU_USAGE &&
2952 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2953 mLastCpuTime.set(now);
2954 mProcessCpuTracker.update();
2955 if (mProcessCpuTracker.hasGoodLastStats()) {
2956 haveNewCpuStats = true;
2957 //Slog.i(TAG, mProcessCpu.printCurrentState());
2958 //Slog.i(TAG, "Total CPU usage: "
2959 // + mProcessCpu.getTotalCpuPercent() + "%");
2961 // Slog the cpu usage if the property is set.
2962 if ("true".equals(SystemProperties.get("events.cpu"))) {
2963 int user = mProcessCpuTracker.getLastUserTime();
2964 int system = mProcessCpuTracker.getLastSystemTime();
2965 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2966 int irq = mProcessCpuTracker.getLastIrqTime();
2967 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2968 int idle = mProcessCpuTracker.getLastIdleTime();
2970 int total = user + system + iowait + irq + softIrq + idle;
2971 if (total == 0) total = 1;
2973 EventLog.writeEvent(EventLogTags.CPU,
2974 ((user+system+iowait+irq+softIrq) * 100) / total,
2975 (user * 100) / total,
2976 (system * 100) / total,
2977 (iowait * 100) / total,
2978 (irq * 100) / total,
2979 (softIrq * 100) / total);
2984 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2985 synchronized(bstats) {
2986 synchronized(mPidsSelfLocked) {
2987 if (haveNewCpuStats) {
2988 if (bstats.startAddingCpuLocked()) {
2991 final int N = mProcessCpuTracker.countStats();
2992 for (int i=0; i<N; i++) {
2993 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2997 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2998 totalUTime += st.rel_utime;
2999 totalSTime += st.rel_stime;
3001 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3002 if (ps == null || !ps.isActive()) {
3003 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3004 pr.info.uid, pr.processName);
3006 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3007 pr.curCpuTime += st.rel_utime + st.rel_stime;
3008 if (pr.lastCpuTime == 0) {
3009 pr.lastCpuTime = pr.curCpuTime;
3012 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3013 if (ps == null || !ps.isActive()) {
3014 st.batteryStats = ps = bstats.getProcessStatsLocked(
3015 bstats.mapUid(st.uid), st.name);
3017 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3020 final int userTime = mProcessCpuTracker.getLastUserTime();
3021 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3022 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3023 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3024 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3025 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3026 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3027 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3032 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3033 mLastWriteTime = now;
3034 mBatteryStatsService.scheduleWriteToDisk();
3041 public void batteryNeedsCpuUpdate() {
3042 updateCpuStatsNow();
3046 public void batteryPowerChanged(boolean onBattery) {
3047 // When plugging in, update the CPU stats first before changing
3049 updateCpuStatsNow();
3050 synchronized (this) {
3051 synchronized(mPidsSelfLocked) {
3052 mOnBattery = DEBUG_POWER ? true : onBattery;
3058 public void batterySendBroadcast(Intent intent) {
3059 synchronized (this) {
3060 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3061 AppOpsManager.OP_NONE, null, false, false,
3062 -1, SYSTEM_UID, UserHandle.USER_ALL);
3067 * Initialize the application bind args. These are passed to each
3068 * process when the bindApplication() IPC is sent to the process. They're
3069 * lazily setup to make sure the services are running when they're asked for.
3071 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3072 // Isolated processes won't get this optimization, so that we don't
3073 // violate the rules about which services they have access to.
3075 if (mIsolatedAppBindArgs == null) {
3076 mIsolatedAppBindArgs = new HashMap<>();
3077 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3079 return mIsolatedAppBindArgs;
3082 if (mAppBindArgs == null) {
3083 mAppBindArgs = new HashMap<>();
3085 // Setup the application init args
3086 mAppBindArgs.put("package", ServiceManager.getService("package"));
3087 mAppBindArgs.put("window", ServiceManager.getService("window"));
3088 mAppBindArgs.put(Context.ALARM_SERVICE,
3089 ServiceManager.getService(Context.ALARM_SERVICE));
3091 return mAppBindArgs;
3095 * Update AMS states when an activity is resumed. This should only be called by
3096 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3098 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3099 final TaskRecord task = r.getTask();
3100 if (task.isApplicationTask()) {
3101 if (mCurAppTimeTracker != r.appTimeTracker) {
3102 // We are switching app tracking. Complete the current one.
3103 if (mCurAppTimeTracker != null) {
3104 mCurAppTimeTracker.stop();
3105 mHandler.obtainMessage(
3106 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3107 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3108 mCurAppTimeTracker = null;
3110 if (r.appTimeTracker != null) {
3111 mCurAppTimeTracker = r.appTimeTracker;
3112 startTimeTrackingFocusedActivityLocked();
3115 startTimeTrackingFocusedActivityLocked();
3118 r.appTimeTracker = null;
3120 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3121 // TODO: Probably not, because we don't want to resume voice on switching
3122 // back to this activity
3123 if (task.voiceInteractor != null) {
3124 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3126 finishRunningVoiceLocked();
3128 if (mLastResumedActivity != null) {
3129 final IVoiceInteractionSession session;
3131 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3132 if (lastResumedActivityTask != null
3133 && lastResumedActivityTask.voiceSession != null) {
3134 session = lastResumedActivityTask.voiceSession;
3136 session = mLastResumedActivity.voiceSession;
3139 if (session != null) {
3140 // We had been in a voice interaction session, but now focused has
3141 // move to something different. Just finish the session, we can't
3142 // return to it and retain the proper state and synchronization with
3143 // the voice interaction service.
3144 finishVoiceTask(session);
3149 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3150 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3151 mHandler.obtainMessage(
3152 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3154 mLastResumedActivity = r;
3156 mWindowManager.setFocusedApp(r.appToken, true);
3158 applyUpdateLockStateLocked(r);
3159 applyUpdateVrModeLocked(r);
3161 EventLogTags.writeAmSetResumedActivity(
3162 r == null ? -1 : r.userId,
3163 r == null ? "NULL" : r.shortComponentName,
3168 public void setFocusedStack(int stackId) {
3169 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3170 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3171 final long callingId = Binder.clearCallingIdentity();
3173 synchronized (this) {
3174 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3175 if (stack == null) {
3178 final ActivityRecord r = stack.topRunningActivityLocked();
3179 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3180 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3184 Binder.restoreCallingIdentity(callingId);
3189 public void setFocusedTask(int taskId) {
3190 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3191 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3192 final long callingId = Binder.clearCallingIdentity();
3194 synchronized (this) {
3195 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3199 final ActivityRecord r = task.topRunningActivityLocked();
3200 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3201 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3205 Binder.restoreCallingIdentity(callingId);
3209 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3211 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3212 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3213 mTaskChangeNotificationController.registerTaskStackListener(listener);
3217 * Unregister a task stack listener so that it stops receiving callbacks.
3220 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3221 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3222 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3226 public void notifyActivityDrawn(IBinder token) {
3227 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3228 synchronized (this) {
3229 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3231 r.getStack().notifyActivityDrawnLocked(r);
3236 final void applyUpdateLockStateLocked(ActivityRecord r) {
3237 // Modifications to the UpdateLock state are done on our handler, outside
3238 // the activity manager's locks. The new state is determined based on the
3239 // state *now* of the relevant activity record. The object is passed to
3240 // the handler solely for logging detail, not to be consulted/modified.
3241 final boolean nextState = r != null && r.immersive;
3242 mHandler.sendMessage(
3243 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3246 final void applyUpdateVrModeLocked(ActivityRecord r) {
3247 // VR apps are expected to run in a main display. If an app is turning on VR for
3248 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3249 // fullscreen stack before enabling VR Mode.
3250 // TODO: The goal of this code is to keep the VR app on the main display. When the
3251 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3252 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3253 // option would be a better choice here.
3254 if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3255 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3256 + " to main stack for VR");
3257 moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3259 mHandler.sendMessage(
3260 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3263 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3264 mHandler.sendMessage(
3265 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3268 private void notifyVrManagerOfSleepState(boolean isSleeping) {
3269 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3270 if (vrService == null) {
3273 vrService.onSleepStateChanged(isSleeping);
3276 private void sendNotifyVrManagerOfKeyguardState(boolean isShowing) {
3277 mHandler.sendMessage(
3278 mHandler.obtainMessage(NOTIFY_VR_KEYGUARD_MSG, isShowing ? 1 : 0, 0));
3281 private void notifyVrManagerOfKeyguardState(boolean isShowing) {
3282 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3283 if (vrService == null) {
3286 vrService.onKeyguardStateChanged(isShowing);
3289 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3290 Message msg = Message.obtain();
3291 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3292 msg.obj = r.getTask().askedCompatMode ? null : r;
3293 mUiHandler.sendMessage(msg);
3296 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3297 final Configuration globalConfig = getGlobalConfiguration();
3298 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3299 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3300 final Message msg = Message.obtain();
3301 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3303 mUiHandler.sendMessage(msg);
3307 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3308 String what, Object obj, ProcessRecord srcApp) {
3309 app.lastActivityTime = now;
3311 if (app.activities.size() > 0) {
3312 // Don't want to touch dependent processes that are hosting activities.
3316 int lrui = mLruProcesses.lastIndexOf(app);
3318 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3319 + what + " " + obj + " from " + srcApp);
3323 if (lrui >= index) {
3324 // Don't want to cause this to move dependent processes *back* in the
3325 // list as if they were less frequently used.
3329 if (lrui >= mLruProcessActivityStart) {
3330 // Don't want to touch dependent processes that are hosting activities.
3334 mLruProcesses.remove(lrui);
3338 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3339 + " in LRU list: " + app);
3340 mLruProcesses.add(index, app);
3344 static void killProcessGroup(int uid, int pid) {
3345 if (sKillHandler != null) {
3346 sKillHandler.sendMessage(
3347 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3349 Slog.w(TAG, "Asked to kill process group before system bringup!");
3350 Process.killProcessGroup(uid, pid);
3354 final void removeLruProcessLocked(ProcessRecord app) {
3355 int lrui = mLruProcesses.lastIndexOf(app);
3358 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3359 killProcessQuiet(app.pid);
3360 killProcessGroup(app.uid, app.pid);
3362 if (lrui <= mLruProcessActivityStart) {
3363 mLruProcessActivityStart--;
3365 if (lrui <= mLruProcessServiceStart) {
3366 mLruProcessServiceStart--;
3368 mLruProcesses.remove(lrui);
3372 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3373 ProcessRecord client) {
3374 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3375 || app.treatLikeActivity;
3376 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3377 if (!activityChange && hasActivity) {
3378 // The process has activities, so we are only allowing activity-based adjustments
3379 // to move it. It should be kept in the front of the list with other
3380 // processes that have activities, and we don't want those to change their
3381 // order except due to activity operations.
3386 final long now = SystemClock.uptimeMillis();
3387 app.lastActivityTime = now;
3389 // First a quick reject: if the app is already at the position we will
3390 // put it, then there is nothing to do.
3392 final int N = mLruProcesses.size();
3393 if (N > 0 && mLruProcesses.get(N-1) == app) {
3394 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3398 if (mLruProcessServiceStart > 0
3399 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3400 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3405 int lrui = mLruProcesses.lastIndexOf(app);
3407 if (app.persistent && lrui >= 0) {
3408 // We don't care about the position of persistent processes, as long as
3409 // they are in the list.
3410 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3414 /* In progress: compute new position first, so we can avoid doing work
3415 if the process is not actually going to move. Not yet working.
3418 boolean inActivity = false, inService = false;
3420 // Process has activities, put it at the very tipsy-top.
3421 addIndex = mLruProcesses.size();
3422 nextIndex = mLruProcessServiceStart;
3424 } else if (hasService) {
3425 // Process has services, put it at the top of the service list.
3426 addIndex = mLruProcessActivityStart;
3427 nextIndex = mLruProcessServiceStart;
3431 // Process not otherwise of interest, it goes to the top of the non-service area.
3432 addIndex = mLruProcessServiceStart;
3433 if (client != null) {
3434 int clientIndex = mLruProcesses.lastIndexOf(client);
3435 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3437 if (clientIndex >= 0 && addIndex > clientIndex) {
3438 addIndex = clientIndex;
3441 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3444 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3445 + mLruProcessActivityStart + "): " + app);
3449 if (lrui < mLruProcessActivityStart) {
3450 mLruProcessActivityStart--;
3452 if (lrui < mLruProcessServiceStart) {
3453 mLruProcessServiceStart--;
3456 if (addIndex > lrui) {
3459 if (nextIndex > lrui) {
3463 mLruProcesses.remove(lrui);
3467 mLruProcesses.add(addIndex, app);
3469 mLruProcessActivityStart++;
3472 mLruProcessActivityStart++;
3478 final int N = mLruProcesses.size();
3479 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3480 // Process doesn't have activities, but has clients with
3481 // activities... move it up, but one below the top (the top
3482 // should always have a real activity).
3483 if (DEBUG_LRU) Slog.d(TAG_LRU,
3484 "Adding to second-top of LRU activity list: " + app);
3485 mLruProcesses.add(N - 1, app);
3486 // To keep it from spamming the LRU list (by making a bunch of clients),
3487 // we will push down any other entries owned by the app.
3488 final int uid = app.info.uid;
3489 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3490 ProcessRecord subProc = mLruProcesses.get(i);
3491 if (subProc.info.uid == uid) {
3492 // We want to push this one down the list. If the process after
3493 // it is for the same uid, however, don't do so, because we don't
3494 // want them internally to be re-ordered.
3495 if (mLruProcesses.get(i - 1).info.uid != uid) {
3496 if (DEBUG_LRU) Slog.d(TAG_LRU,
3497 "Pushing uid " + uid + " swapping at " + i + ": "
3498 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3499 ProcessRecord tmp = mLruProcesses.get(i);
3500 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3501 mLruProcesses.set(i - 1, tmp);
3505 // A gap, we can stop here.
3510 // Process has activities, put it at the very tipsy-top.
3511 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3512 mLruProcesses.add(app);
3514 nextIndex = mLruProcessServiceStart;
3515 } else if (hasService) {
3516 // Process has services, put it at the top of the service list.
3517 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3518 mLruProcesses.add(mLruProcessActivityStart, app);
3519 nextIndex = mLruProcessServiceStart;
3520 mLruProcessActivityStart++;
3522 // Process not otherwise of interest, it goes to the top of the non-service area.
3523 int index = mLruProcessServiceStart;
3524 if (client != null) {
3525 // If there is a client, don't allow the process to be moved up higher
3526 // in the list than that client.
3527 int clientIndex = mLruProcesses.lastIndexOf(client);
3528 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3529 + " when updating " + app);
3530 if (clientIndex <= lrui) {
3531 // Don't allow the client index restriction to push it down farther in the
3532 // list than it already is.
3535 if (clientIndex >= 0 && index > clientIndex) {
3536 index = clientIndex;
3539 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3540 mLruProcesses.add(index, app);
3541 nextIndex = index-1;
3542 mLruProcessActivityStart++;
3543 mLruProcessServiceStart++;
3546 // If the app is currently using a content provider or service,
3547 // bump those processes as well.
3548 for (int j=app.connections.size()-1; j>=0; j--) {
3549 ConnectionRecord cr = app.connections.valueAt(j);
3550 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3551 && cr.binding.service.app != null
3552 && cr.binding.service.app.lruSeq != mLruSeq
3553 && !cr.binding.service.app.persistent) {
3554 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3555 "service connection", cr, app);
3558 for (int j=app.conProviders.size()-1; j>=0; j--) {
3559 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3560 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3561 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3562 "provider reference", cpr, app);
3567 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3568 if (uid == SYSTEM_UID) {
3569 // The system gets to run in any process. If there are multiple
3570 // processes with the same uid, just pick the first (this
3571 // should never happen).
3572 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3573 if (procs == null) return null;
3574 final int procCount = procs.size();
3575 for (int i = 0; i < procCount; i++) {
3576 final int procUid = procs.keyAt(i);
3577 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3578 // Don't use an app process or different user process for system component.
3581 return procs.valueAt(i);
3584 ProcessRecord proc = mProcessNames.get(processName, uid);
3585 if (false && proc != null && !keepIfLarge
3586 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3587 && proc.lastCachedPss >= 4000) {
3588 // Turn this condition on to cause killing to happen regularly, for testing.
3589 if (proc.baseProcessTracker != null) {
3590 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3592 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3593 } else if (proc != null && !keepIfLarge
3594 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3595 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3596 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3597 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3598 if (proc.baseProcessTracker != null) {
3599 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3601 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3607 void notifyPackageUse(String packageName, int reason) {
3608 synchronized(this) {
3609 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3613 boolean isNextTransitionForward() {
3614 int transit = mWindowManager.getPendingAppTransition();
3615 return transit == TRANSIT_ACTIVITY_OPEN
3616 || transit == TRANSIT_TASK_OPEN
3617 || transit == TRANSIT_TASK_TO_FRONT;
3620 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3621 String processName, String abiOverride, int uid, Runnable crashHandler) {
3622 synchronized(this) {
3623 ApplicationInfo info = new ApplicationInfo();
3624 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3625 // For isolated processes, the former contains the parent's uid and the latter the
3626 // actual uid of the isolated process.
3627 // In the special case introduced by this method (which is, starting an isolated
3628 // process directly from the SystemServer without an actual parent app process) the
3629 // closest thing to a parent's uid is SYSTEM_UID.
3630 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3631 // the |isolated| logic in the ProcessRecord constructor.
3632 info.uid = SYSTEM_UID;
3633 info.processName = processName;
3634 info.className = entryPoint;
3635 info.packageName = "android";
3636 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3637 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3638 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3639 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3640 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3642 return proc != null ? proc.pid : 0;
3646 final ProcessRecord startProcessLocked(String processName,
3647 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3648 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3649 boolean isolated, boolean keepIfLarge) {
3650 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3651 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3652 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3653 null /* crashHandler */);
3656 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3657 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3658 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3659 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3660 long startTime = SystemClock.elapsedRealtime();
3663 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3664 checkTime(startTime, "startProcess: after getProcessRecord");
3666 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3667 // If we are in the background, then check to see if this process
3668 // is bad. If so, we will just silently fail.
3669 if (mAppErrors.isBadProcessLocked(info)) {
3670 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3671 + "/" + info.processName);
3675 // When the user is explicitly starting a process, then clear its
3676 // crash count so that we won't make it bad until they see at
3677 // least one crash dialog again, and make the process good again
3678 // if it had been bad.
3679 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3680 + "/" + info.processName);
3681 mAppErrors.resetProcessCrashTimeLocked(info);
3682 if (mAppErrors.isBadProcessLocked(info)) {
3683 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3684 UserHandle.getUserId(info.uid), info.uid,
3686 mAppErrors.clearBadProcessLocked(info);
3693 // If this is an isolated process, it can't re-use an existing process.
3697 // We don't have to do anything more if:
3698 // (1) There is an existing application record; and
3699 // (2) The caller doesn't think it is dead, OR there is no thread
3700 // object attached to it so we know it couldn't have crashed; and
3701 // (3) There is a pid assigned to it, so it is either starting or
3703 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3704 + " app=" + app + " knownToBeDead=" + knownToBeDead
3705 + " thread=" + (app != null ? app.thread : null)
3706 + " pid=" + (app != null ? app.pid : -1));
3707 if (app != null && app.pid > 0) {
3708 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3709 // We already have the app running, or are waiting for it to
3710 // come up (we have a pid but not yet its thread), so keep it.
3711 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3712 // If this is a new package in the process, add the package to the list
3713 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3714 checkTime(startTime, "startProcess: done, added package to proc");
3718 // An application record is attached to a previous process,
3720 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3721 checkTime(startTime, "startProcess: bad proc running, killing");
3722 killProcessGroup(app.uid, app.pid);
3723 handleAppDiedLocked(app, true, true);
3724 checkTime(startTime, "startProcess: done killing old proc");
3727 String hostingNameStr = hostingName != null
3728 ? hostingName.flattenToShortString() : null;
3731 checkTime(startTime, "startProcess: creating new process record");
3732 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3734 Slog.w(TAG, "Failed making new process record for "
3735 + processName + "/" + info.uid + " isolated=" + isolated);
3738 app.crashHandler = crashHandler;
3739 checkTime(startTime, "startProcess: done creating new process record");
3741 // If this is a new package in the process, add the package to the list
3742 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3743 checkTime(startTime, "startProcess: added package to existing proc");
3746 // If the system is not ready yet, then hold off on starting this
3747 // process until it is.
3748 if (!mProcessesReady
3749 && !isAllowedWhileBooting(info)
3750 && !allowWhileBooting) {
3751 if (!mProcessesOnHold.contains(app)) {
3752 mProcessesOnHold.add(app);
3754 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3755 "System not ready, putting on hold: " + app);
3756 checkTime(startTime, "startProcess: returning with proc on hold");
3760 checkTime(startTime, "startProcess: stepping in to startProcess");
3762 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3763 checkTime(startTime, "startProcess: done starting proc!");
3764 return (app.pid != 0) ? app : null;
3767 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3768 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3771 private final void startProcessLocked(ProcessRecord app,
3772 String hostingType, String hostingNameStr) {
3773 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3774 null /* entryPoint */, null /* entryPointArgs */);
3777 private final void startProcessLocked(ProcessRecord app, String hostingType,
3778 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3779 long startTime = SystemClock.elapsedRealtime();
3780 if (app.pid > 0 && app.pid != MY_PID) {
3781 checkTime(startTime, "startProcess: removing from pids map");
3782 synchronized (mPidsSelfLocked) {
3783 mPidsSelfLocked.remove(app.pid);
3784 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3786 checkTime(startTime, "startProcess: done removing from pids map");
3790 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3791 "startProcessLocked removing on hold: " + app);
3792 mProcessesOnHold.remove(app);
3794 checkTime(startTime, "startProcess: starting to update cpu stats");
3796 checkTime(startTime, "startProcess: done updating cpu stats");
3800 final int userId = UserHandle.getUserId(app.uid);
3801 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3802 } catch (RemoteException e) {
3803 throw e.rethrowAsRuntimeException();
3808 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3809 if (!app.isolated) {
3810 int[] permGids = null;
3812 checkTime(startTime, "startProcess: getting gids from package manager");
3813 final IPackageManager pm = AppGlobals.getPackageManager();
3814 permGids = pm.getPackageGids(app.info.packageName,
3815 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3816 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3817 StorageManagerInternal.class);
3818 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3819 app.info.packageName);
3820 } catch (RemoteException e) {
3821 throw e.rethrowAsRuntimeException();
3825 * Add shared application and profile GIDs so applications can share some
3826 * resources like shared libraries and access user-wide resources
3828 if (ArrayUtils.isEmpty(permGids)) {
3831 gids = new int[permGids.length + 3];
3832 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3834 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3835 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3836 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3838 checkTime(startTime, "startProcess: building args");
3839 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3840 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3841 && mTopComponent != null
3842 && app.processName.equals(mTopComponent.getPackageName())) {
3845 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3846 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3851 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3852 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3853 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3854 // Also turn on CheckJNI for debuggable apps. It's quite
3855 // awkward to turn on otherwise.
3856 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3858 // Run the app in safe mode if its manifest requests so or the
3859 // system is booted in safe mode.
3860 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3861 mSafeMode == true) {
3862 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3864 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3865 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3867 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3868 if ("true".equals(genDebugInfoProperty)) {
3869 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3871 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3872 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3874 if ("1".equals(SystemProperties.get("debug.assert"))) {
3875 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3877 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3878 // Enable all debug flags required by the native debugger.
3879 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3880 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3881 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3882 mNativeDebuggingApp = null;
3885 String invokeWith = null;
3886 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3887 // Debuggable apps may include a wrapper script with their library directory.
3888 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3889 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3891 if (new File(wrapperFileName).exists()) {
3892 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3895 StrictMode.setThreadPolicy(oldPolicy);
3899 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3900 if (requiredAbi == null) {
3901 requiredAbi = Build.SUPPORTED_ABIS[0];
3904 String instructionSet = null;
3905 if (app.info.primaryCpuAbi != null) {
3906 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3910 app.requiredAbi = requiredAbi;
3911 app.instructionSet = instructionSet;
3913 // the per-user SELinux context must be set
3914 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3915 Slog.wtf(TAG, "SELinux tag not defined",
3916 new IllegalStateException("SELinux tag not defined for "
3917 + app.info.packageName + " (uid " + app.uid + ")"));
3919 final String seInfo = app.info.seInfo
3920 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3921 // Start the process. It will either succeed and return a result containing
3922 // the PID of the new process, or else throw a RuntimeException.
3923 boolean isActivityProcess = (entryPoint == null);
3924 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3925 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3927 checkTime(startTime, "startProcess: asking zygote to start proc");
3928 ProcessStartResult startResult;
3929 if (hostingType.equals("webview_service")) {
3930 startResult = startWebView(entryPoint,
3931 app.processName, uid, uid, gids, debugFlags, mountExternal,
3932 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3933 app.info.dataDir, null, entryPointArgs);
3935 startResult = Process.start(entryPoint,
3936 app.processName, uid, uid, gids, debugFlags, mountExternal,
3937 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3938 app.info.dataDir, invokeWith, entryPointArgs);
3940 checkTime(startTime, "startProcess: returned from zygote!");
3941 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3943 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3944 checkTime(startTime, "startProcess: done updating battery stats");
3946 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3947 UserHandle.getUserId(uid), startResult.pid, uid,
3948 app.processName, hostingType,
3949 hostingNameStr != null ? hostingNameStr : "");
3952 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3953 seInfo, app.info.sourceDir, startResult.pid);
3954 } catch (RemoteException ex) {
3958 if (app.persistent) {
3959 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3962 checkTime(startTime, "startProcess: building log message");
3963 StringBuilder buf = mStringBuilder;
3965 buf.append("Start proc ");
3966 buf.append(startResult.pid);
3968 buf.append(app.processName);
3970 UserHandle.formatUid(buf, uid);
3971 if (!isActivityProcess) {
3973 buf.append(entryPoint);
3976 buf.append(" for ");
3977 buf.append(hostingType);
3978 if (hostingNameStr != null) {
3980 buf.append(hostingNameStr);
3982 Slog.i(TAG, buf.toString());
3983 app.setPid(startResult.pid);
3984 app.usingWrapper = startResult.usingWrapper;
3985 app.removed = false;
3987 app.killedByAm = false;
3988 checkTime(startTime, "startProcess: starting to update pids map");
3989 ProcessRecord oldApp;
3990 synchronized (mPidsSelfLocked) {
3991 oldApp = mPidsSelfLocked.get(startResult.pid);
3993 // If there is already an app occupying that pid that hasn't been cleaned up
3994 if (oldApp != null && !app.isolated) {
3995 // Clean up anything relating to this pid first
3996 Slog.w(TAG, "Reusing pid " + startResult.pid
3997 + " while app is still mapped to it");
3998 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3999 true /*replacingPid*/);
4001 synchronized (mPidsSelfLocked) {
4002 this.mPidsSelfLocked.put(startResult.pid, app);
4003 if (isActivityProcess) {
4004 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4006 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4007 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4010 checkTime(startTime, "startProcess: done updating pids map");
4011 } catch (RuntimeException e) {
4012 Slog.e(TAG, "Failure starting process " + app.processName, e);
4014 // Something went very wrong while trying to start this process; one
4015 // common case is when the package is frozen due to an active
4016 // upgrade. To recover, clean up any active bookkeeping related to
4017 // starting this process. (We already invoked this method once when
4018 // the package was initially frozen through KILL_APPLICATION_MSG, so
4019 // it doesn't hurt to use it again.)
4020 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4021 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4025 void updateUsageStats(ActivityRecord component, boolean resumed) {
4026 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4027 "updateUsageStats: comp=" + component + "res=" + resumed);
4028 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4030 if (mUsageStatsService != null) {
4031 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4032 UsageEvents.Event.MOVE_TO_FOREGROUND);
4034 synchronized (stats) {
4035 stats.noteActivityResumedLocked(component.app.uid);
4038 if (mUsageStatsService != null) {
4039 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4040 UsageEvents.Event.MOVE_TO_BACKGROUND);
4042 synchronized (stats) {
4043 stats.noteActivityPausedLocked(component.app.uid);
4048 Intent getHomeIntent() {
4049 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4050 intent.setComponent(mTopComponent);
4051 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4052 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4053 intent.addCategory(Intent.CATEGORY_HOME);
4058 boolean startHomeActivityLocked(int userId, String reason) {
4059 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4060 && mTopAction == null) {
4061 // We are running in factory test mode, but unable to find
4062 // the factory test app, so just sit around displaying the
4063 // error message and don't try to start anything.
4066 Intent intent = getHomeIntent();
4067 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4068 if (aInfo != null) {
4069 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4070 // Don't do this if the home app is currently being
4072 aInfo = new ActivityInfo(aInfo);
4073 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4074 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4075 aInfo.applicationInfo.uid, true);
4076 if (app == null || app.instr == null) {
4077 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4078 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4079 // For ANR debugging to verify if the user activity is the one that actually
4081 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4082 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4085 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4091 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4092 ActivityInfo ai = null;
4093 ComponentName comp = intent.getComponent();
4097 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4099 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4101 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4105 ai = info.activityInfo;
4108 } catch (RemoteException e) {
4116 * Starts the "new version setup screen" if appropriate.
4118 void startSetupActivityLocked() {
4119 // Only do this once per boot.
4120 if (mCheckedForSetup) {
4124 // We will show this screen if the current one is a different
4125 // version than the last one shown, and we are not running in
4126 // low-level factory test mode.
4127 final ContentResolver resolver = mContext.getContentResolver();
4128 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4129 Settings.Global.getInt(resolver,
4130 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4131 mCheckedForSetup = true;
4133 // See if we should be showing the platform update setup UI.
4134 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4135 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4136 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4137 if (!ris.isEmpty()) {
4138 final ResolveInfo ri = ris.get(0);
4139 String vers = ri.activityInfo.metaData != null
4140 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4142 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4143 vers = ri.activityInfo.applicationInfo.metaData.getString(
4144 Intent.METADATA_SETUP_VERSION);
4146 String lastVers = Settings.Secure.getString(
4147 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4148 if (vers != null && !vers.equals(lastVers)) {
4149 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4150 intent.setComponent(new ComponentName(
4151 ri.activityInfo.packageName, ri.activityInfo.name));
4152 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4153 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4154 null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4160 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4161 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4164 void enforceNotIsolatedCaller(String caller) {
4165 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4166 throw new SecurityException("Isolated process not allowed to call " + caller);
4170 void enforceShellRestriction(String restriction, int userHandle) {
4171 if (Binder.getCallingUid() == SHELL_UID) {
4172 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4173 throw new SecurityException("Shell does not have permission to access user "
4180 public int getFrontActivityScreenCompatMode() {
4181 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4182 synchronized (this) {
4183 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4188 public void setFrontActivityScreenCompatMode(int mode) {
4189 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4190 "setFrontActivityScreenCompatMode");
4191 synchronized (this) {
4192 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4197 public int getPackageScreenCompatMode(String packageName) {
4198 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4199 synchronized (this) {
4200 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4205 public void setPackageScreenCompatMode(String packageName, int mode) {
4206 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4207 "setPackageScreenCompatMode");
4208 synchronized (this) {
4209 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4214 public boolean getPackageAskScreenCompat(String packageName) {
4215 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4216 synchronized (this) {
4217 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4222 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4223 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4224 "setPackageAskScreenCompat");
4225 synchronized (this) {
4226 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4230 private boolean hasUsageStatsPermission(String callingPackage) {
4231 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4232 Binder.getCallingUid(), callingPackage);
4233 if (mode == AppOpsManager.MODE_DEFAULT) {
4234 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4235 == PackageManager.PERMISSION_GRANTED;
4237 return mode == AppOpsManager.MODE_ALLOWED;
4241 public int getPackageProcessState(String packageName, String callingPackage) {
4242 if (!hasUsageStatsPermission(callingPackage)) {
4243 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4244 "getPackageProcessState");
4247 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4248 synchronized (this) {
4249 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4250 final ProcessRecord proc = mLruProcesses.get(i);
4251 if (procState > proc.setProcState) {
4252 if (proc.pkgList.containsKey(packageName) ||
4253 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4254 procState = proc.setProcState;
4263 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4264 throws RemoteException {
4265 synchronized (this) {
4266 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4268 throw new IllegalArgumentException("Unknown process: " + process);
4270 if (app.thread == null) {
4271 throw new IllegalArgumentException("Process has no app thread");
4273 if (app.trimMemoryLevel >= level) {
4274 throw new IllegalArgumentException(
4275 "Unable to set a higher trim level than current level");
4277 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4278 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4279 throw new IllegalArgumentException("Unable to set a background trim level "
4280 + "on a foreground process");
4282 app.thread.scheduleTrimMemory(level);
4283 app.trimMemoryLevel = level;
4288 private void dispatchProcessesChanged() {
4290 synchronized (this) {
4291 N = mPendingProcessChanges.size();
4292 if (mActiveProcessChanges.length < N) {
4293 mActiveProcessChanges = new ProcessChangeItem[N];
4295 mPendingProcessChanges.toArray(mActiveProcessChanges);
4296 mPendingProcessChanges.clear();
4297 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4298 "*** Delivering " + N + " process changes");
4301 int i = mProcessObservers.beginBroadcast();
4304 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4305 if (observer != null) {
4307 for (int j=0; j<N; j++) {
4308 ProcessChangeItem item = mActiveProcessChanges[j];
4309 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4310 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4311 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4312 + item.uid + ": " + item.foregroundActivities);
4313 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4314 item.foregroundActivities);
4317 } catch (RemoteException e) {
4321 mProcessObservers.finishBroadcast();
4323 synchronized (this) {
4324 for (int j=0; j<N; j++) {
4325 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4330 private void dispatchProcessDied(int pid, int uid) {
4331 int i = mProcessObservers.beginBroadcast();
4334 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4335 if (observer != null) {
4337 observer.onProcessDied(pid, uid);
4338 } catch (RemoteException e) {
4342 mProcessObservers.finishBroadcast();
4346 void dispatchUidsChanged() {
4348 synchronized (this) {
4349 N = mPendingUidChanges.size();
4350 if (mActiveUidChanges.length < N) {
4351 mActiveUidChanges = new UidRecord.ChangeItem[N];
4353 for (int i=0; i<N; i++) {
4354 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4355 mActiveUidChanges[i] = change;
4356 if (change.uidRecord != null) {
4357 change.uidRecord.pendingChange = null;
4358 change.uidRecord = null;
4361 mPendingUidChanges.clear();
4362 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4363 "*** Delivering " + N + " uid changes");
4366 int i = mUidObservers.beginBroadcast();
4369 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4370 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4372 mUidObservers.finishBroadcast();
4374 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4375 for (int j = 0; j < N; ++j) {
4376 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4377 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4378 mValidateUids.remove(item.uid);
4380 UidRecord validateUid = mValidateUids.get(item.uid);
4381 if (validateUid == null) {
4382 validateUid = new UidRecord(item.uid);
4383 mValidateUids.put(item.uid, validateUid);
4385 if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4386 validateUid.idle = true;
4387 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4388 validateUid.idle = false;
4390 validateUid.curProcState = validateUid.setProcState = item.processState;
4391 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4396 synchronized (this) {
4397 for (int j = 0; j < N; j++) {
4398 mAvailUidChanges.add(mActiveUidChanges[j]);
4403 private void dispatchUidsChangedForObserver(IUidObserver observer,
4404 UidObserverRegistration reg, int changesSize) {
4405 if (observer == null) {
4409 for (int j = 0; j < changesSize; j++) {
4410 UidRecord.ChangeItem item = mActiveUidChanges[j];
4411 final int change = item.change;
4412 if (change == UidRecord.CHANGE_PROCSTATE &&
4413 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4414 // No-op common case: no significant change, the observer is not
4415 // interested in all proc state changes.
4418 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4419 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4420 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4421 "UID idle uid=" + item.uid);
4422 observer.onUidIdle(item.uid, item.ephemeral);
4424 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4425 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4426 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4427 "UID active uid=" + item.uid);
4428 observer.onUidActive(item.uid);
4431 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4432 if ((change & UidRecord.CHANGE_CACHED) != 0) {
4433 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4434 "UID cached uid=" + item.uid);
4435 observer.onUidCachedChanged(item.uid, true);
4436 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4437 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4438 "UID active uid=" + item.uid);
4439 observer.onUidCachedChanged(item.uid, false);
4442 if ((change & UidRecord.CHANGE_GONE) != 0) {
4443 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4444 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4445 "UID gone uid=" + item.uid);
4446 observer.onUidGone(item.uid, item.ephemeral);
4448 if (reg.lastProcStates != null) {
4449 reg.lastProcStates.delete(item.uid);
4452 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4453 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4454 "UID CHANGED uid=" + item.uid
4455 + ": " + item.processState);
4456 boolean doReport = true;
4457 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4458 final int lastState = reg.lastProcStates.get(item.uid,
4459 ActivityManager.PROCESS_STATE_UNKNOWN);
4460 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4461 final boolean lastAboveCut = lastState <= reg.cutpoint;
4462 final boolean newAboveCut = item.processState <= reg.cutpoint;
4463 doReport = lastAboveCut != newAboveCut;
4465 doReport = item.processState
4466 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4470 if (reg.lastProcStates != null) {
4471 reg.lastProcStates.put(item.uid, item.processState);
4473 observer.onUidStateChanged(item.uid, item.processState,
4479 } catch (RemoteException e) {
4483 void dispatchOomAdjObserver(String msg) {
4484 OomAdjObserver observer;
4485 synchronized (this) {
4486 observer = mCurOomAdjObserver;
4489 if (observer != null) {
4490 observer.onOomAdjMessage(msg);
4494 void setOomAdjObserver(int uid, OomAdjObserver observer) {
4495 synchronized (this) {
4496 mCurOomAdjUid = uid;
4497 mCurOomAdjObserver = observer;
4501 void clearOomAdjObserver() {
4502 synchronized (this) {
4504 mCurOomAdjObserver = null;
4508 void reportOomAdjMessageLocked(String tag, String msg) {
4510 if (mCurOomAdjObserver != null) {
4511 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4516 public final int startActivity(IApplicationThread caller, String callingPackage,
4517 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4518 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4519 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4520 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4521 UserHandle.getCallingUserId());
4525 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4526 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4527 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4528 enforceNotIsolatedCaller("startActivity");
4529 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4530 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4531 // TODO: Switch to user app stacks here.
4532 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4533 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4534 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4538 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4539 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4540 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4543 // This is very dangerous -- it allows you to perform a start activity (including
4544 // permission grants) as any app that may launch one of your own activities. So
4545 // we will only allow this to be done from activities that are part of the core framework,
4546 // and then only when they are running as the system.
4547 final ActivityRecord sourceRecord;
4548 final int targetUid;
4549 final String targetPackage;
4550 synchronized (this) {
4551 if (resultTo == null) {
4552 throw new SecurityException("Must be called from an activity");
4554 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4555 if (sourceRecord == null) {
4556 throw new SecurityException("Called with bad activity token: " + resultTo);
4558 if (!sourceRecord.info.packageName.equals("android")) {
4559 throw new SecurityException(
4560 "Must be called from an activity that is declared in the android package");
4562 if (sourceRecord.app == null) {
4563 throw new SecurityException("Called without a process attached to activity");
4565 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4566 // This is still okay, as long as this activity is running under the
4567 // uid of the original calling activity.
4568 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4569 throw new SecurityException(
4570 "Calling activity in uid " + sourceRecord.app.uid
4571 + " must be system uid or original calling uid "
4572 + sourceRecord.launchedFromUid);
4575 if (ignoreTargetSecurity) {
4576 if (intent.getComponent() == null) {
4577 throw new SecurityException(
4578 "Component must be specified with ignoreTargetSecurity");
4580 if (intent.getSelector() != null) {
4581 throw new SecurityException(
4582 "Selector not allowed with ignoreTargetSecurity");
4585 targetUid = sourceRecord.launchedFromUid;
4586 targetPackage = sourceRecord.launchedFromPackage;
4589 if (userId == UserHandle.USER_NULL) {
4590 userId = UserHandle.getUserId(sourceRecord.app.uid);
4593 // TODO: Switch to user app stacks here.
4595 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4596 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4597 null, null, bOptions, ignoreTargetSecurity, userId, null,
4598 "startActivityAsCaller");
4600 } catch (SecurityException e) {
4601 // XXX need to figure out how to propagate to original app.
4602 // A SecurityException here is generally actually a fault of the original
4603 // calling activity (such as a fairly granting permissions), so propagate it
4606 StringBuilder msg = new StringBuilder();
4607 msg.append("While launching");
4608 msg.append(intent.toString());
4610 msg.append(e.getMessage());
4617 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4618 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4619 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4620 enforceNotIsolatedCaller("startActivityAndWait");
4621 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4622 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4623 WaitResult res = new WaitResult();
4624 // TODO: Switch to user app stacks here.
4625 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4626 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4627 bOptions, false, userId, null, "startActivityAndWait");
4632 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4633 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4634 int startFlags, Configuration config, Bundle bOptions, int userId) {
4635 enforceNotIsolatedCaller("startActivityWithConfig");
4636 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4637 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4638 // TODO: Switch to user app stacks here.
4639 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4640 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4641 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4646 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4647 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4648 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4649 throws TransactionTooLargeException {
4650 enforceNotIsolatedCaller("startActivityIntentSender");
4651 // Refuse possible leaked file descriptors
4652 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4653 throw new IllegalArgumentException("File descriptors passed in Intent");
4656 if (!(target instanceof PendingIntentRecord)) {
4657 throw new IllegalArgumentException("Bad PendingIntent object");
4660 PendingIntentRecord pir = (PendingIntentRecord)target;
4662 synchronized (this) {
4663 // If this is coming from the currently resumed activity, it is
4664 // effectively saying that app switches are allowed at this point.
4665 final ActivityStack stack = getFocusedStack();
4666 if (stack.mResumedActivity != null &&
4667 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4668 mAppSwitchesAllowedTime = 0;
4671 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4672 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4677 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4678 Intent intent, String resolvedType, IVoiceInteractionSession session,
4679 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4680 Bundle bOptions, int userId) {
4681 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4682 != PackageManager.PERMISSION_GRANTED) {
4683 String msg = "Permission Denial: startVoiceActivity() from pid="
4684 + Binder.getCallingPid()
4685 + ", uid=" + Binder.getCallingUid()
4686 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4688 throw new SecurityException(msg);
4690 if (session == null || interactor == null) {
4691 throw new NullPointerException("null session or interactor");
4693 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4694 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4695 // TODO: Switch to user app stacks here.
4696 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4697 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4698 null, bOptions, false, userId, null, "startVoiceActivity");
4702 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4703 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4704 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4705 != PackageManager.PERMISSION_GRANTED) {
4706 final String msg = "Permission Denial: startAssistantActivity() from pid="
4707 + Binder.getCallingPid()
4708 + ", uid=" + Binder.getCallingUid()
4709 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4711 throw new SecurityException(msg);
4713 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4714 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4715 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4716 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4717 userId, null, "startAssistantActivity");
4721 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4722 throws RemoteException {
4723 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4724 synchronized (this) {
4725 ActivityRecord activity = getFocusedStack().topActivity();
4726 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4727 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4729 if (mRunningVoice != null || activity.getTask().voiceSession != null
4730 || activity.voiceSession != null) {
4731 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4734 if (activity.pendingVoiceInteractionStart) {
4735 Slog.w(TAG, "Pending start of voice interaction already.");
4738 activity.pendingVoiceInteractionStart = true;
4740 LocalServices.getService(VoiceInteractionManagerInternal.class)
4741 .startLocalVoiceInteraction(callingActivity, options);
4745 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4746 LocalServices.getService(VoiceInteractionManagerInternal.class)
4747 .stopLocalVoiceInteraction(callingActivity);
4751 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4752 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4753 .supportsLocalVoiceInteraction();
4756 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4757 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4758 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4759 if (activityToCallback == null) return;
4760 activityToCallback.setVoiceSessionLocked(voiceSession);
4762 // Inform the activity
4764 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4766 long token = Binder.clearCallingIdentity();
4768 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4770 Binder.restoreCallingIdentity(token);
4772 // TODO: VI Should we cache the activity so that it's easier to find later
4773 // rather than scan through all the stacks and activities?
4774 } catch (RemoteException re) {
4775 activityToCallback.clearVoiceSessionLocked();
4776 // TODO: VI Should this terminate the voice session?
4781 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4782 synchronized (this) {
4783 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4785 mVoiceWakeLock.acquire();
4787 mVoiceWakeLock.release();
4794 public boolean startNextMatchingActivity(IBinder callingActivity,
4795 Intent intent, Bundle bOptions) {
4796 // Refuse possible leaked file descriptors
4797 if (intent != null && intent.hasFileDescriptors() == true) {
4798 throw new IllegalArgumentException("File descriptors passed in Intent");
4800 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4802 synchronized (this) {
4803 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4805 ActivityOptions.abort(options);
4808 if (r.app == null || r.app.thread == null) {
4809 // The caller is not running... d'oh!
4810 ActivityOptions.abort(options);
4813 intent = new Intent(intent);
4814 // The caller is not allowed to change the data.
4815 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4816 // And we are resetting to find the next component...
4817 intent.setComponent(null);
4819 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4821 ActivityInfo aInfo = null;
4823 List<ResolveInfo> resolves =
4824 AppGlobals.getPackageManager().queryIntentActivities(
4825 intent, r.resolvedType,
4826 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4827 UserHandle.getCallingUserId()).getList();
4829 // Look for the original activity in the list...
4830 final int N = resolves != null ? resolves.size() : 0;
4831 for (int i=0; i<N; i++) {
4832 ResolveInfo rInfo = resolves.get(i);
4833 if (rInfo.activityInfo.packageName.equals(r.packageName)
4834 && rInfo.activityInfo.name.equals(r.info.name)) {
4835 // We found the current one... the next matching is
4839 aInfo = resolves.get(i).activityInfo;
4842 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4843 + "/" + r.info.name);
4844 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4845 ? "null" : aInfo.packageName + "/" + aInfo.name));
4850 } catch (RemoteException e) {
4853 if (aInfo == null) {
4854 // Nobody who is next!
4855 ActivityOptions.abort(options);
4856 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4860 intent.setComponent(new ComponentName(
4861 aInfo.applicationInfo.packageName, aInfo.name));
4862 intent.setFlags(intent.getFlags()&~(
4863 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4864 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4865 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4866 Intent.FLAG_ACTIVITY_NEW_TASK));
4868 // Okay now we need to start the new activity, replacing the
4869 // currently running activity. This is a little tricky because
4870 // we want to start the new one as if the current one is finished,
4871 // but not finish the current one first so that there is no flicker.
4873 final boolean wasFinishing = r.finishing;
4876 // Propagate reply information over to the new activity.
4877 final ActivityRecord resultTo = r.resultTo;
4878 final String resultWho = r.resultWho;
4879 final int requestCode = r.requestCode;
4881 if (resultTo != null) {
4882 resultTo.removeResultsLocked(r, resultWho, requestCode);
4885 final long origId = Binder.clearCallingIdentity();
4886 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4887 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4888 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4889 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4890 false, false, null, null, "startNextMatchingActivity");
4891 Binder.restoreCallingIdentity(origId);
4893 r.finishing = wasFinishing;
4894 if (res != ActivityManager.START_SUCCESS) {
4902 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4903 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4904 String msg = "Permission Denial: startActivityFromRecents called without " +
4905 START_TASKS_FROM_RECENTS;
4907 throw new SecurityException(msg);
4909 final long origId = Binder.clearCallingIdentity();
4911 synchronized (this) {
4912 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4915 Binder.restoreCallingIdentity(origId);
4919 final int startActivityInPackage(int uid, String callingPackage,
4920 Intent intent, String resolvedType, IBinder resultTo,
4921 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4922 TaskRecord inTask, String reason) {
4924 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4925 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4927 // TODO: Switch to user app stacks here.
4928 return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4929 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4930 null, null, null, bOptions, false, userId, inTask, reason);
4934 public final int startActivities(IApplicationThread caller, String callingPackage,
4935 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4937 final String reason = "startActivities";
4938 enforceNotIsolatedCaller(reason);
4939 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4940 userId, false, ALLOW_FULL_ONLY, reason, null);
4941 // TODO: Switch to user app stacks here.
4942 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4943 resolvedTypes, resultTo, bOptions, userId, reason);
4947 final int startActivitiesInPackage(int uid, String callingPackage,
4948 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4949 Bundle bOptions, int userId) {
4951 final String reason = "startActivityInPackage";
4952 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4953 userId, false, ALLOW_FULL_ONLY, reason, null);
4954 // TODO: Switch to user app stacks here.
4955 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4956 resultTo, bOptions, userId, reason);
4961 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4962 synchronized (this) {
4963 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4967 r.reportFullyDrawnLocked(restoredFromBundle);
4972 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4973 synchronized (this) {
4974 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4978 final long origId = Binder.clearCallingIdentity();
4980 r.setRequestedOrientation(requestedOrientation);
4982 Binder.restoreCallingIdentity(origId);
4988 public int getRequestedOrientation(IBinder token) {
4989 synchronized (this) {
4990 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4992 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4994 return r.getRequestedOrientation();
4999 public final void requestActivityRelaunch(IBinder token) {
5000 synchronized(this) {
5001 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5005 final long origId = Binder.clearCallingIdentity();
5007 r.forceNewConfig = true;
5008 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5009 true /* preserveWindow */);
5011 Binder.restoreCallingIdentity(origId);
5017 * This is the internal entry point for handling Activity.finish().
5019 * @param token The Binder token referencing the Activity we want to finish.
5020 * @param resultCode Result code, if any, from this Activity.
5021 * @param resultData Result data (Intent), if any, from this Activity.
5022 * @param finishTask Whether to finish the task associated with this Activity.
5024 * @return Returns true if the activity successfully finished, or false if it is still running.
5027 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5029 // Refuse possible leaked file descriptors
5030 if (resultData != null && resultData.hasFileDescriptors() == true) {
5031 throw new IllegalArgumentException("File descriptors passed in Intent");
5034 synchronized(this) {
5035 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5039 // Keep track of the root activity of the task before we finish it
5040 TaskRecord tr = r.getTask();
5041 ActivityRecord rootR = tr.getRootActivity();
5042 if (rootR == null) {
5043 Slog.w(TAG, "Finishing task with all activities already finished");
5045 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5047 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5048 mStackSupervisor.isLastLockedTask(tr)) {
5049 Slog.i(TAG, "Not finishing task in lock task mode");
5050 mStackSupervisor.showLockTaskToast();
5053 if (mController != null) {
5054 // Find the first activity that is not finishing.
5055 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5057 // ask watcher if this is allowed
5058 boolean resumeOK = true;
5060 resumeOK = mController.activityResuming(next.packageName);
5061 } catch (RemoteException e) {
5063 Watchdog.getInstance().setActivityController(null);
5067 Slog.i(TAG, "Not finishing activity because controller resumed");
5072 final long origId = Binder.clearCallingIdentity();
5075 final boolean finishWithRootActivity =
5076 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5077 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5078 || (finishWithRootActivity && r == rootR)) {
5079 // If requested, remove the task that is associated to this activity only if it
5080 // was the root activity in the task. The result code and data is ignored
5081 // because we don't support returning them across task boundaries. Also, to
5082 // keep backwards compatibility we remove the task from recents when finishing
5083 // task with root activity.
5084 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5086 Slog.i(TAG, "Removing task failed to finish activity");
5089 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5090 resultData, "app-request", true);
5092 Slog.i(TAG, "Failed to finish by app-request");
5097 Binder.restoreCallingIdentity(origId);
5103 public final void finishHeavyWeightApp() {
5104 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5105 != PackageManager.PERMISSION_GRANTED) {
5106 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5107 + Binder.getCallingPid()
5108 + ", uid=" + Binder.getCallingUid()
5109 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5111 throw new SecurityException(msg);
5114 synchronized(this) {
5115 if (mHeavyWeightProcess == null) {
5119 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5120 for (int i = 0; i < activities.size(); i++) {
5121 ActivityRecord r = activities.get(i);
5122 if (!r.finishing && r.isInStackLocked()) {
5123 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5124 null, "finish-heavy", true);
5128 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5129 mHeavyWeightProcess.userId, 0));
5130 mHeavyWeightProcess = null;
5135 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5137 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5138 != PackageManager.PERMISSION_GRANTED) {
5139 String msg = "Permission Denial: crashApplication() from pid="
5140 + Binder.getCallingPid()
5141 + ", uid=" + Binder.getCallingUid()
5142 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5144 throw new SecurityException(msg);
5147 synchronized(this) {
5148 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5153 public final void finishSubActivity(IBinder token, String resultWho,
5155 synchronized(this) {
5156 final long origId = Binder.clearCallingIdentity();
5157 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5159 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5161 Binder.restoreCallingIdentity(origId);
5166 public boolean finishActivityAffinity(IBinder token) {
5167 synchronized(this) {
5168 final long origId = Binder.clearCallingIdentity();
5170 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5175 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5177 final TaskRecord task = r.getTask();
5178 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5179 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5180 mStackSupervisor.showLockTaskToast();
5183 return task.getStack().finishActivityAffinityLocked(r);
5185 Binder.restoreCallingIdentity(origId);
5191 public void finishVoiceTask(IVoiceInteractionSession session) {
5192 synchronized (this) {
5193 final long origId = Binder.clearCallingIdentity();
5195 // TODO: VI Consider treating local voice interactions and voice tasks
5197 mStackSupervisor.finishVoiceTask(session);
5199 Binder.restoreCallingIdentity(origId);
5206 public boolean releaseActivityInstance(IBinder token) {
5207 synchronized(this) {
5208 final long origId = Binder.clearCallingIdentity();
5210 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5214 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5216 Binder.restoreCallingIdentity(origId);
5222 public void releaseSomeActivities(IApplicationThread appInt) {
5223 synchronized(this) {
5224 final long origId = Binder.clearCallingIdentity();
5226 ProcessRecord app = getRecordForAppLocked(appInt);
5227 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5229 Binder.restoreCallingIdentity(origId);
5235 public boolean willActivityBeVisible(IBinder token) {
5236 synchronized(this) {
5237 ActivityStack stack = ActivityRecord.getStackLocked(token);
5238 if (stack != null) {
5239 return stack.willActivityBeVisibleLocked(token);
5246 public void overridePendingTransition(IBinder token, String packageName,
5247 int enterAnim, int exitAnim) {
5248 synchronized(this) {
5249 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5254 final long origId = Binder.clearCallingIdentity();
5256 if (self.state == ActivityState.RESUMED
5257 || self.state == ActivityState.PAUSING) {
5258 mWindowManager.overridePendingAppTransition(packageName,
5259 enterAnim, exitAnim, null);
5262 Binder.restoreCallingIdentity(origId);
5267 * Main function for removing an existing process from the activity manager
5268 * as a result of that process going away. Clears out all connections
5271 private final void handleAppDiedLocked(ProcessRecord app,
5272 boolean restarting, boolean allowRestart) {
5274 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5275 false /*replacingPid*/);
5276 if (!kept && !restarting) {
5277 removeLruProcessLocked(app);
5279 ProcessList.remove(pid);
5283 if (mProfileProc == app) {
5284 clearProfilerLocked();
5287 // Remove this application's activities from active lists.
5288 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5290 app.activities.clear();
5292 if (app.instr != null) {
5293 Slog.w(TAG, "Crash of app " + app.processName
5294 + " running instrumentation " + app.instr.mClass);
5295 Bundle info = new Bundle();
5296 info.putString("shortMsg", "Process crashed.");
5297 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5300 mWindowManager.deferSurfaceLayout();
5302 if (!restarting && hasVisibleActivities
5303 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5304 // If there was nothing to resume, and we are not already restarting this process, but
5305 // there is a visible activity that is hosted by the process... then make sure all
5306 // visible activities are running, taking care of restarting this process.
5307 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5310 mWindowManager.continueSurfaceLayout();
5314 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5315 final IBinder threadBinder = thread.asBinder();
5316 // Find the application record.
5317 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5318 final ProcessRecord rec = mLruProcesses.get(i);
5319 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5326 final ProcessRecord getRecordForAppLocked(
5327 IApplicationThread thread) {
5328 if (thread == null) {
5332 int appIndex = getLRURecordIndexForAppLocked(thread);
5333 if (appIndex >= 0) {
5334 return mLruProcesses.get(appIndex);
5337 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5338 // double-check that.
5339 final IBinder threadBinder = thread.asBinder();
5340 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5341 for (int i = pmap.size()-1; i >= 0; i--) {
5342 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5343 for (int j = procs.size()-1; j >= 0; j--) {
5344 final ProcessRecord proc = procs.valueAt(j);
5345 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5346 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5356 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5357 // If there are no longer any background processes running,
5358 // and the app that died was not running instrumentation,
5359 // then tell everyone we are now low on memory.
5360 boolean haveBg = false;
5361 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5362 ProcessRecord rec = mLruProcesses.get(i);
5363 if (rec.thread != null
5364 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5371 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5373 long now = SystemClock.uptimeMillis();
5374 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5377 mLastMemUsageReportTime = now;
5380 final ArrayList<ProcessMemInfo> memInfos
5381 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5382 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5383 long now = SystemClock.uptimeMillis();
5384 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5385 ProcessRecord rec = mLruProcesses.get(i);
5386 if (rec == dyingProc || rec.thread == null) {
5390 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5391 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5393 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5394 // The low memory report is overriding any current
5395 // state for a GC request. Make sure to do
5396 // heavy/important/visible/foreground processes first.
5397 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5398 rec.lastRequestedGc = 0;
5400 rec.lastRequestedGc = rec.lastLowMemory;
5402 rec.reportLowMemory = true;
5403 rec.lastLowMemory = now;
5404 mProcessesToGc.remove(rec);
5405 addProcessToGcListLocked(rec);
5409 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5410 mHandler.sendMessage(msg);
5412 scheduleAppGcsLocked();
5416 final void appDiedLocked(ProcessRecord app) {
5417 appDiedLocked(app, app.pid, app.thread, false);
5420 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5421 boolean fromBinderDied) {
5422 // First check if this ProcessRecord is actually active for the pid.
5423 synchronized (mPidsSelfLocked) {
5424 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5425 if (curProc != app) {
5426 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5431 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5432 synchronized (stats) {
5433 stats.noteProcessDiedLocked(app.info.uid, pid);
5437 if (!fromBinderDied) {
5438 killProcessQuiet(pid);
5440 killProcessGroup(app.uid, pid);
5444 // Clean up already done if the process has been re-started.
5445 if (app.pid == pid && app.thread != null &&
5446 app.thread.asBinder() == thread.asBinder()) {
5447 boolean doLowMem = app.instr == null;
5448 boolean doOomAdj = doLowMem;
5449 if (!app.killedByAm) {
5450 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5451 + ProcessList.makeOomAdjString(app.setAdj)
5452 + ProcessList.makeProcStateString(app.setProcState));
5453 mAllowLowerMemLevel = true;
5455 // Note that we always want to do oom adj to update our state with the
5456 // new number of procs.
5457 mAllowLowerMemLevel = false;
5460 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5461 app.setAdj, app.setProcState);
5462 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5463 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5464 handleAppDiedLocked(app, false, true);
5467 updateOomAdjLocked();
5470 doLowMemReportIfNeededLocked(app);
5472 } else if (app.pid != pid) {
5473 // A new process has already been started.
5474 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5475 + ") has died and restarted (pid " + app.pid + ").");
5476 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5477 } else if (DEBUG_PROCESSES) {
5478 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5479 + thread.asBinder());
5484 * If a stack trace dump file is configured, dump process stack traces.
5485 * @param clearTraces causes the dump file to be erased prior to the new
5486 * traces being written, if true; when false, the new traces will be
5487 * appended to any existing file content.
5488 * @param firstPids of dalvik VM processes to dump stack traces for first
5489 * @param lastPids of dalvik VM processes to dump stack traces for last
5490 * @param nativePids optional list of native pids to dump stack crawls
5492 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5493 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5494 ArrayList<Integer> nativePids) {
5495 ArrayList<Integer> extraPids = null;
5497 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5498 // of the top users at the time of the request.
5499 if (processCpuTracker != null) {
5500 processCpuTracker.init();
5503 } catch (InterruptedException ignored) {
5506 processCpuTracker.update();
5508 // We'll take the stack crawls of just the top apps using CPU.
5509 final int N = processCpuTracker.countWorkingStats();
5510 extraPids = new ArrayList<>();
5511 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5512 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5513 if (lastPids.indexOfKey(stats.pid) >= 0) {
5514 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5516 extraPids.add(stats.pid);
5517 } else if (DEBUG_ANR) {
5518 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5524 boolean useTombstonedForJavaTraces = false;
5527 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5528 if (tracesDirProp.isEmpty()) {
5529 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5530 // dumping scheme. All traces are written to a global trace file (usually
5531 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5532 // the file if requested.
5534 // This mode of operation will be removed in the near future.
5537 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5538 if (globalTracesPath.isEmpty()) {
5539 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5543 tracesFile = new File(globalTracesPath);
5545 if (clearTraces && tracesFile.exists()) {
5546 tracesFile.delete();
5549 tracesFile.createNewFile();
5550 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5551 } catch (IOException e) {
5552 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5556 File tracesDir = new File(tracesDirProp);
5557 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5558 // Each set of ANR traces is written to a separate file and dumpstate will process
5559 // all such files and add them to a captured bug report if they're recent enough.
5560 maybePruneOldTraces(tracesDir);
5562 // NOTE: We should consider creating the file in native code atomically once we've
5563 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5565 tracesFile = createAnrDumpFile(tracesDir);
5566 if (tracesFile == null) {
5570 useTombstonedForJavaTraces = true;
5573 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5574 useTombstonedForJavaTraces);
5578 @GuardedBy("ActivityManagerService.class")
5579 private static SimpleDateFormat sAnrFileDateFormat;
5581 private static synchronized File createAnrDumpFile(File tracesDir) {
5582 if (sAnrFileDateFormat == null) {
5583 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5586 final String formattedDate = sAnrFileDateFormat.format(new Date());
5587 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5590 if (anrFile.createNewFile()) {
5591 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5594 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5596 } catch (IOException ioe) {
5597 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5604 * Prune all trace files that are more than a day old.
5606 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5607 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5608 * since it's the system_server that creates trace files for most ANRs.
5610 private static void maybePruneOldTraces(File tracesDir) {
5611 final long now = System.currentTimeMillis();
5612 final File[] traceFiles = tracesDir.listFiles();
5614 if (traceFiles != null) {
5615 for (File file : traceFiles) {
5616 if ((now - file.lastModified()) > DAY_IN_MILLIS) {
5617 if (!file.delete()) {
5618 Slog.w(TAG, "Unable to prune stale trace file: " + file);
5626 * Legacy code, do not use. Existing users will be deleted.
5631 public static class DumpStackFileObserver extends FileObserver {
5632 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5633 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5635 private final String mTracesPath;
5636 private boolean mClosed;
5638 public DumpStackFileObserver(String tracesPath) {
5639 super(tracesPath, FileObserver.CLOSE_WRITE);
5640 mTracesPath = tracesPath;
5644 public synchronized void onEvent(int event, String path) {
5649 public long dumpWithTimeout(int pid, long timeout) {
5650 sendSignal(pid, SIGNAL_QUIT);
5651 final long start = SystemClock.elapsedRealtime();
5653 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5654 synchronized (this) {
5656 wait(waitTime); // Wait for traces file to be closed.
5657 } catch (InterruptedException e) {
5662 // This avoids a corner case of passing a negative time to the native
5663 // trace in case we've already hit the overall timeout.
5664 final long timeWaited = SystemClock.elapsedRealtime() - start;
5665 if (timeWaited >= timeout) {
5670 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5671 ". Attempting native stack collection.");
5673 final long nativeDumpTimeoutMs = Math.min(
5674 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5676 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5677 (int) (nativeDumpTimeoutMs / 1000));
5680 final long end = SystemClock.elapsedRealtime();
5683 return (end - start);
5688 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5689 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5690 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5691 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5694 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5695 final long timeStart = SystemClock.elapsedRealtime();
5696 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5697 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5698 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5701 return SystemClock.elapsedRealtime() - timeStart;
5704 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5705 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5706 boolean useTombstonedForJavaTraces) {
5708 // We don't need any sort of inotify based monitoring when we're dumping traces via
5709 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5710 // control of all writes to the file in question.
5711 final DumpStackFileObserver observer;
5712 if (useTombstonedForJavaTraces) {
5715 // Use a FileObserver to detect when traces finish writing.
5716 // The order of traces is considered important to maintain for legibility.
5717 observer = new DumpStackFileObserver(tracesFile);
5720 // We must complete all stack dumps within 20 seconds.
5721 long remainingTime = 20 * 1000;
5723 if (observer != null) {
5724 observer.startWatching();
5727 // First collect all of the stacks of the most important pids.
5728 if (firstPids != null) {
5729 int num = firstPids.size();
5730 for (int i = 0; i < num; i++) {
5731 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5732 + firstPids.get(i));
5733 final long timeTaken;
5734 if (useTombstonedForJavaTraces) {
5735 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5737 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5740 remainingTime -= timeTaken;
5741 if (remainingTime <= 0) {
5742 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5743 "); deadline exceeded.");
5748 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5753 // Next collect the stacks of the native pids
5754 if (nativePids != null) {
5755 for (int pid : nativePids) {
5756 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5757 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5759 final long start = SystemClock.elapsedRealtime();
5760 Debug.dumpNativeBacktraceToFileTimeout(
5761 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5762 final long timeTaken = SystemClock.elapsedRealtime() - start;
5764 remainingTime -= timeTaken;
5765 if (remainingTime <= 0) {
5766 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5767 "); deadline exceeded.");
5772 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5777 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5778 if (extraPids != null) {
5779 for (int pid : extraPids) {
5780 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5782 final long timeTaken;
5783 if (useTombstonedForJavaTraces) {
5784 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5786 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5789 remainingTime -= timeTaken;
5790 if (remainingTime <= 0) {
5791 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5792 "); deadline exceeded.");
5797 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5802 if (observer != null) {
5803 observer.stopWatching();
5808 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5809 if (true || Build.IS_USER) {
5812 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5813 if (tracesPath == null || tracesPath.length() == 0) {
5817 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5818 StrictMode.allowThreadDiskWrites();
5820 final File tracesFile = new File(tracesPath);
5821 final File tracesDir = tracesFile.getParentFile();
5822 final File tracesTmp = new File(tracesDir, "__tmp__");
5824 if (tracesFile.exists()) {
5826 tracesFile.renameTo(tracesTmp);
5828 StringBuilder sb = new StringBuilder();
5829 Time tobj = new Time();
5830 tobj.set(System.currentTimeMillis());
5831 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5833 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5834 sb.append(" since ");
5836 FileOutputStream fos = new FileOutputStream(tracesFile);
5837 fos.write(sb.toString().getBytes());
5839 fos.write("\n*** No application process!".getBytes());
5842 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5843 } catch (IOException e) {
5844 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5849 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5850 firstPids.add(app.pid);
5851 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5854 File lastTracesFile = null;
5855 File curTracesFile = null;
5856 for (int i=9; i>=0; i--) {
5857 String name = String.format(Locale.US, "slow%02d.txt", i);
5858 curTracesFile = new File(tracesDir, name);
5859 if (curTracesFile.exists()) {
5860 if (lastTracesFile != null) {
5861 curTracesFile.renameTo(lastTracesFile);
5863 curTracesFile.delete();
5866 lastTracesFile = curTracesFile;
5868 tracesFile.renameTo(curTracesFile);
5869 if (tracesTmp.exists()) {
5870 tracesTmp.renameTo(tracesFile);
5873 StrictMode.setThreadPolicy(oldPolicy);
5877 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5878 if (!mLaunchWarningShown) {
5879 mLaunchWarningShown = true;
5880 mUiHandler.post(new Runnable() {
5883 synchronized (ActivityManagerService.this) {
5884 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5886 mUiHandler.postDelayed(new Runnable() {
5889 synchronized (ActivityManagerService.this) {
5891 mLaunchWarningShown = false;
5902 public boolean clearApplicationUserData(final String packageName,
5903 final IPackageDataObserver observer, int userId) {
5904 enforceNotIsolatedCaller("clearApplicationUserData");
5905 int uid = Binder.getCallingUid();
5906 int pid = Binder.getCallingPid();
5907 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5908 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5910 final ApplicationInfo appInfo;
5911 final boolean isInstantApp;
5913 long callingId = Binder.clearCallingIdentity();
5915 IPackageManager pm = AppGlobals.getPackageManager();
5916 synchronized(this) {
5917 // Instant packages are not protected
5918 if (getPackageManagerInternalLocked().isPackageDataProtected(
5919 resolvedUserId, packageName)) {
5920 throw new SecurityException(
5921 "Cannot clear data for a protected package: " + packageName);
5924 ApplicationInfo applicationInfo = null;
5926 applicationInfo = pm.getApplicationInfo(packageName,
5927 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5928 } catch (RemoteException e) {
5931 appInfo = applicationInfo;
5933 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5935 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5936 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5937 throw new SecurityException("PID " + pid + " does not have permission "
5938 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5939 + " of package " + packageName);
5942 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5943 .hasInstantApplicationMetadata(packageName, resolvedUserId);
5944 final boolean isUninstalledAppWithoutInstantMetadata =
5945 (appInfo == null && !hasInstantMetadata);
5946 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5947 || hasInstantMetadata;
5948 final boolean canAccessInstantApps = checkComponentPermission(
5949 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5950 == PackageManager.PERMISSION_GRANTED;
5952 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5953 && !canAccessInstantApps)) {
5954 Slog.w(TAG, "Invalid packageName: " + packageName);
5955 if (observer != null) {
5957 observer.onRemoveCompleted(packageName, false);
5958 } catch (RemoteException e) {
5959 Slog.i(TAG, "Observer no longer exists.");
5965 if (appInfo != null) {
5966 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5967 // Remove all tasks match the cleared application package and user
5968 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5969 final TaskRecord tr = mRecentTasks.get(i);
5970 final String taskPackageName =
5971 tr.getBaseIntent().getComponent().getPackageName();
5972 if (tr.userId != resolvedUserId) continue;
5973 if (!taskPackageName.equals(packageName)) continue;
5974 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5975 REMOVE_FROM_RECENTS);
5980 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5982 public void onRemoveCompleted(String packageName, boolean succeeded)
5983 throws RemoteException {
5984 if (appInfo != null) {
5985 synchronized (ActivityManagerService.this) {
5986 finishForceStopPackageLocked(packageName, appInfo.uid);
5989 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5990 Uri.fromParts("package", packageName, null));
5991 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5992 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5993 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5995 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5996 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5997 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6000 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6001 null, null, null, null, false, false, resolvedUserId);
6004 if (observer != null) {
6005 observer.onRemoveCompleted(packageName, succeeded);
6011 // Clear application user data
6012 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6014 if (appInfo != null) {
6015 synchronized (this) {
6016 // Remove all permissions granted from/to this package
6017 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6020 // Reset notification settings.
6021 INotificationManager inm = NotificationManager.getService();
6022 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6024 } catch (RemoteException e) {
6027 Binder.restoreCallingIdentity(callingId);
6033 public void killBackgroundProcesses(final String packageName, int userId) {
6034 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6035 != PackageManager.PERMISSION_GRANTED &&
6036 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6037 != PackageManager.PERMISSION_GRANTED) {
6038 String msg = "Permission Denial: killBackgroundProcesses() from pid="
6039 + Binder.getCallingPid()
6040 + ", uid=" + Binder.getCallingUid()
6041 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6043 throw new SecurityException(msg);
6046 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6047 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6048 long callingId = Binder.clearCallingIdentity();
6050 IPackageManager pm = AppGlobals.getPackageManager();
6051 synchronized(this) {
6054 appId = UserHandle.getAppId(
6055 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6056 } catch (RemoteException e) {
6059 Slog.w(TAG, "Invalid packageName: " + packageName);
6062 killPackageProcessesLocked(packageName, appId, userId,
6063 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6066 Binder.restoreCallingIdentity(callingId);
6071 public void killAllBackgroundProcesses() {
6072 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6073 != PackageManager.PERMISSION_GRANTED) {
6074 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6075 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6076 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6078 throw new SecurityException(msg);
6081 final long callingId = Binder.clearCallingIdentity();
6083 synchronized (this) {
6084 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6085 final int NP = mProcessNames.getMap().size();
6086 for (int ip = 0; ip < NP; ip++) {
6087 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6088 final int NA = apps.size();
6089 for (int ia = 0; ia < NA; ia++) {
6090 final ProcessRecord app = apps.valueAt(ia);
6091 if (app.persistent) {
6092 // We don't kill persistent processes.
6097 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6104 final int N = procs.size();
6105 for (int i = 0; i < N; i++) {
6106 removeProcessLocked(procs.get(i), false, true, "kill all background");
6109 mAllowLowerMemLevel = true;
6111 updateOomAdjLocked();
6112 doLowMemReportIfNeededLocked(null);
6115 Binder.restoreCallingIdentity(callingId);
6120 * Kills all background processes, except those matching any of the
6121 * specified properties.
6123 * @param minTargetSdk the target SDK version at or above which to preserve
6124 * processes, or {@code -1} to ignore the target SDK
6125 * @param maxProcState the process state at or below which to preserve
6126 * processes, or {@code -1} to ignore the process state
6128 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6129 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6130 != PackageManager.PERMISSION_GRANTED) {
6131 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6132 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6133 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6135 throw new SecurityException(msg);
6138 final long callingId = Binder.clearCallingIdentity();
6140 synchronized (this) {
6141 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6142 final int NP = mProcessNames.getMap().size();
6143 for (int ip = 0; ip < NP; ip++) {
6144 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6145 final int NA = apps.size();
6146 for (int ia = 0; ia < NA; ia++) {
6147 final ProcessRecord app = apps.valueAt(ia);
6150 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6151 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6158 final int N = procs.size();
6159 for (int i = 0; i < N; i++) {
6160 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6164 Binder.restoreCallingIdentity(callingId);
6169 public void forceStopPackage(final String packageName, int userId) {
6170 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6171 != PackageManager.PERMISSION_GRANTED) {
6172 String msg = "Permission Denial: forceStopPackage() from pid="
6173 + Binder.getCallingPid()
6174 + ", uid=" + Binder.getCallingUid()
6175 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6177 throw new SecurityException(msg);
6179 final int callingPid = Binder.getCallingPid();
6180 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6181 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6182 long callingId = Binder.clearCallingIdentity();
6184 IPackageManager pm = AppGlobals.getPackageManager();
6185 synchronized(this) {
6186 int[] users = userId == UserHandle.USER_ALL
6187 ? mUserController.getUsers() : new int[] { userId };
6188 for (int user : users) {
6191 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6193 } catch (RemoteException e) {
6196 Slog.w(TAG, "Invalid packageName: " + packageName);
6200 pm.setPackageStoppedState(packageName, true, user);
6201 } catch (RemoteException e) {
6202 } catch (IllegalArgumentException e) {
6203 Slog.w(TAG, "Failed trying to unstop package "
6204 + packageName + ": " + e);
6206 if (mUserController.isUserRunningLocked(user, 0)) {
6207 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6208 finishForceStopPackageLocked(packageName, pkgUid);
6213 Binder.restoreCallingIdentity(callingId);
6218 public void addPackageDependency(String packageName) {
6219 synchronized (this) {
6220 int callingPid = Binder.getCallingPid();
6221 if (callingPid == myPid()) {
6226 synchronized (mPidsSelfLocked) {
6227 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6230 if (proc.pkgDeps == null) {
6231 proc.pkgDeps = new ArraySet<String>(1);
6233 proc.pkgDeps.add(packageName);
6239 * The pkg name and app id have to be specified.
6242 public void killApplication(String pkg, int appId, int userId, String reason) {
6246 // Make sure the uid is valid.
6248 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6251 int callerUid = Binder.getCallingUid();
6252 // Only the system server can kill an application
6253 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6254 // Post an aysnc message to kill the application
6255 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6258 Bundle bundle = new Bundle();
6259 bundle.putString("pkg", pkg);
6260 bundle.putString("reason", reason);
6262 mHandler.sendMessage(msg);
6264 throw new SecurityException(callerUid + " cannot kill pkg: " +
6270 public void closeSystemDialogs(String reason) {
6271 enforceNotIsolatedCaller("closeSystemDialogs");
6273 final int pid = Binder.getCallingPid();
6274 final int uid = Binder.getCallingUid();
6275 final long origId = Binder.clearCallingIdentity();
6277 synchronized (this) {
6278 // Only allow this from foreground processes, so that background
6279 // applications can't abuse it to prevent system UI from being shown.
6280 if (uid >= FIRST_APPLICATION_UID) {
6282 synchronized (mPidsSelfLocked) {
6283 proc = mPidsSelfLocked.get(pid);
6285 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6286 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6287 + " from background process " + proc);
6291 closeSystemDialogsLocked(reason);
6294 Binder.restoreCallingIdentity(origId);
6298 void closeSystemDialogsLocked(String reason) {
6299 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6300 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6301 | Intent.FLAG_RECEIVER_FOREGROUND);
6302 if (reason != null) {
6303 intent.putExtra("reason", reason);
6305 mWindowManager.closeSystemDialogs(reason);
6307 mStackSupervisor.closeSystemDialogsLocked();
6309 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6310 AppOpsManager.OP_NONE, null, false, false,
6311 -1, SYSTEM_UID, UserHandle.USER_ALL);
6315 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6316 enforceNotIsolatedCaller("getProcessMemoryInfo");
6317 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6318 for (int i=pids.length-1; i>=0; i--) {
6321 synchronized (this) {
6322 synchronized (mPidsSelfLocked) {
6323 proc = mPidsSelfLocked.get(pids[i]);
6324 oomAdj = proc != null ? proc.setAdj : 0;
6327 infos[i] = new Debug.MemoryInfo();
6328 Debug.getMemoryInfo(pids[i], infos[i]);
6330 synchronized (this) {
6331 if (proc.thread != null && proc.setAdj == oomAdj) {
6332 // Record this for posterity if the process has been stable.
6333 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6334 infos[i].getTotalUss(), false, proc.pkgList);
6343 public long[] getProcessPss(int[] pids) {
6344 enforceNotIsolatedCaller("getProcessPss");
6345 long[] pss = new long[pids.length];
6346 for (int i=pids.length-1; i>=0; i--) {
6349 synchronized (this) {
6350 synchronized (mPidsSelfLocked) {
6351 proc = mPidsSelfLocked.get(pids[i]);
6352 oomAdj = proc != null ? proc.setAdj : 0;
6355 long[] tmpUss = new long[1];
6356 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6358 synchronized (this) {
6359 if (proc.thread != null && proc.setAdj == oomAdj) {
6360 // Record this for posterity if the process has been stable.
6361 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6370 public void killApplicationProcess(String processName, int uid) {
6371 if (processName == null) {
6375 int callerUid = Binder.getCallingUid();
6376 // Only the system server can kill an application
6377 if (callerUid == SYSTEM_UID) {
6378 synchronized (this) {
6379 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6380 if (app != null && app.thread != null) {
6382 app.thread.scheduleSuicide();
6383 } catch (RemoteException e) {
6384 // If the other end already died, then our work here is done.
6387 Slog.w(TAG, "Process/uid not found attempting kill of "
6388 + processName + " / " + uid);
6392 throw new SecurityException(callerUid + " cannot kill app process: " +
6397 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6398 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6399 false, true, false, false, UserHandle.getUserId(uid), reason);
6402 private void finishForceStopPackageLocked(final String packageName, int uid) {
6403 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6404 Uri.fromParts("package", packageName, null));
6405 if (!mProcessesReady) {
6406 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6407 | Intent.FLAG_RECEIVER_FOREGROUND);
6409 intent.putExtra(Intent.EXTRA_UID, uid);
6410 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6411 broadcastIntentLocked(null, null, intent,
6412 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6413 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6417 private final boolean killPackageProcessesLocked(String packageName, int appId,
6418 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6419 boolean doit, boolean evenPersistent, String reason) {
6420 ArrayList<ProcessRecord> procs = new ArrayList<>();
6422 // Remove all processes this package may have touched: all with the
6423 // same UID (except for the system or root user), and all whose name
6424 // matches the package name.
6425 final int NP = mProcessNames.getMap().size();
6426 for (int ip=0; ip<NP; ip++) {
6427 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6428 final int NA = apps.size();
6429 for (int ia=0; ia<NA; ia++) {
6430 ProcessRecord app = apps.valueAt(ia);
6431 if (app.persistent && !evenPersistent) {
6432 // we don't kill persistent processes
6442 // Skip process if it doesn't meet our oom adj requirement.
6443 if (app.setAdj < minOomAdj) {
6447 // If no package is specified, we call all processes under the
6449 if (packageName == null) {
6450 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6453 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6456 // Package has been specified, we want to hit all processes
6457 // that match it. We need to qualify this by the processes
6458 // that are running under the specified app and user ID.
6460 final boolean isDep = app.pkgDeps != null
6461 && app.pkgDeps.contains(packageName);
6462 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6465 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6468 if (!app.pkgList.containsKey(packageName) && !isDep) {
6473 // Process has passed all conditions, kill it!
6482 int N = procs.size();
6483 for (int i=0; i<N; i++) {
6484 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6486 updateOomAdjLocked();
6490 private void cleanupDisabledPackageComponentsLocked(
6491 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6493 Set<String> disabledClasses = null;
6494 boolean packageDisabled = false;
6495 IPackageManager pm = AppGlobals.getPackageManager();
6497 if (changedClasses == null) {
6498 // Nothing changed...
6502 // Determine enable/disable state of the package and its components.
6503 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6504 for (int i = changedClasses.length - 1; i >= 0; i--) {
6505 final String changedClass = changedClasses[i];
6507 if (changedClass.equals(packageName)) {
6509 // Entire package setting changed
6510 enabled = pm.getApplicationEnabledSetting(packageName,
6511 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6512 } catch (Exception e) {
6513 // No such package/component; probably racing with uninstall. In any
6514 // event it means we have nothing further to do here.
6517 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6518 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6519 if (packageDisabled) {
6520 // Entire package is disabled.
6521 // No need to continue to check component states.
6522 disabledClasses = null;
6527 enabled = pm.getComponentEnabledSetting(
6528 new ComponentName(packageName, changedClass),
6529 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6530 } catch (Exception e) {
6531 // As above, probably racing with uninstall.
6534 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6535 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6536 if (disabledClasses == null) {
6537 disabledClasses = new ArraySet<>(changedClasses.length);
6539 disabledClasses.add(changedClass);
6544 if (!packageDisabled && disabledClasses == null) {
6545 // Nothing to do here...
6549 // Clean-up disabled activities.
6550 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6551 packageName, disabledClasses, true, false, userId) && mBooted) {
6552 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6553 mStackSupervisor.scheduleIdleLocked();
6556 // Clean-up disabled tasks
6557 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6559 // Clean-up disabled services.
6560 mServices.bringDownDisabledPackageServicesLocked(
6561 packageName, disabledClasses, userId, false, killProcess, true);
6563 // Clean-up disabled providers.
6564 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6565 mProviderMap.collectPackageProvidersLocked(
6566 packageName, disabledClasses, true, false, userId, providers);
6567 for (int i = providers.size() - 1; i >= 0; i--) {
6568 removeDyingProviderLocked(null, providers.get(i), true);
6571 // Clean-up disabled broadcast receivers.
6572 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6573 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6574 packageName, disabledClasses, userId, true);
6579 final boolean clearBroadcastQueueForUserLocked(int userId) {
6580 boolean didSomething = false;
6581 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6582 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6583 null, null, userId, true);
6585 return didSomething;
6588 final boolean forceStopPackageLocked(String packageName, int appId,
6589 boolean callerWillRestart, boolean purgeCache, boolean doit,
6590 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6593 if (userId == UserHandle.USER_ALL && packageName == null) {
6594 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6597 if (appId < 0 && packageName != null) {
6599 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6600 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6601 } catch (RemoteException e) {
6606 if (packageName != null) {
6607 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6608 + " user=" + userId + ": " + reason);
6610 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6613 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6616 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6617 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6618 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6620 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6622 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6623 packageName, null, doit, evenPersistent, userId)) {
6627 didSomething = true;
6630 if (mServices.bringDownDisabledPackageServicesLocked(
6631 packageName, null, userId, evenPersistent, true, doit)) {
6635 didSomething = true;
6638 if (packageName == null) {
6639 // Remove all sticky broadcasts from this user.
6640 mStickyBroadcasts.remove(userId);
6643 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6644 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6645 userId, providers)) {
6649 didSomething = true;
6651 for (i = providers.size() - 1; i >= 0; i--) {
6652 removeDyingProviderLocked(null, providers.get(i), true);
6655 // Remove transient permissions granted from/to this package/user
6656 removeUriPermissionsForPackageLocked(packageName, userId, false);
6659 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6660 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6661 packageName, null, userId, doit);
6665 if (packageName == null || uninstalling) {
6666 // Remove pending intents. For now we only do this when force
6667 // stopping users, because we have some problems when doing this
6668 // for packages -- app widgets are not currently cleaned up for
6669 // such packages, so they can be left with bad pending intents.
6670 if (mIntentSenderRecords.size() > 0) {
6671 Iterator<WeakReference<PendingIntentRecord>> it
6672 = mIntentSenderRecords.values().iterator();
6673 while (it.hasNext()) {
6674 WeakReference<PendingIntentRecord> wpir = it.next();
6679 PendingIntentRecord pir = wpir.get();
6684 if (packageName == null) {
6685 // Stopping user, remove all objects for the user.
6686 if (pir.key.userId != userId) {
6687 // Not the same user, skip it.
6691 if (UserHandle.getAppId(pir.uid) != appId) {
6692 // Different app id, skip it.
6695 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6696 // Different user, skip it.
6699 if (!pir.key.packageName.equals(packageName)) {
6700 // Different package, skip it.
6707 didSomething = true;
6709 makeIntentSenderCanceledLocked(pir);
6710 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6711 pir.key.activity.pendingResults.remove(pir.ref);
6718 if (purgeCache && packageName != null) {
6719 AttributeCache ac = AttributeCache.instance();
6721 ac.removePackage(packageName);
6725 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6726 mStackSupervisor.scheduleIdleLocked();
6730 return didSomething;
6733 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6734 return removeProcessNameLocked(name, uid, null);
6737 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6738 final ProcessRecord expecting) {
6739 ProcessRecord old = mProcessNames.get(name, uid);
6740 // Only actually remove when the currently recorded value matches the
6741 // record that we expected; if it doesn't match then we raced with a
6742 // newly created process and we don't want to destroy the new one.
6743 if ((expecting == null) || (old == expecting)) {
6744 mProcessNames.remove(name, uid);
6746 if (old != null && old.uidRecord != null) {
6747 old.uidRecord.numProcs--;
6748 if (old.uidRecord.numProcs == 0) {
6749 // No more processes using this uid, tell clients it is gone.
6750 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6751 "No more processes in " + old.uidRecord);
6752 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6753 EventLogTags.writeAmUidStopped(uid);
6754 mActiveUids.remove(uid);
6755 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6757 old.uidRecord = null;
6759 mIsolatedProcesses.remove(uid);
6763 private final void addProcessNameLocked(ProcessRecord proc) {
6764 // We shouldn't already have a process under this name, but just in case we
6765 // need to clean up whatever may be there now.
6766 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6767 if (old == proc && proc.persistent) {
6768 // We are re-adding a persistent process. Whatevs! Just leave it there.
6769 Slog.w(TAG, "Re-adding persistent process " + proc);
6770 } else if (old != null) {
6771 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6773 UidRecord uidRec = mActiveUids.get(proc.uid);
6774 if (uidRec == null) {
6775 uidRec = new UidRecord(proc.uid);
6776 // This is the first appearance of the uid, report it now!
6777 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6778 "Creating new process uid: " + uidRec);
6779 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6780 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6781 uidRec.setWhitelist = uidRec.curWhitelist = true;
6783 uidRec.updateHasInternetPermission();
6784 mActiveUids.put(proc.uid, uidRec);
6785 EventLogTags.writeAmUidRunning(uidRec.uid);
6786 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6788 proc.uidRecord = uidRec;
6790 // Reset render thread tid if it was already set, so new process can set it again.
6791 proc.renderThreadTid = 0;
6793 mProcessNames.put(proc.processName, proc.uid, proc);
6794 if (proc.isolated) {
6795 mIsolatedProcesses.put(proc.uid, proc);
6799 boolean removeProcessLocked(ProcessRecord app,
6800 boolean callerWillRestart, boolean allowRestart, String reason) {
6801 final String name = app.processName;
6802 final int uid = app.uid;
6803 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6804 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6806 ProcessRecord old = mProcessNames.get(name, uid);
6808 // This process is no longer active, so nothing to do.
6809 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6812 removeProcessNameLocked(name, uid);
6813 if (mHeavyWeightProcess == app) {
6814 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6815 mHeavyWeightProcess.userId, 0));
6816 mHeavyWeightProcess = null;
6818 boolean needRestart = false;
6819 if (app.pid > 0 && app.pid != MY_PID) {
6821 synchronized (mPidsSelfLocked) {
6822 mPidsSelfLocked.remove(pid);
6823 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6825 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6826 boolean willRestart = false;
6827 if (app.persistent && !app.isolated) {
6828 if (!callerWillRestart) {
6834 app.kill(reason, true);
6836 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6837 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6839 handleAppDiedLocked(app, willRestart, allowRestart);
6841 removeLruProcessLocked(app);
6842 addAppLocked(app.info, null, false, null /* ABI override */);
6845 mRemovedProcesses.add(app);
6851 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6852 cleanupAppInLaunchingProvidersLocked(app, true);
6853 removeProcessLocked(app, false, true, "timeout publishing content providers");
6856 private final void processStartTimedOutLocked(ProcessRecord app) {
6857 final int pid = app.pid;
6858 boolean gone = false;
6859 synchronized (mPidsSelfLocked) {
6860 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6861 if (knownApp != null && knownApp.thread == null) {
6862 mPidsSelfLocked.remove(pid);
6868 Slog.w(TAG, "Process " + app + " failed to attach");
6869 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6870 pid, app.uid, app.processName);
6871 removeProcessNameLocked(app.processName, app.uid);
6872 if (mHeavyWeightProcess == app) {
6873 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6874 mHeavyWeightProcess.userId, 0));
6875 mHeavyWeightProcess = null;
6877 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6878 // Take care of any launching providers waiting for this process.
6879 cleanupAppInLaunchingProvidersLocked(app, true);
6880 // Take care of any services that are waiting for the process.
6881 mServices.processStartTimedOutLocked(app);
6882 app.kill("start timeout", true);
6884 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6886 removeLruProcessLocked(app);
6887 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6888 Slog.w(TAG, "Unattached app died before backup, skipping");
6889 mHandler.post(new Runnable() {
6893 IBackupManager bm = IBackupManager.Stub.asInterface(
6894 ServiceManager.getService(Context.BACKUP_SERVICE));
6895 bm.agentDisconnected(app.info.packageName);
6896 } catch (RemoteException e) {
6897 // Can't happen; the backup manager is local
6902 if (isPendingBroadcastProcessLocked(pid)) {
6903 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6904 skipPendingBroadcastLocked(pid);
6907 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6911 private final boolean attachApplicationLocked(IApplicationThread thread,
6914 // Find the application record that is being attached... either via
6915 // the pid if we are running in multiple processes, or just pull the
6916 // next app record if we are emulating process with anonymous threads.
6918 long startTime = SystemClock.uptimeMillis();
6919 if (pid != MY_PID && pid >= 0) {
6920 synchronized (mPidsSelfLocked) {
6921 app = mPidsSelfLocked.get(pid);
6928 Slog.w(TAG, "No pending application record for pid " + pid
6929 + " (IApplicationThread " + thread + "); dropping process");
6930 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6931 if (pid > 0 && pid != MY_PID) {
6932 killProcessQuiet(pid);
6933 //TODO: killProcessGroup(app.info.uid, pid);
6936 thread.scheduleExit();
6937 } catch (Exception e) {
6938 // Ignore exceptions.
6944 // If this application record is still attached to a previous
6945 // process, clean it up now.
6946 if (app.thread != null) {
6947 handleAppDiedLocked(app, true, true);
6950 // Tell the process all about itself.
6952 if (DEBUG_ALL) Slog.v(
6953 TAG, "Binding process pid " + pid + " to record " + app);
6955 final String processName = app.processName;
6957 AppDeathRecipient adr = new AppDeathRecipient(
6959 thread.asBinder().linkToDeath(adr, 0);
6960 app.deathRecipient = adr;
6961 } catch (RemoteException e) {
6962 app.resetPackageList(mProcessStats);
6963 startProcessLocked(app, "link fail", processName);
6967 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6969 app.makeActive(thread, mProcessStats);
6970 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6971 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6972 app.forcingToImportant = null;
6973 updateProcessForegroundLocked(app, false, false);
6974 app.hasShownUi = false;
6975 app.debugging = false;
6977 app.killedByAm = false;
6981 // We carefully use the same state that PackageManager uses for
6982 // filtering, since we use this flag to decide if we need to install
6983 // providers when user is unlocked later
6984 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6986 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6988 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6989 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6991 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6992 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6994 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6997 checkTime(startTime, "attachApplicationLocked: before bindApplication");
7000 Slog.i(TAG, "Launching preboot mode app: " + app);
7003 if (DEBUG_ALL) Slog.v(
7004 TAG, "New app record " + app
7005 + " thread=" + thread.asBinder() + " pid=" + pid);
7007 int testMode = ApplicationThreadConstants.DEBUG_OFF;
7008 if (mDebugApp != null && mDebugApp.equals(processName)) {
7009 testMode = mWaitForDebugger
7010 ? ApplicationThreadConstants.DEBUG_WAIT
7011 : ApplicationThreadConstants.DEBUG_ON;
7012 app.debugging = true;
7013 if (mDebugTransient) {
7014 mDebugApp = mOrigDebugApp;
7015 mWaitForDebugger = mOrigWaitForDebugger;
7019 ProfilerInfo profilerInfo = null;
7020 String agent = null;
7021 if (mProfileApp != null && mProfileApp.equals(processName)) {
7023 profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7024 new ProfilerInfo(mProfilerInfo) : null;
7025 agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7026 } else if (app.instr != null && app.instr.mProfileFile != null) {
7027 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7031 boolean enableTrackAllocation = false;
7032 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7033 enableTrackAllocation = true;
7034 mTrackAllocationApp = null;
7037 // If the app is being launched for restore or full backup, set it up specially
7038 boolean isRestrictedBackupMode = false;
7039 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7040 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7041 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7042 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7043 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7046 if (app.instr != null) {
7047 notifyPackageUse(app.instr.mClass.getPackageName(),
7048 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7050 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7051 + processName + " with config " + getGlobalConfiguration());
7052 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7053 app.compat = compatibilityInfoForPackageLocked(appInfo);
7055 if (profilerInfo != null && profilerInfo.profileFd != null) {
7056 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7059 // We deprecated Build.SERIAL and it is not accessible to
7060 // apps that target the v2 security sandbox. Since access to
7061 // the serial is now behind a permission we push down the value.
7062 String buildSerial = appInfo.targetSandboxVersion < 2
7063 ? sTheRealBuildSerial : Build.UNKNOWN;
7065 // Check if this is a secondary process that should be incorporated into some
7066 // currently active instrumentation. (Note we do this AFTER all of the profiling
7067 // stuff above because profiling can currently happen only in the primary
7068 // instrumentation process.)
7069 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7070 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7071 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7072 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7073 if (aInstr.mTargetProcesses.length == 0) {
7074 // This is the wildcard mode, where every process brought up for
7075 // the target instrumentation should be included.
7076 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7078 aInstr.mRunningProcesses.add(app);
7081 for (String proc : aInstr.mTargetProcesses) {
7082 if (proc.equals(app.processName)) {
7084 aInstr.mRunningProcesses.add(app);
7093 // If we were asked to attach an agent on startup, do so now, before we're binding
7094 // application code.
7095 if (agent != null) {
7096 thread.attachAgent(agent);
7099 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7100 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7101 if (app.instr != null) {
7102 thread.bindApplication(processName, appInfo, providers,
7104 profilerInfo, app.instr.mArguments,
7106 app.instr.mUiAutomationConnection, testMode,
7107 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7108 isRestrictedBackupMode || !normalMode, app.persistent,
7109 new Configuration(getGlobalConfiguration()), app.compat,
7110 getCommonServicesLocked(app.isolated),
7111 mCoreSettingsObserver.getCoreSettingsLocked(),
7114 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7115 null, null, null, testMode,
7116 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7117 isRestrictedBackupMode || !normalMode, app.persistent,
7118 new Configuration(getGlobalConfiguration()), app.compat,
7119 getCommonServicesLocked(app.isolated),
7120 mCoreSettingsObserver.getCoreSettingsLocked(),
7124 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7125 updateLruProcessLocked(app, false, null);
7126 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7127 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7128 } catch (Exception e) {
7129 // todo: Yikes! What should we do? For now we will try to
7130 // start another process, but that could easily get us in
7131 // an infinite loop of restarting processes...
7132 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7134 app.resetPackageList(mProcessStats);
7135 app.unlinkDeathRecipient();
7136 startProcessLocked(app, "bind fail", processName);
7140 // Remove this record from the list of starting applications.
7141 mPersistentStartingProcesses.remove(app);
7142 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7143 "Attach application locked removing on hold: " + app);
7144 mProcessesOnHold.remove(app);
7146 boolean badApp = false;
7147 boolean didSomething = false;
7149 // See if the top visible activity is waiting to run in this process...
7152 if (mStackSupervisor.attachApplicationLocked(app)) {
7153 didSomething = true;
7155 } catch (Exception e) {
7156 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7161 // Find any services that should be running in this process...
7164 didSomething |= mServices.attachApplicationLocked(app, processName);
7165 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7166 } catch (Exception e) {
7167 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7172 // Check if a next-broadcast receiver is in this process...
7173 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7175 didSomething |= sendPendingBroadcastsLocked(app);
7176 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7177 } catch (Exception e) {
7178 // If the app died trying to launch the receiver we declare it 'bad'
7179 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7184 // Check whether the next backup agent is in this process...
7185 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7186 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7187 "New app is backup target, launching agent for " + app);
7188 notifyPackageUse(mBackupTarget.appInfo.packageName,
7189 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7191 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7192 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7193 mBackupTarget.backupMode);
7194 } catch (Exception e) {
7195 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7201 app.kill("error during init", true);
7202 handleAppDiedLocked(app, false, true);
7206 if (!didSomething) {
7207 updateOomAdjLocked();
7208 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7215 public final void attachApplication(IApplicationThread thread) {
7216 synchronized (this) {
7217 int callingPid = Binder.getCallingPid();
7218 final long origId = Binder.clearCallingIdentity();
7219 attachApplicationLocked(thread, callingPid);
7220 Binder.restoreCallingIdentity(origId);
7225 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7226 final long origId = Binder.clearCallingIdentity();
7227 synchronized (this) {
7228 ActivityStack stack = ActivityRecord.getStackLocked(token);
7229 if (stack != null) {
7231 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7232 false /* processPausingActivities */, config);
7233 if (stopProfiling) {
7234 if ((mProfileProc == r.app) && mProfilerInfo != null) {
7235 clearProfilerLocked();
7240 Binder.restoreCallingIdentity(origId);
7243 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7244 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7245 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7248 void enableScreenAfterBoot() {
7249 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7250 SystemClock.uptimeMillis());
7251 mWindowManager.enableScreenAfterBoot();
7253 synchronized (this) {
7254 updateEventDispatchingLocked();
7259 public void showBootMessage(final CharSequence msg, final boolean always) {
7260 if (Binder.getCallingUid() != myUid()) {
7261 throw new SecurityException();
7263 mWindowManager.showBootMessage(msg, always);
7267 public void keyguardGoingAway(int flags) {
7268 enforceNotIsolatedCaller("keyguardGoingAway");
7269 final long token = Binder.clearCallingIdentity();
7271 synchronized (this) {
7272 mKeyguardController.keyguardGoingAway(flags);
7275 Binder.restoreCallingIdentity(token);
7280 * @return whther the keyguard is currently locked.
7282 boolean isKeyguardLocked() {
7283 return mKeyguardController.isKeyguardLocked();
7286 final void finishBooting() {
7287 synchronized (this) {
7288 if (!mBootAnimationComplete) {
7289 mCallFinishBooting = true;
7292 mCallFinishBooting = false;
7295 ArraySet<String> completedIsas = new ArraySet<String>();
7296 for (String abi : Build.SUPPORTED_ABIS) {
7297 zygoteProcess.establishZygoteConnectionForAbi(abi);
7298 final String instructionSet = VMRuntime.getInstructionSet(abi);
7299 if (!completedIsas.contains(instructionSet)) {
7301 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7302 } catch (InstallerException e) {
7303 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7304 e.getMessage() +")");
7306 completedIsas.add(instructionSet);
7310 IntentFilter pkgFilter = new IntentFilter();
7311 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7312 pkgFilter.addDataScheme("package");
7313 mContext.registerReceiver(new BroadcastReceiver() {
7315 public void onReceive(Context context, Intent intent) {
7316 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7318 for (String pkg : pkgs) {
7319 synchronized (ActivityManagerService.this) {
7320 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7321 0, "query restart")) {
7322 setResultCode(Activity.RESULT_OK);
7331 IntentFilter dumpheapFilter = new IntentFilter();
7332 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7333 mContext.registerReceiver(new BroadcastReceiver() {
7335 public void onReceive(Context context, Intent intent) {
7336 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7337 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7339 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7344 // Let system services know.
7345 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7347 synchronized (this) {
7348 // Ensure that any processes we had put on hold are now started
7350 final int NP = mProcessesOnHold.size();
7352 ArrayList<ProcessRecord> procs =
7353 new ArrayList<ProcessRecord>(mProcessesOnHold);
7354 for (int ip=0; ip<NP; ip++) {
7355 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7357 startProcessLocked(procs.get(ip), "on-hold", null);
7361 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7362 // Start looking for apps that are abusing wake locks.
7363 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7364 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7365 // Tell anyone interested that we are done booting!
7366 SystemProperties.set("sys.boot_completed", "1");
7368 // And trigger dev.bootcomplete if we are not showing encryption progress
7369 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7370 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7371 SystemProperties.set("dev.bootcomplete", "1");
7373 mUserController.sendBootCompletedLocked(
7374 new IIntentReceiver.Stub() {
7376 public void performReceive(Intent intent, int resultCode,
7377 String data, Bundle extras, boolean ordered,
7378 boolean sticky, int sendingUser) {
7379 synchronized (ActivityManagerService.this) {
7380 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7385 scheduleStartProfilesLocked();
7391 public void bootAnimationComplete() {
7392 final boolean callFinishBooting;
7393 synchronized (this) {
7394 callFinishBooting = mCallFinishBooting;
7395 mBootAnimationComplete = true;
7397 if (callFinishBooting) {
7398 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7400 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7404 final void ensureBootCompleted() {
7406 boolean enableScreen;
7407 synchronized (this) {
7410 enableScreen = !mBooted;
7415 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7417 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7421 enableScreenAfterBoot();
7426 public final void activityResumed(IBinder token) {
7427 final long origId = Binder.clearCallingIdentity();
7428 synchronized(this) {
7429 ActivityRecord.activityResumedLocked(token);
7430 mWindowManager.notifyAppResumedFinished(token);
7432 Binder.restoreCallingIdentity(origId);
7436 public final void activityPaused(IBinder token) {
7437 final long origId = Binder.clearCallingIdentity();
7438 synchronized(this) {
7439 ActivityStack stack = ActivityRecord.getStackLocked(token);
7440 if (stack != null) {
7441 stack.activityPausedLocked(token, false);
7444 Binder.restoreCallingIdentity(origId);
7448 public final void activityStopped(IBinder token, Bundle icicle,
7449 PersistableBundle persistentState, CharSequence description) {
7450 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7452 // Refuse possible leaked file descriptors
7453 if (icicle != null && icicle.hasFileDescriptors()) {
7454 throw new IllegalArgumentException("File descriptors passed in Bundle");
7457 final long origId = Binder.clearCallingIdentity();
7459 synchronized (this) {
7460 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7462 r.activityStoppedLocked(icicle, persistentState, description);
7468 Binder.restoreCallingIdentity(origId);
7472 public final void activityDestroyed(IBinder token) {
7473 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7474 synchronized (this) {
7475 ActivityStack stack = ActivityRecord.getStackLocked(token);
7476 if (stack != null) {
7477 stack.activityDestroyedLocked(token, "activityDestroyed");
7483 public final void activityRelaunched(IBinder token) {
7484 final long origId = Binder.clearCallingIdentity();
7485 synchronized (this) {
7486 mStackSupervisor.activityRelaunchedLocked(token);
7488 Binder.restoreCallingIdentity(origId);
7492 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7493 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7494 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7495 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7496 synchronized (this) {
7497 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7498 if (record == null) {
7499 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7500 + "found for: " + token);
7502 record.setSizeConfigurations(horizontalSizeConfiguration,
7503 verticalSizeConfigurations, smallestSizeConfigurations);
7508 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7509 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7513 public final void notifyEnterAnimationComplete(IBinder token) {
7514 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7518 public String getCallingPackage(IBinder token) {
7519 synchronized (this) {
7520 ActivityRecord r = getCallingRecordLocked(token);
7521 return r != null ? r.info.packageName : null;
7526 public ComponentName getCallingActivity(IBinder token) {
7527 synchronized (this) {
7528 ActivityRecord r = getCallingRecordLocked(token);
7529 return r != null ? r.intent.getComponent() : null;
7533 private ActivityRecord getCallingRecordLocked(IBinder token) {
7534 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7542 public ComponentName getActivityClassForToken(IBinder token) {
7543 synchronized(this) {
7544 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7548 return r.intent.getComponent();
7553 public String getPackageForToken(IBinder token) {
7554 synchronized(this) {
7555 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7559 return r.packageName;
7564 public boolean isRootVoiceInteraction(IBinder token) {
7565 synchronized(this) {
7566 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7570 return r.rootVoiceInteraction;
7575 public IIntentSender getIntentSender(int type,
7576 String packageName, IBinder token, String resultWho,
7577 int requestCode, Intent[] intents, String[] resolvedTypes,
7578 int flags, Bundle bOptions, int userId) {
7579 enforceNotIsolatedCaller("getIntentSender");
7580 // Refuse possible leaked file descriptors
7581 if (intents != null) {
7582 if (intents.length < 1) {
7583 throw new IllegalArgumentException("Intents array length must be >= 1");
7585 for (int i=0; i<intents.length; i++) {
7586 Intent intent = intents[i];
7587 if (intent != null) {
7588 if (intent.hasFileDescriptors()) {
7589 throw new IllegalArgumentException("File descriptors passed in Intent");
7591 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7592 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7593 throw new IllegalArgumentException(
7594 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7596 intents[i] = new Intent(intent);
7599 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7600 throw new IllegalArgumentException(
7601 "Intent array length does not match resolvedTypes length");
7604 if (bOptions != null) {
7605 if (bOptions.hasFileDescriptors()) {
7606 throw new IllegalArgumentException("File descriptors passed in options");
7610 synchronized(this) {
7611 int callingUid = Binder.getCallingUid();
7612 int origUserId = userId;
7613 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7614 type == ActivityManager.INTENT_SENDER_BROADCAST,
7615 ALLOW_NON_FULL, "getIntentSender", null);
7616 if (origUserId == UserHandle.USER_CURRENT) {
7617 // We don't want to evaluate this until the pending intent is
7618 // actually executed. However, we do want to always do the
7619 // security checking for it above.
7620 userId = UserHandle.USER_CURRENT;
7623 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7624 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7625 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7626 if (!UserHandle.isSameApp(callingUid, uid)) {
7627 String msg = "Permission Denial: getIntentSender() from pid="
7628 + Binder.getCallingPid()
7629 + ", uid=" + Binder.getCallingUid()
7630 + ", (need uid=" + uid + ")"
7631 + " is not allowed to send as package " + packageName;
7633 throw new SecurityException(msg);
7637 return getIntentSenderLocked(type, packageName, callingUid, userId,
7638 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7640 } catch (RemoteException e) {
7641 throw new SecurityException(e);
7646 IIntentSender getIntentSenderLocked(int type, String packageName,
7647 int callingUid, int userId, IBinder token, String resultWho,
7648 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7650 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7651 ActivityRecord activity = null;
7652 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7653 activity = ActivityRecord.isInStackLocked(token);
7654 if (activity == null) {
7655 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7658 if (activity.finishing) {
7659 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7664 // We're going to be splicing together extras before sending, so we're
7665 // okay poking into any contained extras.
7666 if (intents != null) {
7667 for (int i = 0; i < intents.length; i++) {
7668 intents[i].setDefusable(true);
7671 Bundle.setDefusable(bOptions, true);
7673 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7674 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7675 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7676 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7677 |PendingIntent.FLAG_UPDATE_CURRENT);
7679 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7680 type, packageName, activity, resultWho,
7681 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7682 WeakReference<PendingIntentRecord> ref;
7683 ref = mIntentSenderRecords.get(key);
7684 PendingIntentRecord rec = ref != null ? ref.get() : null;
7686 if (!cancelCurrent) {
7687 if (updateCurrent) {
7688 if (rec.key.requestIntent != null) {
7689 rec.key.requestIntent.replaceExtras(intents != null ?
7690 intents[intents.length - 1] : null);
7692 if (intents != null) {
7693 intents[intents.length-1] = rec.key.requestIntent;
7694 rec.key.allIntents = intents;
7695 rec.key.allResolvedTypes = resolvedTypes;
7697 rec.key.allIntents = null;
7698 rec.key.allResolvedTypes = null;
7703 makeIntentSenderCanceledLocked(rec);
7704 mIntentSenderRecords.remove(key);
7709 rec = new PendingIntentRecord(this, key, callingUid);
7710 mIntentSenderRecords.put(key, rec.ref);
7711 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7712 if (activity.pendingResults == null) {
7713 activity.pendingResults
7714 = new HashSet<WeakReference<PendingIntentRecord>>();
7716 activity.pendingResults.add(rec.ref);
7722 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7723 Intent intent, String resolvedType,
7724 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7725 if (target instanceof PendingIntentRecord) {
7726 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7727 whitelistToken, finishedReceiver, requiredPermission, options);
7729 if (intent == null) {
7730 // Weird case: someone has given us their own custom IIntentSender, and now
7731 // they have someone else trying to send to it but of course this isn't
7732 // really a PendingIntent, so there is no base Intent, and the caller isn't
7733 // supplying an Intent... but we never want to dispatch a null Intent to
7734 // a receiver, so um... let's make something up.
7735 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7736 intent = new Intent(Intent.ACTION_MAIN);
7739 target.send(code, intent, resolvedType, whitelistToken, null,
7740 requiredPermission, options);
7741 } catch (RemoteException e) {
7743 // Platform code can rely on getting a result back when the send is done, but if
7744 // this intent sender is from outside of the system we can't rely on it doing that.
7745 // So instead we don't give it the result receiver, and instead just directly
7746 // report the finish immediately.
7747 if (finishedReceiver != null) {
7749 finishedReceiver.performReceive(intent, 0,
7750 null, null, false, false, UserHandle.getCallingUserId());
7751 } catch (RemoteException e) {
7759 public void cancelIntentSender(IIntentSender sender) {
7760 if (!(sender instanceof PendingIntentRecord)) {
7763 synchronized(this) {
7764 PendingIntentRecord rec = (PendingIntentRecord)sender;
7766 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7767 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7768 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7769 String msg = "Permission Denial: cancelIntentSender() from pid="
7770 + Binder.getCallingPid()
7771 + ", uid=" + Binder.getCallingUid()
7772 + " is not allowed to cancel package "
7773 + rec.key.packageName;
7775 throw new SecurityException(msg);
7777 } catch (RemoteException e) {
7778 throw new SecurityException(e);
7780 cancelIntentSenderLocked(rec, true);
7784 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7785 makeIntentSenderCanceledLocked(rec);
7786 mIntentSenderRecords.remove(rec.key);
7787 if (cleanActivity && rec.key.activity != null) {
7788 rec.key.activity.pendingResults.remove(rec.ref);
7792 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7793 rec.canceled = true;
7794 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7795 if (callbacks != null) {
7796 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7801 public String getPackageForIntentSender(IIntentSender pendingResult) {
7802 if (!(pendingResult instanceof PendingIntentRecord)) {
7806 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7807 return res.key.packageName;
7808 } catch (ClassCastException e) {
7814 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7815 if (!(sender instanceof PendingIntentRecord)) {
7818 synchronized(this) {
7819 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7824 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7825 IResultReceiver receiver) {
7826 if (!(sender instanceof PendingIntentRecord)) {
7829 synchronized(this) {
7830 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7835 public int getUidForIntentSender(IIntentSender sender) {
7836 if (sender instanceof PendingIntentRecord) {
7838 PendingIntentRecord res = (PendingIntentRecord)sender;
7840 } catch (ClassCastException e) {
7847 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7848 if (!(pendingResult instanceof PendingIntentRecord)) {
7852 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7853 if (res.key.allIntents == null) {
7856 for (int i=0; i<res.key.allIntents.length; i++) {
7857 Intent intent = res.key.allIntents[i];
7858 if (intent.getPackage() != null && intent.getComponent() != null) {
7863 } catch (ClassCastException e) {
7869 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7870 if (!(pendingResult instanceof PendingIntentRecord)) {
7874 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7875 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7879 } catch (ClassCastException e) {
7885 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7886 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7887 "getIntentForIntentSender()");
7888 if (!(pendingResult instanceof PendingIntentRecord)) {
7892 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7893 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7894 } catch (ClassCastException e) {
7900 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7901 if (!(pendingResult instanceof PendingIntentRecord)) {
7905 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7906 synchronized (this) {
7907 return getTagForIntentSenderLocked(res, prefix);
7909 } catch (ClassCastException e) {
7914 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7915 final Intent intent = res.key.requestIntent;
7916 if (intent != null) {
7917 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7918 || res.lastTagPrefix.equals(prefix))) {
7921 res.lastTagPrefix = prefix;
7922 final StringBuilder sb = new StringBuilder(128);
7923 if (prefix != null) {
7926 if (intent.getAction() != null) {
7927 sb.append(intent.getAction());
7928 } else if (intent.getComponent() != null) {
7929 intent.getComponent().appendShortString(sb);
7933 return res.lastTag = sb.toString();
7939 public void setProcessLimit(int max) {
7940 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7941 "setProcessLimit()");
7942 synchronized (this) {
7943 mConstants.setOverrideMaxCachedProcesses(max);
7949 public int getProcessLimit() {
7950 synchronized (this) {
7951 return mConstants.getOverrideMaxCachedProcesses();
7955 void importanceTokenDied(ImportanceToken token) {
7956 synchronized (ActivityManagerService.this) {
7957 synchronized (mPidsSelfLocked) {
7959 = mImportantProcesses.get(token.pid);
7963 mImportantProcesses.remove(token.pid);
7964 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7968 pr.forcingToImportant = null;
7969 updateProcessForegroundLocked(pr, false, false);
7971 updateOomAdjLocked();
7976 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7977 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7978 "setProcessImportant()");
7979 synchronized(this) {
7980 boolean changed = false;
7982 synchronized (mPidsSelfLocked) {
7983 ProcessRecord pr = mPidsSelfLocked.get(pid);
7984 if (pr == null && isForeground) {
7985 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7988 ImportanceToken oldToken = mImportantProcesses.get(pid);
7989 if (oldToken != null) {
7990 oldToken.token.unlinkToDeath(oldToken, 0);
7991 mImportantProcesses.remove(pid);
7993 pr.forcingToImportant = null;
7997 if (isForeground && token != null) {
7998 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8000 public void binderDied() {
8001 importanceTokenDied(this);
8005 token.linkToDeath(newToken, 0);
8006 mImportantProcesses.put(pid, newToken);
8007 pr.forcingToImportant = newToken;
8009 } catch (RemoteException e) {
8010 // If the process died while doing this, we will later
8011 // do the cleanup with the process death link.
8017 updateOomAdjLocked();
8023 public boolean isAppForeground(int uid) throws RemoteException {
8024 int callerUid = Binder.getCallingUid();
8025 if (UserHandle.isCore(callerUid) || callerUid == uid) {
8026 return isAppForegroundInternal(uid);
8031 private boolean isAppForegroundInternal(int uid) {
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 // Figure out the value returned when access is allowed
8853 final int allowedResult;
8854 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8855 // If we're extending a persistable grant, then we need to return
8856 // "targetUid" so that we always create a grant data structure to
8857 // support take/release APIs
8858 allowedResult = targetUid;
8860 // Otherwise, we can return "-1" to indicate that no grant data
8861 // structures need to be created
8865 if (targetUid >= 0) {
8866 // First... does the target actually need this permission?
8867 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8868 // No need to grant the target this permission.
8869 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8870 "Target " + targetPkg + " already has full permission to " + grantUri);
8871 return allowedResult;
8874 // First... there is no target package, so can anyone access it?
8875 boolean allowed = pi.exported;
8876 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8877 if (pi.readPermission != null) {
8881 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8882 if (pi.writePermission != null) {
8887 return allowedResult;
8891 /* There is a special cross user grant if:
8892 * - The target is on another user.
8893 * - Apps on the current user can access the uri without any uid permissions.
8894 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8895 * grant uri permissions.
8897 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8898 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8899 modeFlags, false /*without considering the uid permissions*/);
8901 // Second... is the provider allowing granting of URI permissions?
8902 if (!specialCrossUserGrant) {
8903 if (!pi.grantUriPermissions) {
8904 throw new SecurityException("Provider " + pi.packageName
8906 + " does not allow granting of Uri permissions (uri "
8909 if (pi.uriPermissionPatterns != null) {
8910 final int N = pi.uriPermissionPatterns.length;
8911 boolean allowed = false;
8912 for (int i=0; i<N; i++) {
8913 if (pi.uriPermissionPatterns[i] != null
8914 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8920 throw new SecurityException("Provider " + pi.packageName
8922 + " does not allow granting of permission to path of Uri "
8928 // Third... does the caller itself have permission to access
8930 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8931 // Require they hold a strong enough Uri permission
8932 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8933 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8934 throw new SecurityException(
8935 "UID " + callingUid + " does not have permission to " + grantUri
8936 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8937 + "or related APIs");
8939 throw new SecurityException(
8940 "UID " + callingUid + " does not have permission to " + grantUri);
8948 * @param uri This uri must NOT contain an embedded userId.
8949 * @param userId The userId in which the uri is to be resolved.
8952 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8953 final int modeFlags, int userId) {
8954 enforceNotIsolatedCaller("checkGrantUriPermission");
8955 synchronized(this) {
8956 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8957 new GrantUri(userId, uri, false), modeFlags, -1);
8961 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8962 final int modeFlags, UriPermissionOwner owner) {
8963 if (!Intent.isAccessUriMode(modeFlags)) {
8967 // So here we are: the caller has the assumed permission
8968 // to the uri, and the target doesn't. Let's now give this to
8971 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8972 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8974 final String authority = grantUri.uri.getAuthority();
8975 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8976 MATCH_DEBUG_TRIAGED_MISSING);
8978 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8982 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8983 grantUri.prefix = true;
8985 final UriPermission perm = findOrCreateUriPermissionLocked(
8986 pi.packageName, targetPkg, targetUid, grantUri);
8987 perm.grantModes(modeFlags, owner);
8990 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8991 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8992 if (targetPkg == null) {
8993 throw new NullPointerException("targetPkg");
8996 final IPackageManager pm = AppGlobals.getPackageManager();
8998 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8999 } catch (RemoteException ex) {
9003 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9005 if (targetUid < 0) {
9009 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9013 static class NeededUriGrants extends ArrayList<GrantUri> {
9014 final String targetPkg;
9015 final int targetUid;
9018 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9019 this.targetPkg = targetPkg;
9020 this.targetUid = targetUid;
9026 * Like checkGrantUriPermissionLocked, but takes an Intent.
9028 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9029 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9030 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9031 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9032 + " clip=" + (intent != null ? intent.getClipData() : null)
9033 + " from " + intent + "; flags=0x"
9034 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9036 if (targetPkg == null) {
9037 throw new NullPointerException("targetPkg");
9040 if (intent == null) {
9043 Uri data = intent.getData();
9044 ClipData clip = intent.getClipData();
9045 if (data == null && clip == null) {
9048 // Default userId for uris in the intent (if they don't specify it themselves)
9049 int contentUserHint = intent.getContentUserHint();
9050 if (contentUserHint == UserHandle.USER_CURRENT) {
9051 contentUserHint = UserHandle.getUserId(callingUid);
9053 final IPackageManager pm = AppGlobals.getPackageManager();
9055 if (needed != null) {
9056 targetUid = needed.targetUid;
9059 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9061 } catch (RemoteException ex) {
9064 if (targetUid < 0) {
9065 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9066 "Can't grant URI permission no uid for: " + targetPkg
9067 + " on user " + targetUserId);
9072 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9073 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9075 if (targetUid > 0) {
9076 if (needed == null) {
9077 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9079 needed.add(grantUri);
9083 for (int i=0; i<clip.getItemCount(); i++) {
9084 Uri uri = clip.getItemAt(i).getUri();
9086 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9087 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9089 if (targetUid > 0) {
9090 if (needed == null) {
9091 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9093 needed.add(grantUri);
9096 Intent clipIntent = clip.getItemAt(i).getIntent();
9097 if (clipIntent != null) {
9098 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9099 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9100 if (newNeeded != null) {
9112 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9114 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9115 UriPermissionOwner owner) {
9116 if (needed != null) {
9117 for (int i=0; i<needed.size(); i++) {
9118 GrantUri grantUri = needed.get(i);
9119 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9120 grantUri, needed.flags, owner);
9125 void grantUriPermissionFromIntentLocked(int callingUid,
9126 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9127 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9128 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9129 if (needed == null) {
9133 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9137 * @param uri This uri must NOT contain an embedded userId.
9138 * @param userId The userId in which the uri is to be resolved.
9141 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9142 final int modeFlags, int userId) {
9143 enforceNotIsolatedCaller("grantUriPermission");
9144 GrantUri grantUri = new GrantUri(userId, uri, false);
9145 synchronized(this) {
9146 final ProcessRecord r = getRecordForAppLocked(caller);
9148 throw new SecurityException("Unable to find app for caller "
9150 + " when granting permission to uri " + grantUri);
9152 if (targetPkg == null) {
9153 throw new IllegalArgumentException("null target");
9155 if (grantUri == null) {
9156 throw new IllegalArgumentException("null uri");
9159 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9160 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9161 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9162 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9164 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9165 UserHandle.getUserId(r.uid));
9169 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9170 if (perm.modeFlags == 0) {
9171 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9173 if (perms != null) {
9174 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9175 "Removing " + perm.targetUid + " permission to " + perm.uri);
9177 perms.remove(perm.uri);
9178 if (perms.isEmpty()) {
9179 mGrantedUriPermissions.remove(perm.targetUid);
9185 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9186 final int modeFlags) {
9187 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9188 "Revoking all granted permissions to " + grantUri);
9190 final IPackageManager pm = AppGlobals.getPackageManager();
9191 final String authority = grantUri.uri.getAuthority();
9192 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9193 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9195 Slog.w(TAG, "No content provider found for permission revoke: "
9196 + grantUri.toSafeString());
9200 // Does the caller have this permission on the URI?
9201 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9202 // If they don't have direct access to the URI, then revoke any
9203 // ownerless URI permissions that have been granted to them.
9204 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9205 if (perms != null) {
9206 boolean persistChanged = false;
9207 for (int i = perms.size()-1; i >= 0; i--) {
9208 final UriPermission perm = perms.valueAt(i);
9209 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9212 if (perm.uri.sourceUserId == grantUri.sourceUserId
9213 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9214 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9215 "Revoking non-owned " + perm.targetUid
9216 + " permission to " + perm.uri);
9217 persistChanged |= perm.revokeModes(
9218 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9219 if (perm.modeFlags == 0) {
9224 if (perms.isEmpty()) {
9225 mGrantedUriPermissions.remove(callingUid);
9227 if (persistChanged) {
9228 schedulePersistUriGrants();
9234 boolean persistChanged = false;
9236 // Go through all of the permissions and remove any that match.
9237 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9238 final int targetUid = mGrantedUriPermissions.keyAt(i);
9239 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9241 for (int j = perms.size()-1; j >= 0; j--) {
9242 final UriPermission perm = perms.valueAt(j);
9243 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9246 if (perm.uri.sourceUserId == grantUri.sourceUserId
9247 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9248 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9249 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9250 persistChanged |= perm.revokeModes(
9251 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9252 targetPackage == null);
9253 if (perm.modeFlags == 0) {
9259 if (perms.isEmpty()) {
9260 mGrantedUriPermissions.removeAt(i);
9264 if (persistChanged) {
9265 schedulePersistUriGrants();
9270 * @param uri This uri must NOT contain an embedded userId.
9271 * @param userId The userId in which the uri is to be resolved.
9274 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9275 final int modeFlags, int userId) {
9276 enforceNotIsolatedCaller("revokeUriPermission");
9277 synchronized(this) {
9278 final ProcessRecord r = getRecordForAppLocked(caller);
9280 throw new SecurityException("Unable to find app for caller "
9282 + " when revoking permission to uri " + uri);
9285 Slog.w(TAG, "revokeUriPermission: null uri");
9289 if (!Intent.isAccessUriMode(modeFlags)) {
9293 final String authority = uri.getAuthority();
9294 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9295 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9297 Slog.w(TAG, "No content provider found for permission revoke: "
9298 + uri.toSafeString());
9302 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9308 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9311 * @param packageName Package name to match, or {@code null} to apply to all
9313 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9315 * @param persistable If persistable grants should be removed.
9317 private void removeUriPermissionsForPackageLocked(
9318 String packageName, int userHandle, boolean persistable) {
9319 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9320 throw new IllegalArgumentException("Must narrow by either package or user");
9323 boolean persistChanged = false;
9325 int N = mGrantedUriPermissions.size();
9326 for (int i = 0; i < N; i++) {
9327 final int targetUid = mGrantedUriPermissions.keyAt(i);
9328 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9330 // Only inspect grants matching user
9331 if (userHandle == UserHandle.USER_ALL
9332 || userHandle == UserHandle.getUserId(targetUid)) {
9333 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9334 final UriPermission perm = it.next();
9336 // Only inspect grants matching package
9337 if (packageName == null || perm.sourcePkg.equals(packageName)
9338 || perm.targetPkg.equals(packageName)) {
9339 // Hacky solution as part of fixing a security bug; ignore
9340 // grants associated with DownloadManager so we don't have
9341 // to immediately launch it to regrant the permissions
9342 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9343 && !persistable) continue;
9345 persistChanged |= perm.revokeModes(persistable
9346 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9348 // Only remove when no modes remain; any persisted grants
9349 // will keep this alive.
9350 if (perm.modeFlags == 0) {
9356 if (perms.isEmpty()) {
9357 mGrantedUriPermissions.remove(targetUid);
9364 if (persistChanged) {
9365 schedulePersistUriGrants();
9370 public IBinder newUriPermissionOwner(String name) {
9371 enforceNotIsolatedCaller("newUriPermissionOwner");
9372 synchronized(this) {
9373 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9374 return owner.getExternalTokenLocked();
9379 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9380 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9381 synchronized(this) {
9382 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9384 throw new IllegalArgumentException("Activity does not exist; token="
9387 return r.getUriPermissionsLocked().getExternalTokenLocked();
9391 * @param uri This uri must NOT contain an embedded userId.
9392 * @param sourceUserId The userId in which the uri is to be resolved.
9393 * @param targetUserId The userId of the app that receives the grant.
9396 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9397 final int modeFlags, int sourceUserId, int targetUserId) {
9398 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9399 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9400 "grantUriPermissionFromOwner", null);
9401 synchronized(this) {
9402 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9403 if (owner == null) {
9404 throw new IllegalArgumentException("Unknown owner: " + token);
9406 if (fromUid != Binder.getCallingUid()) {
9407 if (Binder.getCallingUid() != myUid()) {
9408 // Only system code can grant URI permissions on behalf
9410 throw new SecurityException("nice try");
9413 if (targetPkg == null) {
9414 throw new IllegalArgumentException("null target");
9417 throw new IllegalArgumentException("null uri");
9420 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9421 modeFlags, owner, targetUserId);
9426 * @param uri This uri must NOT contain an embedded userId.
9427 * @param userId The userId in which the uri is to be resolved.
9430 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9431 synchronized(this) {
9432 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9433 if (owner == null) {
9434 throw new IllegalArgumentException("Unknown owner: " + token);
9438 owner.removeUriPermissionsLocked(mode);
9440 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9441 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9446 private void schedulePersistUriGrants() {
9447 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9448 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9449 10 * DateUtils.SECOND_IN_MILLIS);
9453 private void writeGrantedUriPermissions() {
9454 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9456 // Snapshot permissions so we can persist without lock
9457 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9458 synchronized (this) {
9459 final int size = mGrantedUriPermissions.size();
9460 for (int i = 0; i < size; i++) {
9461 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9462 for (UriPermission perm : perms.values()) {
9463 if (perm.persistedModeFlags != 0) {
9464 persist.add(perm.snapshot());
9470 FileOutputStream fos = null;
9472 fos = mGrantFile.startWrite();
9474 XmlSerializer out = new FastXmlSerializer();
9475 out.setOutput(fos, StandardCharsets.UTF_8.name());
9476 out.startDocument(null, true);
9477 out.startTag(null, TAG_URI_GRANTS);
9478 for (UriPermission.Snapshot perm : persist) {
9479 out.startTag(null, TAG_URI_GRANT);
9480 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9481 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9482 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9483 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9484 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9485 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9486 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9487 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9488 out.endTag(null, TAG_URI_GRANT);
9490 out.endTag(null, TAG_URI_GRANTS);
9493 mGrantFile.finishWrite(fos);
9494 } catch (IOException e) {
9496 mGrantFile.failWrite(fos);
9501 private void readGrantedUriPermissionsLocked() {
9502 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9504 final long now = System.currentTimeMillis();
9506 FileInputStream fis = null;
9508 fis = mGrantFile.openRead();
9509 final XmlPullParser in = Xml.newPullParser();
9510 in.setInput(fis, StandardCharsets.UTF_8.name());
9513 while ((type = in.next()) != END_DOCUMENT) {
9514 final String tag = in.getName();
9515 if (type == START_TAG) {
9516 if (TAG_URI_GRANT.equals(tag)) {
9517 final int sourceUserId;
9518 final int targetUserId;
9519 final int userHandle = readIntAttribute(in,
9520 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9521 if (userHandle != UserHandle.USER_NULL) {
9522 // For backwards compatibility.
9523 sourceUserId = userHandle;
9524 targetUserId = userHandle;
9526 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9527 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9529 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9530 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9531 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9532 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9533 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9534 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9536 // Sanity check that provider still belongs to source package
9537 // Both direct boot aware and unaware packages are fine as we
9538 // will do filtering at query time to avoid multiple parsing.
9539 final ProviderInfo pi = getProviderInfoLocked(
9540 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9541 | MATCH_DIRECT_BOOT_UNAWARE);
9542 if (pi != null && sourcePkg.equals(pi.packageName)) {
9545 targetUid = AppGlobals.getPackageManager().getPackageUid(
9546 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9547 } catch (RemoteException e) {
9549 if (targetUid != -1) {
9550 final UriPermission perm = findOrCreateUriPermissionLocked(
9551 sourcePkg, targetPkg, targetUid,
9552 new GrantUri(sourceUserId, uri, prefix));
9553 perm.initPersistedModes(modeFlags, createdTime);
9556 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9557 + " but instead found " + pi);
9562 } catch (FileNotFoundException e) {
9563 // Missing grants is okay
9564 } catch (IOException e) {
9565 Slog.wtf(TAG, "Failed reading Uri grants", e);
9566 } catch (XmlPullParserException e) {
9567 Slog.wtf(TAG, "Failed reading Uri grants", e);
9569 IoUtils.closeQuietly(fis);
9574 * @param uri This uri must NOT contain an embedded userId.
9575 * @param userId The userId in which the uri is to be resolved.
9578 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9579 enforceNotIsolatedCaller("takePersistableUriPermission");
9581 Preconditions.checkFlagsArgument(modeFlags,
9582 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9584 synchronized (this) {
9585 final int callingUid = Binder.getCallingUid();
9586 boolean persistChanged = false;
9587 GrantUri grantUri = new GrantUri(userId, uri, false);
9589 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9590 new GrantUri(userId, uri, false));
9591 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9592 new GrantUri(userId, uri, true));
9594 final boolean exactValid = (exactPerm != null)
9595 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9596 final boolean prefixValid = (prefixPerm != null)
9597 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9599 if (!(exactValid || prefixValid)) {
9600 throw new SecurityException("No persistable permission grants found for UID "
9601 + callingUid + " and Uri " + grantUri.toSafeString());
9605 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9608 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9611 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9613 if (persistChanged) {
9614 schedulePersistUriGrants();
9620 * @param uri This uri must NOT contain an embedded userId.
9621 * @param userId The userId in which the uri is to be resolved.
9624 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9625 enforceNotIsolatedCaller("releasePersistableUriPermission");
9627 Preconditions.checkFlagsArgument(modeFlags,
9628 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9630 synchronized (this) {
9631 final int callingUid = Binder.getCallingUid();
9632 boolean persistChanged = false;
9634 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9635 new GrantUri(userId, uri, false));
9636 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9637 new GrantUri(userId, uri, true));
9638 if (exactPerm == null && prefixPerm == null) {
9639 throw new SecurityException("No permission grants found for UID " + callingUid
9640 + " and Uri " + uri.toSafeString());
9643 if (exactPerm != null) {
9644 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9645 removeUriPermissionIfNeededLocked(exactPerm);
9647 if (prefixPerm != null) {
9648 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9649 removeUriPermissionIfNeededLocked(prefixPerm);
9652 if (persistChanged) {
9653 schedulePersistUriGrants();
9659 * Prune any older {@link UriPermission} for the given UID until outstanding
9660 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9662 * @return if any mutations occured that require persisting.
9664 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9665 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9666 if (perms == null) return false;
9667 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9669 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9670 for (UriPermission perm : perms.values()) {
9671 if (perm.persistedModeFlags != 0) {
9672 persisted.add(perm);
9676 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9677 if (trimCount <= 0) return false;
9679 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9680 for (int i = 0; i < trimCount; i++) {
9681 final UriPermission perm = persisted.get(i);
9683 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9684 "Trimming grant created at " + perm.persistedCreateTime);
9686 perm.releasePersistableModes(~0);
9687 removeUriPermissionIfNeededLocked(perm);
9694 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9695 String packageName, boolean incoming) {
9696 enforceNotIsolatedCaller("getPersistedUriPermissions");
9697 Preconditions.checkNotNull(packageName, "packageName");
9699 final int callingUid = Binder.getCallingUid();
9700 final int callingUserId = UserHandle.getUserId(callingUid);
9701 final IPackageManager pm = AppGlobals.getPackageManager();
9703 final int packageUid = pm.getPackageUid(packageName,
9704 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9705 if (packageUid != callingUid) {
9706 throw new SecurityException(
9707 "Package " + packageName + " does not belong to calling UID " + callingUid);
9709 } catch (RemoteException e) {
9710 throw new SecurityException("Failed to verify package name ownership");
9713 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9714 synchronized (this) {
9716 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9718 if (perms == null) {
9719 Slog.w(TAG, "No permission grants found for " + packageName);
9721 for (UriPermission perm : perms.values()) {
9722 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9723 result.add(perm.buildPersistedPublicApiObject());
9728 final int size = mGrantedUriPermissions.size();
9729 for (int i = 0; i < size; i++) {
9730 final ArrayMap<GrantUri, UriPermission> perms =
9731 mGrantedUriPermissions.valueAt(i);
9732 for (UriPermission perm : perms.values()) {
9733 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9734 result.add(perm.buildPersistedPublicApiObject());
9740 return new ParceledListSlice<android.content.UriPermission>(result);
9744 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9745 String packageName, int userId) {
9746 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9747 "getGrantedUriPermissions");
9749 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9750 synchronized (this) {
9751 final int size = mGrantedUriPermissions.size();
9752 for (int i = 0; i < size; i++) {
9753 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9754 for (UriPermission perm : perms.values()) {
9755 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9756 && perm.persistedModeFlags != 0) {
9757 result.add(perm.buildPersistedPublicApiObject());
9762 return new ParceledListSlice<android.content.UriPermission>(result);
9766 public void clearGrantedUriPermissions(String packageName, int userId) {
9767 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9768 "clearGrantedUriPermissions");
9769 removeUriPermissionsForPackageLocked(packageName, userId, true);
9773 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9774 synchronized (this) {
9776 who != null ? getRecordForAppLocked(who) : null;
9777 if (app == null) return;
9779 Message msg = Message.obtain();
9780 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9782 msg.arg1 = waiting ? 1 : 0;
9783 mUiHandler.sendMessage(msg);
9788 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9789 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9790 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9791 outInfo.availMem = getFreeMemory();
9792 outInfo.totalMem = getTotalMemory();
9793 outInfo.threshold = homeAppMem;
9794 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9795 outInfo.hiddenAppThreshold = cachedAppMem;
9796 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9797 ProcessList.SERVICE_ADJ);
9798 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9799 ProcessList.VISIBLE_APP_ADJ);
9800 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9801 ProcessList.FOREGROUND_APP_ADJ);
9804 // =========================================================
9806 // =========================================================
9809 public List<IBinder> getAppTasks(String callingPackage) {
9810 int callingUid = Binder.getCallingUid();
9811 long ident = Binder.clearCallingIdentity();
9813 synchronized(this) {
9814 ArrayList<IBinder> list = new ArrayList<IBinder>();
9816 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9818 final int N = mRecentTasks.size();
9819 for (int i = 0; i < N; i++) {
9820 TaskRecord tr = mRecentTasks.get(i);
9821 // Skip tasks that do not match the caller. We don't need to verify
9822 // callingPackage, because we are also limiting to callingUid and know
9823 // that will limit to the correct security sandbox.
9824 if (tr.effectiveUid != callingUid) {
9827 Intent intent = tr.getBaseIntent();
9828 if (intent == null ||
9829 !callingPackage.equals(intent.getComponent().getPackageName())) {
9832 ActivityManager.RecentTaskInfo taskInfo =
9833 createRecentTaskInfoFromTaskRecord(tr);
9834 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9835 list.add(taskImpl.asBinder());
9838 Binder.restoreCallingIdentity(ident);
9845 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9846 final int callingUid = Binder.getCallingUid();
9847 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9849 synchronized(this) {
9850 if (DEBUG_ALL) Slog.v(
9851 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9853 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9856 // TODO: Improve with MRU list from all ActivityStacks.
9857 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9864 * Creates a new RecentTaskInfo from a TaskRecord.
9866 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9867 // Update the task description to reflect any changes in the task stack
9868 tr.updateTaskDescription();
9870 // Compose the recent task info
9871 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9872 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9873 rti.persistentId = tr.taskId;
9874 rti.baseIntent = new Intent(tr.getBaseIntent());
9875 rti.origActivity = tr.origActivity;
9876 rti.realActivity = tr.realActivity;
9877 rti.description = tr.lastDescription;
9878 rti.stackId = tr.getStackId();
9879 rti.userId = tr.userId;
9880 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9881 rti.firstActiveTime = tr.firstActiveTime;
9882 rti.lastActiveTime = tr.lastActiveTime;
9883 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9884 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9885 rti.numActivities = 0;
9886 if (tr.mBounds != null) {
9887 rti.bounds = new Rect(tr.mBounds);
9889 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9890 rti.resizeMode = tr.mResizeMode;
9892 ActivityRecord base = null;
9893 ActivityRecord top = null;
9896 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9897 tmp = tr.mActivities.get(i);
9898 if (tmp.finishing) {
9902 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9905 rti.numActivities++;
9908 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9909 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9914 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9915 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9916 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9918 if (checkPermission(android.Manifest.permission.GET_TASKS,
9919 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9920 // Temporary compatibility: some existing apps on the system image may
9921 // still be requesting the old permission and not switched to the new
9922 // one; if so, we'll still allow them full access. This means we need
9923 // to see if they are holding the old permission and are a system app.
9925 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9927 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9928 + " is using old GET_TASKS but privileged; allowing");
9930 } catch (RemoteException e) {
9935 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9936 + " does not hold REAL_GET_TASKS; limiting output");
9942 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9944 final int callingUid = Binder.getCallingUid();
9945 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9946 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9948 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9949 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9950 synchronized (this) {
9951 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9953 final boolean detailed = checkCallingPermission(
9954 android.Manifest.permission.GET_DETAILED_TASKS)
9955 == PackageManager.PERMISSION_GRANTED;
9957 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9958 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9959 return ParceledListSlice.emptyList();
9961 mRecentTasks.loadUserRecentsLocked(userId);
9963 final int recentsCount = mRecentTasks.size();
9964 ArrayList<ActivityManager.RecentTaskInfo> res =
9965 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9967 final Set<Integer> includedUsers;
9968 if (includeProfiles) {
9969 includedUsers = mUserController.getProfileIds(userId);
9971 includedUsers = new HashSet<>();
9973 includedUsers.add(Integer.valueOf(userId));
9975 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9976 TaskRecord tr = mRecentTasks.get(i);
9977 // Only add calling user or related users recent tasks
9978 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9979 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9983 if (tr.realActivitySuspended) {
9984 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9988 // Return the entry if desired by the caller. We always return
9989 // the first entry, because callers always expect this to be the
9990 // foreground app. We may filter others if the caller has
9991 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9992 // we should exclude the entry.
9996 || (tr.intent == null)
9997 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
10000 // If the caller doesn't have the GET_TASKS permission, then only
10001 // allow them to see a small subset of tasks -- their own and home.
10002 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
10003 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
10007 final ActivityStack stack = tr.getStack();
10008 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
10009 if (stack != null && stack.isHomeOrRecentsStack()) {
10010 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10011 "Skipping, home or recents stack task: " + tr);
10015 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10016 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10017 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10018 "Skipping, top task in docked stack: " + tr);
10022 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10023 if (stack != null && stack.isPinnedStack()) {
10024 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10025 "Skipping, pinned stack task: " + tr);
10029 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10030 // Don't include auto remove tasks that are finished or finishing.
10031 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10032 "Skipping, auto-remove without activity: " + tr);
10035 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10036 && !tr.isAvailable) {
10037 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10038 "Skipping, unavail real act: " + tr);
10042 if (!tr.mUserSetupComplete) {
10043 // Don't include task launched while user is not done setting-up.
10044 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10045 "Skipping, user setup not complete: " + tr);
10049 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10051 rti.baseIntent.replaceExtras((Bundle)null);
10058 return new ParceledListSlice<>(res);
10063 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10064 synchronized (this) {
10065 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10066 "getTaskThumbnail()");
10067 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10068 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10070 return tr.getTaskThumbnailLocked();
10077 public ActivityManager.TaskDescription getTaskDescription(int id) {
10078 synchronized (this) {
10079 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10080 "getTaskDescription()");
10081 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10082 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10084 return tr.lastTaskDescription;
10091 public int addAppTask(IBinder activityToken, Intent intent,
10092 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10093 final int callingUid = Binder.getCallingUid();
10094 final long callingIdent = Binder.clearCallingIdentity();
10097 synchronized (this) {
10098 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10100 throw new IllegalArgumentException("Activity does not exist; token="
10103 ComponentName comp = intent.getComponent();
10104 if (comp == null) {
10105 throw new IllegalArgumentException("Intent " + intent
10106 + " must specify explicit component");
10108 if (thumbnail.getWidth() != mThumbnailWidth
10109 || thumbnail.getHeight() != mThumbnailHeight) {
10110 throw new IllegalArgumentException("Bad thumbnail size: got "
10111 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10112 + mThumbnailWidth + "x" + mThumbnailHeight);
10114 if (intent.getSelector() != null) {
10115 intent.setSelector(null);
10117 if (intent.getSourceBounds() != null) {
10118 intent.setSourceBounds(null);
10120 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10121 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10122 // The caller has added this as an auto-remove task... that makes no
10123 // sense, so turn off auto-remove.
10124 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10127 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10128 mLastAddedTaskActivity = null;
10130 ActivityInfo ainfo = mLastAddedTaskActivity;
10131 if (ainfo == null) {
10132 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10133 comp, 0, UserHandle.getUserId(callingUid));
10134 if (ainfo.applicationInfo.uid != callingUid) {
10135 throw new SecurityException(
10136 "Can't add task for another application: target uid="
10137 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10141 TaskRecord task = new TaskRecord(this,
10142 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10143 ainfo, intent, description, new TaskThumbnailInfo());
10145 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10146 if (trimIdx >= 0) {
10147 // If this would have caused a trim, then we'll abort because that
10148 // means it would be added at the end of the list but then just removed.
10149 return INVALID_TASK_ID;
10152 final int N = mRecentTasks.size();
10153 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10154 final TaskRecord tr = mRecentTasks.remove(N - 1);
10155 tr.removedFromRecents();
10158 task.inRecents = true;
10159 mRecentTasks.add(task);
10160 r.getStack().addTask(task, false, "addAppTask");
10162 task.setLastThumbnailLocked(thumbnail);
10163 task.freeLastThumbnail();
10164 return task.taskId;
10167 Binder.restoreCallingIdentity(callingIdent);
10172 public Point getAppTaskThumbnailSize() {
10173 synchronized (this) {
10174 return new Point(mThumbnailWidth, mThumbnailHeight);
10179 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10180 synchronized (this) {
10181 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10183 r.setTaskDescription(td);
10184 final TaskRecord task = r.getTask();
10185 task.updateTaskDescription();
10186 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10192 public void setTaskResizeable(int taskId, int resizeableMode) {
10193 synchronized (this) {
10194 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10195 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10196 if (task == null) {
10197 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10200 task.setResizeMode(resizeableMode);
10205 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10206 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10207 long ident = Binder.clearCallingIdentity();
10209 synchronized (this) {
10210 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10211 if (task == null) {
10212 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10215 // Place the task in the right stack if it isn't there already based on
10216 // the requested bounds.
10217 // The stack transition logic is:
10218 // - a null bounds on a freeform task moves that task to fullscreen
10219 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10220 // that task to freeform
10221 // - otherwise the task is not moved
10222 int stackId = task.getStackId();
10223 if (!StackId.isTaskResizeAllowed(stackId)) {
10224 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10226 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10227 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10228 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10229 stackId = FREEFORM_WORKSPACE_STACK_ID;
10232 // Reparent the task to the right stack if necessary
10233 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10234 if (stackId != task.getStackId()) {
10235 // Defer resume until the task is resized below
10236 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10237 DEFER_RESUME, "resizeTask");
10238 preserveWindow = false;
10241 // After reparenting (which only resizes the task to the stack bounds), resize the
10242 // task to the actual bounds provided
10243 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10246 Binder.restoreCallingIdentity(ident);
10251 public Rect getTaskBounds(int taskId) {
10252 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10253 long ident = Binder.clearCallingIdentity();
10254 Rect rect = new Rect();
10256 synchronized (this) {
10257 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10258 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10259 if (task == null) {
10260 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10263 if (task.getStack() != null) {
10264 // Return the bounds from window manager since it will be adjusted for various
10265 // things like the presense of a docked stack for tasks that aren't resizeable.
10266 task.getWindowContainerBounds(rect);
10268 // Task isn't in window manager yet since it isn't associated with a stack.
10269 // Return the persist value from activity manager
10270 if (task.mBounds != null) {
10271 rect.set(task.mBounds);
10272 } else if (task.mLastNonFullscreenBounds != null) {
10273 rect.set(task.mLastNonFullscreenBounds);
10278 Binder.restoreCallingIdentity(ident);
10284 public void cancelTaskWindowTransition(int taskId) {
10285 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10286 final long ident = Binder.clearCallingIdentity();
10288 synchronized (this) {
10289 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10290 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10291 if (task == null) {
10292 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10295 task.cancelWindowTransition();
10298 Binder.restoreCallingIdentity(ident);
10303 public void cancelTaskThumbnailTransition(int taskId) {
10304 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10305 final long ident = Binder.clearCallingIdentity();
10307 synchronized (this) {
10308 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10309 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10310 if (task == null) {
10311 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10314 task.cancelThumbnailTransition();
10317 Binder.restoreCallingIdentity(ident);
10322 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10323 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10324 final long ident = Binder.clearCallingIdentity();
10326 final TaskRecord task;
10327 synchronized (this) {
10328 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10329 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10330 if (task == null) {
10331 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10335 // Don't call this while holding the lock as this operation might hit the disk.
10336 return task.getSnapshot(reducedResolution);
10338 Binder.restoreCallingIdentity(ident);
10343 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10344 if (userId != UserHandle.getCallingUserId()) {
10345 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10346 "getTaskDescriptionIcon");
10348 final File passedIconFile = new File(filePath);
10349 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10350 passedIconFile.getName());
10351 if (!legitIconFile.getPath().equals(filePath)
10352 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10353 throw new IllegalArgumentException("Bad file path: " + filePath
10354 + " passed for userId " + userId);
10356 return mRecentTasks.getTaskDescriptionIcon(filePath);
10360 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10361 throws RemoteException {
10362 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10363 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10364 activityOptions.getCustomInPlaceResId() == 0) {
10365 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10366 "with valid animation");
10368 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10369 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10370 activityOptions.getCustomInPlaceResId());
10371 mWindowManager.executeAppTransition();
10374 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10375 // Remove all tasks with activities in the specified package from the list of recent tasks
10376 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10377 TaskRecord tr = mRecentTasks.get(i);
10378 if (tr.userId != userId) continue;
10380 ComponentName cn = tr.intent.getComponent();
10381 if (cn != null && cn.getPackageName().equals(packageName)) {
10382 // If the package name matches, remove the task.
10383 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10388 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10391 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10392 TaskRecord tr = mRecentTasks.get(i);
10393 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10397 ComponentName cn = tr.intent.getComponent();
10398 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10399 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10400 if (sameComponent) {
10401 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10407 public void removeStack(int stackId) {
10408 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10409 if (StackId.isHomeOrRecentsStack(stackId)) {
10410 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10413 synchronized (this) {
10414 final long ident = Binder.clearCallingIdentity();
10416 mStackSupervisor.removeStackLocked(stackId);
10418 Binder.restoreCallingIdentity(ident);
10424 public void moveStackToDisplay(int stackId, int displayId) {
10425 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10427 synchronized (this) {
10428 final long ident = Binder.clearCallingIdentity();
10430 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10431 + " to displayId=" + displayId);
10432 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10434 Binder.restoreCallingIdentity(ident);
10440 public boolean removeTask(int taskId) {
10441 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10442 synchronized (this) {
10443 final long ident = Binder.clearCallingIdentity();
10445 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10447 Binder.restoreCallingIdentity(ident);
10453 * TODO: Add mController hook
10456 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10457 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10459 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10460 synchronized(this) {
10461 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10465 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10466 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10468 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10469 Binder.getCallingUid(), -1, -1, "Task to front")) {
10470 ActivityOptions.abort(options);
10473 final long origId = Binder.clearCallingIdentity();
10475 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10476 if (task == null) {
10477 Slog.d(TAG, "Could not find task for id: "+ taskId);
10480 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10481 mStackSupervisor.showLockTaskToast();
10482 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10485 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10486 if (prev != null) {
10487 task.setTaskToReturnTo(prev);
10489 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10490 false /* forceNonResizable */);
10492 final ActivityRecord topActivity = task.getTopActivity();
10493 if (topActivity != null) {
10495 // We are reshowing a task, use a starting window to hide the initial draw delay
10496 // so the transition can start earlier.
10497 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10498 true /* taskSwitch */, fromRecents);
10501 Binder.restoreCallingIdentity(origId);
10503 ActivityOptions.abort(options);
10507 * Attempts to move a task backwards in z-order (the order of activities within the task is
10510 * There are several possible results of this call:
10511 * - if the task is locked, then we will show the lock toast
10512 * - if there is a task behind the provided task, then that task is made visible and resumed as
10513 * this task is moved to the back
10514 * - otherwise, if there are no other tasks in the stack:
10515 * - if this task is in the pinned stack, then we remove the stack completely, which will
10516 * have the effect of moving the task to the top or bottom of the fullscreen stack
10517 * (depending on whether it is visible)
10518 * - otherwise, we simply return home and hide this task
10520 * @param token A reference to the activity we wish to move
10521 * @param nonRoot If false then this only works if the activity is the root
10522 * of a task; if true it will work for any activity in a task.
10523 * @return Returns true if the move completed, false if not.
10526 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10527 enforceNotIsolatedCaller("moveActivityTaskToBack");
10528 synchronized(this) {
10529 final long origId = Binder.clearCallingIdentity();
10531 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10532 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10533 if (task != null) {
10534 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10537 Binder.restoreCallingIdentity(origId);
10544 public void moveTaskBackwards(int task) {
10545 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10546 "moveTaskBackwards()");
10548 synchronized(this) {
10549 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10550 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10553 final long origId = Binder.clearCallingIdentity();
10554 moveTaskBackwardsLocked(task);
10555 Binder.restoreCallingIdentity(origId);
10559 private final void moveTaskBackwardsLocked(int task) {
10560 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10564 public int createStackOnDisplay(int displayId) throws RemoteException {
10565 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10566 synchronized (this) {
10567 final int stackId = mStackSupervisor.getNextStackId();
10568 final ActivityStack stack =
10569 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10570 if (stack == null) {
10571 return INVALID_STACK_ID;
10573 return stack.mStackId;
10578 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10579 synchronized (this) {
10580 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10581 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10582 return stack.mDisplayId;
10584 return DEFAULT_DISPLAY;
10589 public int getActivityStackId(IBinder token) throws RemoteException {
10590 synchronized (this) {
10591 ActivityStack stack = ActivityRecord.getStackLocked(token);
10592 if (stack == null) {
10593 return INVALID_STACK_ID;
10595 return stack.mStackId;
10600 public void exitFreeformMode(IBinder token) throws RemoteException {
10601 synchronized (this) {
10602 long ident = Binder.clearCallingIdentity();
10604 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10606 throw new IllegalArgumentException(
10607 "exitFreeformMode: No activity record matching token=" + token);
10610 final ActivityStack stack = r.getStack();
10611 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10612 throw new IllegalStateException(
10613 "exitFreeformMode: You can only go fullscreen from freeform.");
10616 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10617 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10618 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10620 Binder.restoreCallingIdentity(ident);
10626 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10627 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10628 if (StackId.isHomeOrRecentsStack(stackId)) {
10629 throw new IllegalArgumentException(
10630 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10632 synchronized (this) {
10633 long ident = Binder.clearCallingIdentity();
10635 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10636 if (task == null) {
10637 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10641 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10642 + " to stackId=" + stackId + " toTop=" + toTop);
10643 if (stackId == DOCKED_STACK_ID) {
10644 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10645 null /* initialBounds */);
10647 task.reparent(stackId, toTop,
10648 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10650 Binder.restoreCallingIdentity(ident);
10656 public void swapDockedAndFullscreenStack() throws RemoteException {
10657 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10658 synchronized (this) {
10659 long ident = Binder.clearCallingIdentity();
10661 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10662 FULLSCREEN_WORKSPACE_STACK_ID);
10663 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10665 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10666 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10668 if (topTask == null || tasks == null || tasks.size() == 0) {
10670 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10674 // TODO: App transition
10675 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10677 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10678 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10679 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10680 final int size = tasks.size();
10681 for (int i = 0; i < size; i++) {
10682 final int id = tasks.get(i).taskId;
10683 if (id == topTask.taskId) {
10687 // Defer the resume until after all the tasks have been moved
10688 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10689 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10690 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10693 // Because we deferred the resume to avoid conflicts with stack switches while
10694 // resuming, we need to do it after all the tasks are moved.
10695 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10696 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10698 mWindowManager.executeAppTransition();
10700 Binder.restoreCallingIdentity(ident);
10706 * Moves the input task to the docked stack.
10708 * @param taskId Id of task to move.
10709 * @param createMode The mode the docked stack should be created in if it doesn't exist
10711 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10713 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10714 * @param toTop If the task and stack should be moved to the top.
10715 * @param animate Whether we should play an animation for the moving the task
10716 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10717 * docked stack. Pass {@code null} to use default bounds.
10720 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10721 Rect initialBounds) {
10722 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10723 synchronized (this) {
10724 long ident = Binder.clearCallingIdentity();
10726 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10727 if (task == null) {
10728 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10732 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10733 + " to createMode=" + createMode + " toTop=" + toTop);
10734 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10736 // Defer resuming until we move the home stack to the front below
10737 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10738 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10739 "moveTaskToDockedStack");
10741 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10745 Binder.restoreCallingIdentity(ident);
10751 * Moves the top activity in the input stackId to the pinned stack.
10753 * @param stackId Id of stack to move the top activity to pinned stack.
10754 * @param bounds Bounds to use for pinned stack.
10756 * @return True if the top activity of the input stack was successfully moved to the pinned
10760 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10761 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10762 synchronized (this) {
10763 if (!mSupportsPictureInPicture) {
10764 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10765 + "Device doesn't support picture-in-picture mode");
10768 long ident = Binder.clearCallingIdentity();
10770 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10772 Binder.restoreCallingIdentity(ident);
10778 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10779 boolean preserveWindows, boolean animate, int animationDuration) {
10780 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10781 long ident = Binder.clearCallingIdentity();
10783 synchronized (this) {
10785 if (stackId == PINNED_STACK_ID) {
10786 final PinnedActivityStack pinnedStack =
10787 mStackSupervisor.getStack(PINNED_STACK_ID);
10788 if (pinnedStack != null) {
10789 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10790 destBounds, animationDuration, false /* fromFullscreen */);
10793 throw new IllegalArgumentException("Stack: " + stackId
10794 + " doesn't support animated resize.");
10797 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10798 null /* tempTaskInsetBounds */, preserveWindows,
10799 allowResizeInDockedMode, !DEFER_RESUME);
10803 Binder.restoreCallingIdentity(ident);
10808 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10809 Rect tempDockedTaskInsetBounds,
10810 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10811 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10812 "resizeDockedStack()");
10813 long ident = Binder.clearCallingIdentity();
10815 synchronized (this) {
10816 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10817 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10821 Binder.restoreCallingIdentity(ident);
10826 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10827 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10828 "resizePinnedStack()");
10829 final long ident = Binder.clearCallingIdentity();
10831 synchronized (this) {
10832 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10835 Binder.restoreCallingIdentity(ident);
10840 * Try to place task to provided position. The final position might be different depending on
10841 * current user and stacks state. The task will be moved to target stack if it's currently in
10845 public void positionTaskInStack(int taskId, int stackId, int position) {
10846 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10847 if (StackId.isHomeOrRecentsStack(stackId)) {
10848 throw new IllegalArgumentException(
10849 "positionTaskInStack: Attempt to change the position of task "
10850 + taskId + " in/to home/recents stack");
10852 synchronized (this) {
10853 long ident = Binder.clearCallingIdentity();
10855 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10856 + taskId + " in stackId=" + stackId + " at position=" + position);
10857 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10858 if (task == null) {
10859 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10863 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10866 // TODO: Have the callers of this API call a separate reparent method if that is
10867 // what they intended to do vs. having this method also do reparenting.
10868 if (task.getStack() == stack) {
10869 // Change position in current stack.
10870 stack.positionChildAt(task, position);
10872 // Reparent to new stack.
10873 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10874 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10877 Binder.restoreCallingIdentity(ident);
10883 public List<StackInfo> getAllStackInfos() {
10884 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10885 long ident = Binder.clearCallingIdentity();
10887 synchronized (this) {
10888 return mStackSupervisor.getAllStackInfosLocked();
10891 Binder.restoreCallingIdentity(ident);
10896 public StackInfo getStackInfo(int stackId) {
10897 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10898 long ident = Binder.clearCallingIdentity();
10900 synchronized (this) {
10901 return mStackSupervisor.getStackInfoLocked(stackId);
10904 Binder.restoreCallingIdentity(ident);
10909 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10910 synchronized(this) {
10911 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10916 public void updateDeviceOwner(String packageName) {
10917 final int callingUid = Binder.getCallingUid();
10918 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10919 throw new SecurityException("updateDeviceOwner called from non-system process");
10921 synchronized (this) {
10922 mDeviceOwnerName = packageName;
10927 public void updateLockTaskPackages(int userId, String[] packages) {
10928 final int callingUid = Binder.getCallingUid();
10929 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10930 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10931 "updateLockTaskPackages()");
10933 synchronized (this) {
10934 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10935 Arrays.toString(packages));
10936 mLockTaskPackages.put(userId, packages);
10937 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10942 void startLockTaskModeLocked(TaskRecord task) {
10943 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10944 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10948 // When a task is locked, dismiss the pinned stack if it exists
10949 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10951 if (pinnedStack != null) {
10952 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10955 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10956 // is initiated by system after the pinning request was shown and locked mode is initiated
10957 // by an authorized app directly
10958 final int callingUid = Binder.getCallingUid();
10959 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10960 long ident = Binder.clearCallingIdentity();
10962 if (!isSystemInitiated) {
10963 task.mLockTaskUid = callingUid;
10964 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10965 // startLockTask() called by app and task mode is lockTaskModeDefault.
10966 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10967 StatusBarManagerInternal statusBarManager =
10968 LocalServices.getService(StatusBarManagerInternal.class);
10969 if (statusBarManager != null) {
10970 statusBarManager.showScreenPinningRequest(task.taskId);
10975 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10976 if (stack == null || task != stack.topTask()) {
10977 throw new IllegalArgumentException("Invalid task, not in foreground");
10980 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10982 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10983 ActivityManager.LOCK_TASK_MODE_PINNED :
10984 ActivityManager.LOCK_TASK_MODE_LOCKED,
10985 "startLockTask", true);
10987 Binder.restoreCallingIdentity(ident);
10992 public void startLockTaskModeById(int taskId) {
10993 synchronized (this) {
10994 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10995 if (task != null) {
10996 startLockTaskModeLocked(task);
11002 public void startLockTaskModeByToken(IBinder token) {
11003 synchronized (this) {
11004 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11008 final TaskRecord task = r.getTask();
11009 if (task != null) {
11010 startLockTaskModeLocked(task);
11016 public void startSystemLockTaskMode(int taskId) throws RemoteException {
11017 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11018 // This makes inner call to look as if it was initiated by system.
11019 long ident = Binder.clearCallingIdentity();
11021 synchronized (this) {
11022 startLockTaskModeById(taskId);
11025 Binder.restoreCallingIdentity(ident);
11030 public void stopLockTaskMode() {
11031 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11032 if (lockTask == null) {
11033 // Our work here is done.
11037 final int callingUid = Binder.getCallingUid();
11038 final int lockTaskUid = lockTask.mLockTaskUid;
11039 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11040 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11044 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11045 // It is possible lockTaskMode was started by the system process because
11046 // android:lockTaskMode is set to a locking value in the application manifest
11047 // instead of the app calling startLockTaskMode. In this case
11048 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11049 // {@link TaskRecord.effectiveUid} instead. Also caller with
11050 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11051 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11052 && callingUid != lockTaskUid
11053 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11054 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11055 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11058 long ident = Binder.clearCallingIdentity();
11060 Log.d(TAG, "stopLockTaskMode");
11062 synchronized (this) {
11063 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11064 "stopLockTask", true);
11066 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11068 tm.showInCallScreen(false);
11071 Binder.restoreCallingIdentity(ident);
11076 * This API should be called by SystemUI only when user perform certain action to dismiss
11077 * lock task mode. We should only dismiss pinned lock task mode in this case.
11080 public void stopSystemLockTaskMode() throws RemoteException {
11081 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11082 stopLockTaskMode();
11084 mStackSupervisor.showLockTaskToast();
11089 public boolean isInLockTaskMode() {
11090 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11094 public int getLockTaskModeState() {
11095 synchronized (this) {
11096 return mStackSupervisor.getLockTaskModeState();
11101 public void showLockTaskEscapeMessage(IBinder token) {
11102 synchronized (this) {
11103 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11107 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11112 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11113 throws RemoteException {
11114 synchronized (this) {
11115 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11117 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11121 final long origId = Binder.clearCallingIdentity();
11123 r.setDisablePreviewScreenshots(disable);
11125 Binder.restoreCallingIdentity(origId);
11130 // =========================================================
11131 // CONTENT PROVIDERS
11132 // =========================================================
11134 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11135 List<ProviderInfo> providers = null;
11137 providers = AppGlobals.getPackageManager()
11138 .queryContentProviders(app.processName, app.uid,
11139 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11140 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11142 } catch (RemoteException ex) {
11144 if (DEBUG_MU) Slog.v(TAG_MU,
11145 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11146 int userId = app.userId;
11147 if (providers != null) {
11148 int N = providers.size();
11149 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11150 for (int i=0; i<N; i++) {
11151 // TODO: keep logic in sync with installEncryptionUnawareProviders
11153 (ProviderInfo)providers.get(i);
11154 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11155 cpi.name, cpi.flags);
11156 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11157 // This is a singleton provider, but a user besides the
11158 // default user is asking to initialize a process it runs
11159 // in... well, no, it doesn't actually run in this process,
11160 // it runs in the process of the default user. Get rid of it.
11161 providers.remove(i);
11167 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11168 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11170 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11171 mProviderMap.putProviderByClass(comp, cpr);
11173 if (DEBUG_MU) Slog.v(TAG_MU,
11174 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11175 app.pubProviders.put(cpi.name, cpr);
11176 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11177 // Don't add this if it is a platform component that is marked
11178 // to run in multiple processes, because this is actually
11179 // part of the framework so doesn't make sense to track as a
11180 // separate apk in the process.
11181 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11184 notifyPackageUse(cpi.applicationInfo.packageName,
11185 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11192 * Check if the calling UID has a possible chance at accessing the provider
11193 * at the given authority and user.
11195 public String checkContentProviderAccess(String authority, int userId) {
11196 if (userId == UserHandle.USER_ALL) {
11197 mContext.enforceCallingOrSelfPermission(
11198 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11199 userId = UserHandle.getCallingUserId();
11202 ProviderInfo cpi = null;
11204 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11205 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11206 | PackageManager.MATCH_DISABLED_COMPONENTS
11207 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11208 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11210 } catch (RemoteException ignored) {
11213 return "Failed to find provider " + authority + " for user " + userId
11214 + "; expected to find a valid ContentProvider for this authority";
11217 ProcessRecord r = null;
11218 synchronized (mPidsSelfLocked) {
11219 r = mPidsSelfLocked.get(Binder.getCallingPid());
11222 return "Failed to find PID " + Binder.getCallingPid();
11225 synchronized (this) {
11226 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11231 * Check if {@link ProcessRecord} has a possible chance at accessing the
11232 * given {@link ProviderInfo}. Final permission checking is always done
11233 * in {@link ContentProvider}.
11235 private final String checkContentProviderPermissionLocked(
11236 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11237 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11238 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11239 boolean checkedGrants = false;
11241 // Looking for cross-user grants before enforcing the typical cross-users permissions
11242 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11243 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11244 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11247 checkedGrants = true;
11249 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11250 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11251 if (userId != tmpTargetUserId) {
11252 // When we actually went to determine the final targer user ID, this ended
11253 // up different than our initial check for the authority. This is because
11254 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11255 // SELF. So we need to re-check the grants again.
11256 checkedGrants = false;
11259 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11260 cpi.applicationInfo.uid, cpi.exported)
11261 == PackageManager.PERMISSION_GRANTED) {
11264 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11265 cpi.applicationInfo.uid, cpi.exported)
11266 == PackageManager.PERMISSION_GRANTED) {
11270 PathPermission[] pps = cpi.pathPermissions;
11272 int i = pps.length;
11275 PathPermission pp = pps[i];
11276 String pprperm = pp.getReadPermission();
11277 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11278 cpi.applicationInfo.uid, cpi.exported)
11279 == PackageManager.PERMISSION_GRANTED) {
11282 String ppwperm = pp.getWritePermission();
11283 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11284 cpi.applicationInfo.uid, cpi.exported)
11285 == PackageManager.PERMISSION_GRANTED) {
11290 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11294 final String suffix;
11295 if (!cpi.exported) {
11296 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11297 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11298 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11300 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11302 final String msg = "Permission Denial: opening provider " + cpi.name
11303 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11304 + ", uid=" + callingUid + ")" + suffix;
11310 * Returns if the ContentProvider has granted a uri to callingUid
11312 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11313 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11314 if (perms != null) {
11315 for (int i=perms.size()-1; i>=0; i--) {
11316 GrantUri grantUri = perms.keyAt(i);
11317 if (grantUri.sourceUserId == userId || !checkUser) {
11318 if (matchesProvider(grantUri.uri, cpi)) {
11328 * Returns true if the uri authority is one of the authorities specified in the provider.
11330 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11331 String uriAuth = uri.getAuthority();
11332 String cpiAuth = cpi.authority;
11333 if (cpiAuth.indexOf(';') == -1) {
11334 return cpiAuth.equals(uriAuth);
11336 String[] cpiAuths = cpiAuth.split(";");
11337 int length = cpiAuths.length;
11338 for (int i = 0; i < length; i++) {
11339 if (cpiAuths[i].equals(uriAuth)) return true;
11344 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11345 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11347 for (int i=0; i<r.conProviders.size(); i++) {
11348 ContentProviderConnection conn = r.conProviders.get(i);
11349 if (conn.provider == cpr) {
11350 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11351 "Adding provider requested by "
11352 + r.processName + " from process "
11353 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11354 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11356 conn.stableCount++;
11357 conn.numStableIncs++;
11359 conn.unstableCount++;
11360 conn.numUnstableIncs++;
11365 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11367 conn.stableCount = 1;
11368 conn.numStableIncs = 1;
11370 conn.unstableCount = 1;
11371 conn.numUnstableIncs = 1;
11373 cpr.connections.add(conn);
11374 r.conProviders.add(conn);
11375 startAssociationLocked(r.uid, r.processName, r.curProcState,
11376 cpr.uid, cpr.name, cpr.info.processName);
11379 cpr.addExternalProcessHandleLocked(externalProcessToken);
11383 boolean decProviderCountLocked(ContentProviderConnection conn,
11384 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11385 if (conn != null) {
11386 cpr = conn.provider;
11387 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11388 "Removing provider requested by "
11389 + conn.client.processName + " from process "
11390 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11391 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11393 conn.stableCount--;
11395 conn.unstableCount--;
11397 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11398 cpr.connections.remove(conn);
11399 conn.client.conProviders.remove(conn);
11400 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11401 // The client is more important than last activity -- note the time this
11402 // is happening, so we keep the old provider process around a bit as last
11403 // activity to avoid thrashing it.
11404 if (cpr.proc != null) {
11405 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11408 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11413 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11417 private void checkTime(long startTime, String where) {
11418 long now = SystemClock.uptimeMillis();
11419 if ((now-startTime) > 50) {
11420 // If we are taking more than 50ms, log about it.
11421 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11425 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11427 PROC_SPACE_TERM|PROC_PARENS,
11428 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11431 private final long[] mProcessStateStatsLongs = new long[1];
11433 boolean isProcessAliveLocked(ProcessRecord proc) {
11434 if (proc.procStatFile == null) {
11435 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11437 mProcessStateStatsLongs[0] = 0;
11438 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11439 mProcessStateStatsLongs, null)) {
11440 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11443 final long state = mProcessStateStatsLongs[0];
11444 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11446 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11449 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11450 String name, IBinder token, boolean stable, int userId) {
11451 ContentProviderRecord cpr;
11452 ContentProviderConnection conn = null;
11453 ProviderInfo cpi = null;
11455 synchronized(this) {
11456 long startTime = SystemClock.uptimeMillis();
11458 ProcessRecord r = null;
11459 if (caller != null) {
11460 r = getRecordForAppLocked(caller);
11462 throw new SecurityException(
11463 "Unable to find app for caller " + caller
11464 + " (pid=" + Binder.getCallingPid()
11465 + ") when getting content provider " + name);
11469 boolean checkCrossUser = true;
11471 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11473 // First check if this content provider has been published...
11474 cpr = mProviderMap.getProviderByName(name, userId);
11475 // If that didn't work, check if it exists for user 0 and then
11476 // verify that it's a singleton provider before using it.
11477 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11478 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11481 if (isSingleton(cpi.processName, cpi.applicationInfo,
11482 cpi.name, cpi.flags)
11483 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11484 userId = UserHandle.USER_SYSTEM;
11485 checkCrossUser = false;
11493 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11494 if (providerRunning) {
11497 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11498 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11500 throw new SecurityException(msg);
11502 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11504 if (r != null && cpr.canRunHere(r)) {
11505 // This provider has been published or is in the process
11506 // of being published... but it is also allowed to run
11507 // in the caller's process, so don't make a connection
11508 // and just let the caller instantiate its own instance.
11509 ContentProviderHolder holder = cpr.newHolder(null);
11510 // don't give caller the provider object, it needs
11511 // to make its own.
11512 holder.provider = null;
11515 // Don't expose providers between normal apps and instant apps
11517 if (AppGlobals.getPackageManager()
11518 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11521 } catch (RemoteException e) {
11524 final long origId = Binder.clearCallingIdentity();
11526 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11528 // In this case the provider instance already exists, so we can
11529 // return it right away.
11530 conn = incProviderCountLocked(r, cpr, token, stable);
11531 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11532 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11533 // If this is a perceptible app accessing the provider,
11534 // make sure to count it as being accessed and thus
11535 // back up on the LRU list. This is good because
11536 // content providers are often expensive to start.
11537 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11538 updateLruProcessLocked(cpr.proc, false, null);
11539 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11543 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11544 final int verifiedAdj = cpr.proc.verifiedAdj;
11545 boolean success = updateOomAdjLocked(cpr.proc, true);
11546 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11547 // if the process has been successfully adjusted. So to reduce races with
11548 // it, we will check whether the process still exists. Note that this doesn't
11549 // completely get rid of races with LMK killing the process, but should make
11550 // them much smaller.
11551 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11554 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11555 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11556 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11557 // NOTE: there is still a race here where a signal could be
11558 // pending on the process even though we managed to update its
11559 // adj level. Not sure what to do about this, but at least
11560 // the race is now smaller.
11562 // Uh oh... it looks like the provider's process
11563 // has been killed on us. We need to wait for a new
11564 // process to be started, and make sure its death
11565 // doesn't kill our process.
11566 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11567 + " is crashing; detaching " + r);
11568 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11569 checkTime(startTime, "getContentProviderImpl: before appDied");
11570 appDiedLocked(cpr.proc);
11571 checkTime(startTime, "getContentProviderImpl: after appDied");
11573 // This wasn't the last ref our process had on
11574 // the provider... we have now been killed, bail.
11577 providerRunning = false;
11580 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11583 Binder.restoreCallingIdentity(origId);
11586 if (!providerRunning) {
11588 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11589 cpi = AppGlobals.getPackageManager().
11590 resolveContentProvider(name,
11591 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11592 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11593 } catch (RemoteException ex) {
11598 // If the provider is a singleton AND
11599 // (it's a call within the same user || the provider is a
11601 // Then allow connecting to the singleton provider
11602 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11603 cpi.name, cpi.flags)
11604 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11606 userId = UserHandle.USER_SYSTEM;
11608 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11609 checkTime(startTime, "getContentProviderImpl: got app info for user");
11612 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11613 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11615 throw new SecurityException(msg);
11617 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11619 if (!mProcessesReady
11620 && !cpi.processName.equals("system")) {
11621 // If this content provider does not run in the system
11622 // process, and the system is not yet ready to run other
11623 // processes, then fail fast instead of hanging.
11624 throw new IllegalArgumentException(
11625 "Attempt to launch content provider before system ready");
11628 // Make sure that the user who owns this provider is running. If not,
11629 // we don't want to allow it to run.
11630 if (!mUserController.isUserRunningLocked(userId, 0)) {
11631 Slog.w(TAG, "Unable to launch app "
11632 + cpi.applicationInfo.packageName + "/"
11633 + cpi.applicationInfo.uid + " for provider "
11634 + name + ": user " + userId + " is stopped");
11638 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11639 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11640 cpr = mProviderMap.getProviderByClass(comp, userId);
11641 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11642 final boolean firstClass = cpr == null;
11644 final long ident = Binder.clearCallingIdentity();
11646 // If permissions need a review before any of the app components can run,
11647 // we return no provider and launch a review activity if the calling app
11648 // is in the foreground.
11649 if (mPermissionReviewRequired) {
11650 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11656 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11657 ApplicationInfo ai =
11658 AppGlobals.getPackageManager().
11659 getApplicationInfo(
11660 cpi.applicationInfo.packageName,
11661 STOCK_PM_FLAGS, userId);
11662 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11664 Slog.w(TAG, "No package info for content provider "
11668 ai = getAppInfoForUser(ai, userId);
11669 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11670 } catch (RemoteException ex) {
11671 // pm is in same process, this will never happen.
11673 Binder.restoreCallingIdentity(ident);
11677 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11679 if (r != null && cpr.canRunHere(r)) {
11680 // If this is a multiprocess provider, then just return its
11681 // info and allow the caller to instantiate it. Only do
11682 // this if the provider is the same user as the caller's
11683 // process, or can run as root (so can be in any process).
11684 return cpr.newHolder(null);
11687 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11688 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11689 + cpr.info.name + " callers=" + Debug.getCallers(6));
11691 // This is single process, and our app is now connecting to it.
11692 // See if we are already in the process of launching this
11694 final int N = mLaunchingProviders.size();
11696 for (i = 0; i < N; i++) {
11697 if (mLaunchingProviders.get(i) == cpr) {
11702 // If the provider is not already being launched, then get it
11705 final long origId = Binder.clearCallingIdentity();
11708 // Content provider is now in use, its package can't be stopped.
11710 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11711 AppGlobals.getPackageManager().setPackageStoppedState(
11712 cpr.appInfo.packageName, false, userId);
11713 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11714 } catch (RemoteException e) {
11715 } catch (IllegalArgumentException e) {
11716 Slog.w(TAG, "Failed trying to unstop package "
11717 + cpr.appInfo.packageName + ": " + e);
11720 // Use existing process if already started
11721 checkTime(startTime, "getContentProviderImpl: looking for process record");
11722 ProcessRecord proc = getProcessRecordLocked(
11723 cpi.processName, cpr.appInfo.uid, false);
11724 if (proc != null && proc.thread != null && !proc.killed) {
11725 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11726 "Installing in existing process " + proc);
11727 if (!proc.pubProviders.containsKey(cpi.name)) {
11728 checkTime(startTime, "getContentProviderImpl: scheduling install");
11729 proc.pubProviders.put(cpi.name, cpr);
11731 proc.thread.scheduleInstallProvider(cpi);
11732 } catch (RemoteException e) {
11736 checkTime(startTime, "getContentProviderImpl: before start process");
11737 proc = startProcessLocked(cpi.processName,
11738 cpr.appInfo, false, 0, "content provider",
11739 new ComponentName(cpi.applicationInfo.packageName,
11740 cpi.name), false, false, false);
11741 checkTime(startTime, "getContentProviderImpl: after start process");
11742 if (proc == null) {
11743 Slog.w(TAG, "Unable to launch app "
11744 + cpi.applicationInfo.packageName + "/"
11745 + cpi.applicationInfo.uid + " for provider "
11746 + name + ": process is bad");
11750 cpr.launchingApp = proc;
11751 mLaunchingProviders.add(cpr);
11753 Binder.restoreCallingIdentity(origId);
11757 checkTime(startTime, "getContentProviderImpl: updating data structures");
11759 // Make sure the provider is published (the same provider class
11760 // may be published under multiple names).
11762 mProviderMap.putProviderByClass(comp, cpr);
11765 mProviderMap.putProviderByName(name, cpr);
11766 conn = incProviderCountLocked(r, cpr, token, stable);
11767 if (conn != null) {
11768 conn.waiting = true;
11771 checkTime(startTime, "getContentProviderImpl: done!");
11773 grantEphemeralAccessLocked(userId, null /*intent*/,
11774 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11777 // Wait for the provider to be published...
11778 synchronized (cpr) {
11779 while (cpr.provider == null) {
11780 if (cpr.launchingApp == null) {
11781 Slog.w(TAG, "Unable to launch app "
11782 + cpi.applicationInfo.packageName + "/"
11783 + cpi.applicationInfo.uid + " for provider "
11784 + name + ": launching app became null");
11785 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11786 UserHandle.getUserId(cpi.applicationInfo.uid),
11787 cpi.applicationInfo.packageName,
11788 cpi.applicationInfo.uid, name);
11792 if (DEBUG_MU) Slog.v(TAG_MU,
11793 "Waiting to start provider " + cpr
11794 + " launchingApp=" + cpr.launchingApp);
11795 if (conn != null) {
11796 conn.waiting = true;
11799 } catch (InterruptedException ex) {
11801 if (conn != null) {
11802 conn.waiting = false;
11807 return cpr != null ? cpr.newHolder(conn) : null;
11810 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11811 ProcessRecord r, final int userId) {
11812 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11813 cpi.packageName, userId)) {
11815 final boolean callerForeground = r == null || r.setSchedGroup
11816 != ProcessList.SCHED_GROUP_BACKGROUND;
11818 // Show a permission review UI only for starting from a foreground app
11819 if (!callerForeground) {
11820 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11821 + cpi.packageName + " requires a permissions review");
11825 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11826 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11827 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11828 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11830 if (DEBUG_PERMISSIONS_REVIEW) {
11831 Slog.i(TAG, "u" + userId + " Launching permission review "
11832 + "for package " + cpi.packageName);
11835 final UserHandle userHandle = new UserHandle(userId);
11836 mHandler.post(new Runnable() {
11838 public void run() {
11839 mContext.startActivityAsUser(intent, userHandle);
11849 PackageManagerInternal getPackageManagerInternalLocked() {
11850 if (mPackageManagerInt == null) {
11851 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11853 return mPackageManagerInt;
11857 public final ContentProviderHolder getContentProvider(
11858 IApplicationThread caller, String name, int userId, boolean stable) {
11859 enforceNotIsolatedCaller("getContentProvider");
11860 if (caller == null) {
11861 String msg = "null IApplicationThread when getting content provider "
11864 throw new SecurityException(msg);
11866 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11867 // with cross-user grant.
11868 return getContentProviderImpl(caller, name, null, stable, userId);
11871 public ContentProviderHolder getContentProviderExternal(
11872 String name, int userId, IBinder token) {
11873 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11874 "Do not have permission in call getContentProviderExternal()");
11875 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11876 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11877 return getContentProviderExternalUnchecked(name, token, userId);
11880 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11881 IBinder token, int userId) {
11882 return getContentProviderImpl(null, name, token, true, userId);
11886 * Drop a content provider from a ProcessRecord's bookkeeping
11888 public void removeContentProvider(IBinder connection, boolean stable) {
11889 enforceNotIsolatedCaller("removeContentProvider");
11890 long ident = Binder.clearCallingIdentity();
11892 synchronized (this) {
11893 ContentProviderConnection conn;
11895 conn = (ContentProviderConnection)connection;
11896 } catch (ClassCastException e) {
11897 String msg ="removeContentProvider: " + connection
11898 + " not a ContentProviderConnection";
11900 throw new IllegalArgumentException(msg);
11902 if (conn == null) {
11903 throw new NullPointerException("connection is null");
11905 if (decProviderCountLocked(conn, null, null, stable)) {
11906 updateOomAdjLocked();
11910 Binder.restoreCallingIdentity(ident);
11914 public void removeContentProviderExternal(String name, IBinder token) {
11915 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11916 "Do not have permission in call removeContentProviderExternal()");
11917 int userId = UserHandle.getCallingUserId();
11918 long ident = Binder.clearCallingIdentity();
11920 removeContentProviderExternalUnchecked(name, token, userId);
11922 Binder.restoreCallingIdentity(ident);
11926 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11927 synchronized (this) {
11928 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11930 //remove from mProvidersByClass
11931 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11935 //update content provider record entry info
11936 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11937 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11938 if (localCpr.hasExternalProcessHandles()) {
11939 if (localCpr.removeExternalProcessHandleLocked(token)) {
11940 updateOomAdjLocked();
11942 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11943 + " with no external reference for token: "
11947 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11948 + " with no external references.");
11953 public final void publishContentProviders(IApplicationThread caller,
11954 List<ContentProviderHolder> providers) {
11955 if (providers == null) {
11959 enforceNotIsolatedCaller("publishContentProviders");
11960 synchronized (this) {
11961 final ProcessRecord r = getRecordForAppLocked(caller);
11962 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11964 throw new SecurityException(
11965 "Unable to find app for caller " + caller
11966 + " (pid=" + Binder.getCallingPid()
11967 + ") when publishing content providers");
11970 final long origId = Binder.clearCallingIdentity();
11972 final int N = providers.size();
11973 for (int i = 0; i < N; i++) {
11974 ContentProviderHolder src = providers.get(i);
11975 if (src == null || src.info == null || src.provider == null) {
11978 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11979 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11981 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11982 mProviderMap.putProviderByClass(comp, dst);
11983 String names[] = dst.info.authority.split(";");
11984 for (int j = 0; j < names.length; j++) {
11985 mProviderMap.putProviderByName(names[j], dst);
11988 int launchingCount = mLaunchingProviders.size();
11990 boolean wasInLaunchingProviders = false;
11991 for (j = 0; j < launchingCount; j++) {
11992 if (mLaunchingProviders.get(j) == dst) {
11993 mLaunchingProviders.remove(j);
11994 wasInLaunchingProviders = true;
11999 if (wasInLaunchingProviders) {
12000 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12002 synchronized (dst) {
12003 dst.provider = src.provider;
12007 updateOomAdjLocked(r, true);
12008 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12009 src.info.authority);
12013 Binder.restoreCallingIdentity(origId);
12017 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12018 ContentProviderConnection conn;
12020 conn = (ContentProviderConnection)connection;
12021 } catch (ClassCastException e) {
12022 String msg ="refContentProvider: " + connection
12023 + " not a ContentProviderConnection";
12025 throw new IllegalArgumentException(msg);
12027 if (conn == null) {
12028 throw new NullPointerException("connection is null");
12031 synchronized (this) {
12033 conn.numStableIncs += stable;
12035 stable = conn.stableCount + stable;
12037 throw new IllegalStateException("stableCount < 0: " + stable);
12040 if (unstable > 0) {
12041 conn.numUnstableIncs += unstable;
12043 unstable = conn.unstableCount + unstable;
12044 if (unstable < 0) {
12045 throw new IllegalStateException("unstableCount < 0: " + unstable);
12048 if ((stable+unstable) <= 0) {
12049 throw new IllegalStateException("ref counts can't go to zero here: stable="
12050 + stable + " unstable=" + unstable);
12052 conn.stableCount = stable;
12053 conn.unstableCount = unstable;
12058 public void unstableProviderDied(IBinder connection) {
12059 ContentProviderConnection conn;
12061 conn = (ContentProviderConnection)connection;
12062 } catch (ClassCastException e) {
12063 String msg ="refContentProvider: " + connection
12064 + " not a ContentProviderConnection";
12066 throw new IllegalArgumentException(msg);
12068 if (conn == null) {
12069 throw new NullPointerException("connection is null");
12072 // Safely retrieve the content provider associated with the connection.
12073 IContentProvider provider;
12074 synchronized (this) {
12075 provider = conn.provider.provider;
12078 if (provider == null) {
12079 // Um, yeah, we're way ahead of you.
12083 // Make sure the caller is being honest with us.
12084 if (provider.asBinder().pingBinder()) {
12085 // Er, no, still looks good to us.
12086 synchronized (this) {
12087 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12088 + " says " + conn + " died, but we don't agree");
12093 // Well look at that! It's dead!
12094 synchronized (this) {
12095 if (conn.provider.provider != provider) {
12096 // But something changed... good enough.
12100 ProcessRecord proc = conn.provider.proc;
12101 if (proc == null || proc.thread == null) {
12102 // Seems like the process is already cleaned up.
12106 // As far as we're concerned, this is just like receiving a
12107 // death notification... just a bit prematurely.
12108 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12109 + ") early provider death");
12110 final long ident = Binder.clearCallingIdentity();
12112 appDiedLocked(proc);
12114 Binder.restoreCallingIdentity(ident);
12120 public void appNotRespondingViaProvider(IBinder connection) {
12121 enforceCallingPermission(
12122 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12124 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12125 if (conn == null) {
12126 Slog.w(TAG, "ContentProviderConnection is null");
12130 final ProcessRecord host = conn.provider.proc;
12131 if (host == null) {
12132 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12136 mHandler.post(new Runnable() {
12138 public void run() {
12139 mAppErrors.appNotResponding(host, null, null, false,
12140 "ContentProvider not responding");
12145 public final void installSystemProviders() {
12146 List<ProviderInfo> providers;
12147 synchronized (this) {
12148 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12149 providers = generateApplicationProvidersLocked(app);
12150 if (providers != null) {
12151 for (int i=providers.size()-1; i>=0; i--) {
12152 ProviderInfo pi = (ProviderInfo)providers.get(i);
12153 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12154 Slog.w(TAG, "Not installing system proc provider " + pi.name
12155 + ": not system .apk");
12156 providers.remove(i);
12161 if (providers != null) {
12162 mSystemThread.installSystemProviders(providers);
12165 mConstants.start(mContext.getContentResolver());
12166 mCoreSettingsObserver = new CoreSettingsObserver(this);
12167 mFontScaleSettingObserver = new FontScaleSettingObserver();
12169 // Now that the settings provider is published we can consider sending
12170 // in a rescue party.
12171 RescueParty.onSettingsProviderPublished(mContext);
12173 //mUsageStatsService.monitorPackages();
12176 private void startPersistentApps(int matchFlags) {
12177 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12179 synchronized (this) {
12181 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12182 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12183 for (ApplicationInfo app : apps) {
12184 if (!"android".equals(app.packageName)) {
12185 addAppLocked(app, null, false, null /* ABI override */);
12188 } catch (RemoteException ex) {
12194 * When a user is unlocked, we need to install encryption-unaware providers
12195 * belonging to any running apps.
12197 private void installEncryptionUnawareProviders(int userId) {
12198 // We're only interested in providers that are encryption unaware, and
12199 // we don't care about uninstalled apps, since there's no way they're
12200 // running at this point.
12201 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12203 synchronized (this) {
12204 final int NP = mProcessNames.getMap().size();
12205 for (int ip = 0; ip < NP; ip++) {
12206 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12207 final int NA = apps.size();
12208 for (int ia = 0; ia < NA; ia++) {
12209 final ProcessRecord app = apps.valueAt(ia);
12210 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12212 final int NG = app.pkgList.size();
12213 for (int ig = 0; ig < NG; ig++) {
12215 final String pkgName = app.pkgList.keyAt(ig);
12216 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12217 .getPackageInfo(pkgName, matchFlags, userId);
12218 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12219 for (ProviderInfo pi : pkgInfo.providers) {
12220 // TODO: keep in sync with generateApplicationProvidersLocked
12221 final boolean processMatch = Objects.equals(pi.processName,
12222 app.processName) || pi.multiprocess;
12223 final boolean userMatch = isSingleton(pi.processName,
12224 pi.applicationInfo, pi.name, pi.flags)
12225 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12226 if (processMatch && userMatch) {
12227 Log.v(TAG, "Installing " + pi);
12228 app.thread.scheduleInstallProvider(pi);
12230 Log.v(TAG, "Skipping " + pi);
12234 } catch (RemoteException ignored) {
12243 * Allows apps to retrieve the MIME type of a URI.
12244 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12245 * users, then it does not need permission to access the ContentProvider.
12246 * Either, it needs cross-user uri grants.
12248 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12250 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12251 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12253 public String getProviderMimeType(Uri uri, int userId) {
12254 enforceNotIsolatedCaller("getProviderMimeType");
12255 final String name = uri.getAuthority();
12256 int callingUid = Binder.getCallingUid();
12257 int callingPid = Binder.getCallingPid();
12259 boolean clearedIdentity = false;
12260 synchronized (this) {
12261 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12263 if (canClearIdentity(callingPid, callingUid, userId)) {
12264 clearedIdentity = true;
12265 ident = Binder.clearCallingIdentity();
12267 ContentProviderHolder holder = null;
12269 holder = getContentProviderExternalUnchecked(name, null, userId);
12270 if (holder != null) {
12271 return holder.provider.getType(uri);
12273 } catch (RemoteException e) {
12274 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12276 } catch (Exception e) {
12277 Log.w(TAG, "Exception while determining type of " + uri, e);
12280 // We need to clear the identity to call removeContentProviderExternalUnchecked
12281 if (!clearedIdentity) {
12282 ident = Binder.clearCallingIdentity();
12285 if (holder != null) {
12286 removeContentProviderExternalUnchecked(name, null, userId);
12289 Binder.restoreCallingIdentity(ident);
12296 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12297 if (UserHandle.getUserId(callingUid) == userId) {
12300 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12301 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12302 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12303 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12309 // =========================================================
12310 // GLOBAL MANAGEMENT
12311 // =========================================================
12313 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12314 boolean isolated, int isolatedUid) {
12315 String proc = customProcess != null ? customProcess : info.processName;
12316 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12317 final int userId = UserHandle.getUserId(info.uid);
12318 int uid = info.uid;
12320 if (isolatedUid == 0) {
12321 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12323 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12324 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12325 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12327 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12328 mNextIsolatedProcessUid++;
12329 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12330 // No process for this uid, use it.
12334 if (stepsLeft <= 0) {
12339 // Special case for startIsolatedProcess (internal only), where
12340 // the uid of the isolated process is specified by the caller.
12343 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12345 // Register the isolated UID with this application so BatteryStats knows to
12346 // attribute resource usage to the application.
12348 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12349 // about the process state of the isolated UID *before* it is registered with the
12350 // owning application.
12351 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12353 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12354 if (!mBooted && !mBooting
12355 && userId == UserHandle.USER_SYSTEM
12356 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12357 r.persistent = true;
12358 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12360 addProcessNameLocked(r);
12364 private boolean uidOnBackgroundWhitelist(final int uid) {
12365 final int appId = UserHandle.getAppId(uid);
12366 final int[] whitelist = mBackgroundAppIdWhitelist;
12367 final int N = whitelist.length;
12368 for (int i = 0; i < N; i++) {
12369 if (appId == whitelist[i]) {
12377 public void backgroundWhitelistUid(final int uid) {
12378 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12379 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12382 if (DEBUG_BACKGROUND_CHECK) {
12383 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12385 synchronized (this) {
12386 final int N = mBackgroundAppIdWhitelist.length;
12387 int[] newList = new int[N+1];
12388 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12389 newList[N] = UserHandle.getAppId(uid);
12390 mBackgroundAppIdWhitelist = newList;
12394 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12395 String abiOverride) {
12398 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12405 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12406 updateLruProcessLocked(app, false, null);
12407 updateOomAdjLocked();
12410 // This package really, really can not be stopped.
12412 AppGlobals.getPackageManager().setPackageStoppedState(
12413 info.packageName, false, UserHandle.getUserId(app.uid));
12414 } catch (RemoteException e) {
12415 } catch (IllegalArgumentException e) {
12416 Slog.w(TAG, "Failed trying to unstop package "
12417 + info.packageName + ": " + e);
12420 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12421 app.persistent = true;
12422 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12424 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12425 mPersistentStartingProcesses.add(app);
12426 startProcessLocked(app, "added application",
12427 customProcess != null ? customProcess : app.processName, abiOverride,
12428 null /* entryPoint */, null /* entryPointArgs */);
12434 public void unhandledBack() {
12435 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12436 "unhandledBack()");
12438 synchronized(this) {
12439 final long origId = Binder.clearCallingIdentity();
12441 getFocusedStack().unhandledBackLocked();
12443 Binder.restoreCallingIdentity(origId);
12448 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12449 enforceNotIsolatedCaller("openContentUri");
12450 final int userId = UserHandle.getCallingUserId();
12451 final Uri uri = Uri.parse(uriString);
12452 String name = uri.getAuthority();
12453 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12454 ParcelFileDescriptor pfd = null;
12456 // We record the binder invoker's uid in thread-local storage before
12457 // going to the content provider to open the file. Later, in the code
12458 // that handles all permissions checks, we look for this uid and use
12459 // that rather than the Activity Manager's own uid. The effect is that
12460 // we do the check against the caller's permissions even though it looks
12461 // to the content provider like the Activity Manager itself is making
12463 Binder token = new Binder();
12464 sCallerIdentity.set(new Identity(
12465 token, Binder.getCallingPid(), Binder.getCallingUid()));
12467 pfd = cph.provider.openFile(null, uri, "r", null, token);
12468 } catch (FileNotFoundException e) {
12469 // do nothing; pfd will be returned null
12471 // Ensure that whatever happens, we clean up the identity state
12472 sCallerIdentity.remove();
12473 // Ensure we're done with the provider.
12474 removeContentProviderExternalUnchecked(name, null, userId);
12477 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12482 // Actually is sleeping or shutting down or whatever else in the future
12483 // is an inactive state.
12484 boolean isSleepingOrShuttingDownLocked() {
12485 return isSleepingLocked() || mShuttingDown;
12488 boolean isShuttingDownLocked() {
12489 return mShuttingDown;
12492 boolean isSleepingLocked() {
12496 void onWakefulnessChanged(int wakefulness) {
12497 synchronized(this) {
12498 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12499 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12500 mWakefulness = wakefulness;
12502 if (wasAwake != isAwake) {
12503 // Also update state in a special way for running foreground services UI.
12504 mServices.updateScreenStateLocked(isAwake);
12505 sendNotifyVrManagerOfSleepState(!isAwake);
12510 void finishRunningVoiceLocked() {
12511 if (mRunningVoice != null) {
12512 mRunningVoice = null;
12513 mVoiceWakeLock.release();
12514 updateSleepIfNeededLocked();
12518 void startTimeTrackingFocusedActivityLocked() {
12519 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12520 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12521 mCurAppTimeTracker.start(resumedActivity.packageName);
12525 void updateSleepIfNeededLocked() {
12526 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12527 final boolean wasSleeping = mSleeping;
12529 if (!shouldSleep) {
12530 // If wasSleeping is true, we need to wake up activity manager state from when
12531 // we started sleeping. In either case, we need to apply the sleep tokens, which
12532 // will wake up stacks or put them to sleep as appropriate.
12535 startTimeTrackingFocusedActivityLocked();
12536 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12537 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12539 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12541 updateOomAdjLocked();
12543 } else if (!mSleeping && shouldSleep) {
12545 if (mCurAppTimeTracker != null) {
12546 mCurAppTimeTracker.stop();
12548 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12549 mStackSupervisor.goingToSleepLocked();
12550 updateOomAdjLocked();
12554 /** Pokes the task persister. */
12555 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12556 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12560 * Notifies all listeners when the pinned stack animation starts.
12563 public void notifyPinnedStackAnimationStarted() {
12564 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12568 * Notifies all listeners when the pinned stack animation ends.
12571 public void notifyPinnedStackAnimationEnded() {
12572 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12576 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12577 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12581 public boolean shutdown(int timeout) {
12582 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12583 != PackageManager.PERMISSION_GRANTED) {
12584 throw new SecurityException("Requires permission "
12585 + android.Manifest.permission.SHUTDOWN);
12588 boolean timedout = false;
12590 synchronized(this) {
12591 mShuttingDown = true;
12592 mStackSupervisor.prepareForShutdownLocked();
12593 updateEventDispatchingLocked();
12594 timedout = mStackSupervisor.shutdownLocked(timeout);
12597 mAppOpsService.shutdown();
12598 if (mUsageStatsService != null) {
12599 mUsageStatsService.prepareShutdown();
12601 mBatteryStatsService.shutdown();
12602 synchronized (this) {
12603 mProcessStats.shutdownLocked();
12604 notifyTaskPersisterLocked(null, true);
12610 public final void activitySlept(IBinder token) {
12611 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12613 final long origId = Binder.clearCallingIdentity();
12615 synchronized (this) {
12616 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12618 mStackSupervisor.activitySleptLocked(r);
12622 Binder.restoreCallingIdentity(origId);
12625 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12626 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12627 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12628 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12629 boolean wasRunningVoice = mRunningVoice != null;
12630 mRunningVoice = session;
12631 if (!wasRunningVoice) {
12632 mVoiceWakeLock.acquire();
12633 updateSleepIfNeededLocked();
12638 private void updateEventDispatchingLocked() {
12639 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12643 public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12644 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12645 != PackageManager.PERMISSION_GRANTED) {
12646 throw new SecurityException("Requires permission "
12647 + android.Manifest.permission.DEVICE_POWER);
12650 synchronized(this) {
12651 long ident = Binder.clearCallingIdentity();
12653 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12655 Binder.restoreCallingIdentity(ident);
12658 sendNotifyVrManagerOfKeyguardState(showing);
12662 public void notifyLockedProfile(@UserIdInt int userId) {
12664 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12665 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12667 } catch (RemoteException ex) {
12668 throw new SecurityException("Fail to check is caller a privileged app", ex);
12671 synchronized (this) {
12672 final long ident = Binder.clearCallingIdentity();
12674 if (mUserController.shouldConfirmCredentials(userId)) {
12675 if (mKeyguardController.isKeyguardLocked()) {
12676 // Showing launcher to avoid user entering credential twice.
12677 final int currentUserId = mUserController.getCurrentUserIdLocked();
12678 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12680 mStackSupervisor.lockAllProfileTasks(userId);
12683 Binder.restoreCallingIdentity(ident);
12689 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12690 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12691 synchronized (this) {
12692 final long ident = Binder.clearCallingIdentity();
12694 mActivityStarter.startConfirmCredentialIntent(intent, options);
12696 Binder.restoreCallingIdentity(ident);
12702 public void stopAppSwitches() {
12703 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12704 != PackageManager.PERMISSION_GRANTED) {
12705 throw new SecurityException("viewquires permission "
12706 + android.Manifest.permission.STOP_APP_SWITCHES);
12709 synchronized(this) {
12710 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12711 + APP_SWITCH_DELAY_TIME;
12712 mDidAppSwitch = false;
12713 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12714 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12715 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12719 public void resumeAppSwitches() {
12720 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12721 != PackageManager.PERMISSION_GRANTED) {
12722 throw new SecurityException("Requires permission "
12723 + android.Manifest.permission.STOP_APP_SWITCHES);
12726 synchronized(this) {
12727 // Note that we don't execute any pending app switches... we will
12728 // let those wait until either the timeout, or the next start
12729 // activity request.
12730 mAppSwitchesAllowedTime = 0;
12734 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12735 int callingPid, int callingUid, String name) {
12736 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12740 int perm = checkComponentPermission(
12741 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12742 sourceUid, -1, true);
12743 if (perm == PackageManager.PERMISSION_GRANTED) {
12747 // If the actual IPC caller is different from the logical source, then
12748 // also see if they are allowed to control app switches.
12749 if (callingUid != -1 && callingUid != sourceUid) {
12750 perm = checkComponentPermission(
12751 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12752 callingUid, -1, true);
12753 if (perm == PackageManager.PERMISSION_GRANTED) {
12758 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12762 public void setDebugApp(String packageName, boolean waitForDebugger,
12763 boolean persistent) {
12764 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12767 long ident = Binder.clearCallingIdentity();
12769 // Note that this is not really thread safe if there are multiple
12770 // callers into it at the same time, but that's not a situation we
12773 final ContentResolver resolver = mContext.getContentResolver();
12774 Settings.Global.putString(
12775 resolver, Settings.Global.DEBUG_APP,
12777 Settings.Global.putInt(
12778 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12779 waitForDebugger ? 1 : 0);
12782 synchronized (this) {
12784 mOrigDebugApp = mDebugApp;
12785 mOrigWaitForDebugger = mWaitForDebugger;
12787 mDebugApp = packageName;
12788 mWaitForDebugger = waitForDebugger;
12789 mDebugTransient = !persistent;
12790 if (packageName != null) {
12791 forceStopPackageLocked(packageName, -1, false, false, true, true,
12792 false, UserHandle.USER_ALL, "set debug app");
12796 Binder.restoreCallingIdentity(ident);
12800 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12801 synchronized (this) {
12802 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12803 if (!isDebuggable) {
12804 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12805 throw new SecurityException("Process not debuggable: " + app.packageName);
12809 mTrackAllocationApp = processName;
12813 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12814 synchronized (this) {
12815 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12816 if (!isDebuggable) {
12817 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12818 throw new SecurityException("Process not debuggable: " + app.packageName);
12821 mProfileApp = processName;
12823 if (mProfilerInfo != null) {
12824 if (mProfilerInfo.profileFd != null) {
12826 mProfilerInfo.profileFd.close();
12827 } catch (IOException e) {
12831 mProfilerInfo = new ProfilerInfo(profilerInfo);
12836 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12837 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12838 if (!isDebuggable) {
12839 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12840 throw new SecurityException("Process not debuggable: " + app.packageName);
12843 mNativeDebuggingApp = processName;
12847 public void setAlwaysFinish(boolean enabled) {
12848 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12849 "setAlwaysFinish()");
12851 long ident = Binder.clearCallingIdentity();
12853 Settings.Global.putInt(
12854 mContext.getContentResolver(),
12855 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12857 synchronized (this) {
12858 mAlwaysFinishActivities = enabled;
12861 Binder.restoreCallingIdentity(ident);
12866 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12867 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12868 "setActivityController()");
12869 synchronized (this) {
12870 mController = controller;
12871 mControllerIsAMonkey = imAMonkey;
12872 Watchdog.getInstance().setActivityController(controller);
12877 public void setUserIsMonkey(boolean userIsMonkey) {
12878 synchronized (this) {
12879 synchronized (mPidsSelfLocked) {
12880 final int callingPid = Binder.getCallingPid();
12881 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12882 if (proc == null) {
12883 throw new SecurityException("Unknown process: " + callingPid);
12885 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12886 throw new SecurityException("Only an instrumentation process "
12887 + "with a UiAutomation can call setUserIsMonkey");
12890 mUserIsMonkey = userIsMonkey;
12895 public boolean isUserAMonkey() {
12896 synchronized (this) {
12897 // If there is a controller also implies the user is a monkey.
12898 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12903 * @deprecated This method is only used by a few internal components and it will soon be
12904 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12905 * No new code should be calling it.
12909 public void requestBugReport(int bugreportType) {
12910 String extraOptions = null;
12911 switch (bugreportType) {
12912 case ActivityManager.BUGREPORT_OPTION_FULL:
12913 // Default options.
12915 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12916 extraOptions = "bugreportplus";
12918 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12919 extraOptions = "bugreportremote";
12921 case ActivityManager.BUGREPORT_OPTION_WEAR:
12922 extraOptions = "bugreportwear";
12924 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12925 extraOptions = "bugreporttelephony";
12928 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12931 // Always log caller, even if it does not have permission to dump.
12932 String type = extraOptions == null ? "bugreport" : extraOptions;
12933 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12935 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12936 if (extraOptions != null) {
12937 SystemProperties.set("dumpstate.options", extraOptions);
12939 SystemProperties.set("ctl.start", "bugreport");
12943 * @deprecated This method is only used by a few internal components and it will soon be
12944 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12945 * No new code should be calling it.
12949 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12951 if (!TextUtils.isEmpty(shareTitle)) {
12952 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12953 String errorStr = "shareTitle should be less than " +
12954 MAX_BUGREPORT_TITLE_SIZE + " characters";
12955 throw new IllegalArgumentException(errorStr);
12957 if (!TextUtils.isEmpty(shareDescription)) {
12960 length = shareDescription.getBytes("UTF-8").length;
12961 } catch (UnsupportedEncodingException e) {
12962 String errorStr = "shareDescription: UnsupportedEncodingException";
12963 throw new IllegalArgumentException(errorStr);
12965 if (length > SystemProperties.PROP_VALUE_MAX) {
12966 String errorStr = "shareTitle should be less than " +
12967 SystemProperties.PROP_VALUE_MAX + " bytes";
12968 throw new IllegalArgumentException(errorStr);
12970 SystemProperties.set("dumpstate.options.description", shareDescription);
12973 SystemProperties.set("dumpstate.options.title", shareTitle);
12977 Slog.d(TAG, "Bugreport notification title " + shareTitle
12978 + " description " + shareDescription);
12979 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12982 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12983 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12986 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12987 if (r != null && (r.instr != null || r.usingWrapper)) {
12988 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12990 return KEY_DISPATCHING_TIMEOUT;
12994 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12995 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12996 != PackageManager.PERMISSION_GRANTED) {
12997 throw new SecurityException("Requires permission "
12998 + android.Manifest.permission.FILTER_EVENTS);
13000 ProcessRecord proc;
13002 synchronized (this) {
13003 synchronized (mPidsSelfLocked) {
13004 proc = mPidsSelfLocked.get(pid);
13006 timeout = getInputDispatchingTimeoutLocked(proc);
13009 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13017 * Handle input dispatching timeouts.
13018 * Returns whether input dispatching should be aborted or not.
13020 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13021 final ActivityRecord activity, final ActivityRecord parent,
13022 final boolean aboveSystem, String reason) {
13023 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13024 != PackageManager.PERMISSION_GRANTED) {
13025 throw new SecurityException("Requires permission "
13026 + android.Manifest.permission.FILTER_EVENTS);
13029 final String annotation;
13030 if (reason == null) {
13031 annotation = "Input dispatching timed out";
13033 annotation = "Input dispatching timed out (" + reason + ")";
13036 if (proc != null) {
13037 synchronized (this) {
13038 if (proc.debugging) {
13042 if (proc.instr != null) {
13043 Bundle info = new Bundle();
13044 info.putString("shortMsg", "keyDispatchingTimedOut");
13045 info.putString("longMsg", annotation);
13046 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13050 mHandler.post(new Runnable() {
13052 public void run() {
13053 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13062 public Bundle getAssistContextExtras(int requestType) {
13063 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13064 null, null, true /* focused */, true /* newSessionId */,
13065 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13069 synchronized (pae) {
13070 while (!pae.haveResult) {
13073 } catch (InterruptedException e) {
13077 synchronized (this) {
13078 buildAssistBundleLocked(pae, pae.result);
13079 mPendingAssistExtras.remove(pae);
13080 mUiHandler.removeCallbacks(pae);
13086 public boolean isAssistDataAllowedOnCurrentActivity() {
13088 synchronized (this) {
13089 final ActivityStack focusedStack = getFocusedStack();
13090 if (focusedStack == null || focusedStack.isAssistantStack()) {
13094 final ActivityRecord activity = focusedStack.topActivity();
13095 if (activity == null) {
13098 userId = activity.userId;
13100 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13101 Context.DEVICE_POLICY_SERVICE);
13102 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13106 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13107 long ident = Binder.clearCallingIdentity();
13109 synchronized (this) {
13110 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13111 ActivityRecord top = getFocusedStack().topActivity();
13112 if (top != caller) {
13113 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13114 + " is not current top " + top);
13117 if (!top.nowVisible) {
13118 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13119 + " is not visible");
13123 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13126 Binder.restoreCallingIdentity(ident);
13131 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13132 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13133 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13134 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13135 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13139 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13140 IBinder activityToken, int flags) {
13141 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13142 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13143 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13146 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13147 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13148 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13150 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13151 "enqueueAssistContext()");
13153 synchronized (this) {
13154 ActivityRecord activity = getFocusedStack().topActivity();
13155 if (activity == null) {
13156 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13159 if (activity.app == null || activity.app.thread == null) {
13160 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13164 if (activityToken != null) {
13165 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13166 if (activity != caller) {
13167 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13168 + " is not current top " + activity);
13173 activity = ActivityRecord.forTokenLocked(activityToken);
13174 if (activity == null) {
13175 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13176 + " couldn't be found");
13179 if (activity.app == null || activity.app.thread == null) {
13180 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13185 PendingAssistExtras pae;
13186 Bundle extras = new Bundle();
13187 if (args != null) {
13188 extras.putAll(args);
13190 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13191 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13193 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13195 pae.isHome = activity.isHomeActivity();
13197 // Increment the sessionId if necessary
13198 if (newSessionId) {
13202 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13203 mViSessionId, flags);
13204 mPendingAssistExtras.add(pae);
13205 mUiHandler.postDelayed(pae, timeout);
13206 } catch (RemoteException e) {
13207 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13214 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13215 IResultReceiver receiver;
13216 synchronized (this) {
13217 mPendingAssistExtras.remove(pae);
13218 receiver = pae.receiver;
13220 if (receiver != null) {
13221 // Caller wants result sent back to them.
13222 Bundle sendBundle = new Bundle();
13223 // At least return the receiver extras
13224 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13225 pae.receiverExtras);
13227 pae.receiver.send(0, sendBundle);
13228 } catch (RemoteException e) {
13233 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13234 if (result != null) {
13235 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13237 if (pae.hint != null) {
13238 pae.extras.putBoolean(pae.hint, true);
13242 /** Called from an app when assist data is ready. */
13244 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13245 AssistContent content, Uri referrer) {
13246 PendingAssistExtras pae = (PendingAssistExtras)token;
13247 synchronized (pae) {
13248 pae.result = extras;
13249 pae.structure = structure;
13250 pae.content = content;
13251 if (referrer != null) {
13252 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13254 if (structure != null) {
13255 structure.setHomeActivity(pae.isHome);
13257 pae.haveResult = true;
13259 if (pae.intent == null && pae.receiver == null) {
13260 // Caller is just waiting for the result.
13264 // We are now ready to launch the assist activity.
13265 IResultReceiver sendReceiver = null;
13266 Bundle sendBundle = null;
13267 synchronized (this) {
13268 buildAssistBundleLocked(pae, extras);
13269 boolean exists = mPendingAssistExtras.remove(pae);
13270 mUiHandler.removeCallbacks(pae);
13275 if ((sendReceiver=pae.receiver) != null) {
13276 // Caller wants result sent back to them.
13277 sendBundle = new Bundle();
13278 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13279 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13280 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13281 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13282 pae.receiverExtras);
13285 if (sendReceiver != null) {
13287 sendReceiver.send(0, sendBundle);
13288 } catch (RemoteException e) {
13293 final long ident = Binder.clearCallingIdentity();
13295 if (TextUtils.equals(pae.intent.getAction(),
13296 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13297 pae.intent.putExtras(pae.extras);
13298 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13300 pae.intent.replaceExtras(pae.extras);
13301 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13302 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13303 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13304 closeSystemDialogs("assist");
13307 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13308 } catch (ActivityNotFoundException e) {
13309 Slog.w(TAG, "No activity to handle assist action.", e);
13313 Binder.restoreCallingIdentity(ident);
13317 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13319 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13320 true /* focused */, true /* newSessionId */, userHandle, args,
13321 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13324 public void registerProcessObserver(IProcessObserver observer) {
13325 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13326 "registerProcessObserver()");
13327 synchronized (this) {
13328 mProcessObservers.register(observer);
13333 public void unregisterProcessObserver(IProcessObserver observer) {
13334 synchronized (this) {
13335 mProcessObservers.unregister(observer);
13340 public int getUidProcessState(int uid, String callingPackage) {
13341 if (!hasUsageStatsPermission(callingPackage)) {
13342 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13343 "getUidProcessState");
13346 synchronized (this) {
13347 UidRecord uidRec = mActiveUids.get(uid);
13348 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13353 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13354 String callingPackage) {
13355 if (!hasUsageStatsPermission(callingPackage)) {
13356 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13357 "registerUidObserver");
13359 synchronized (this) {
13360 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13361 callingPackage, which, cutpoint));
13366 public void unregisterUidObserver(IUidObserver observer) {
13367 synchronized (this) {
13368 mUidObservers.unregister(observer);
13373 public boolean convertFromTranslucent(IBinder token) {
13374 final long origId = Binder.clearCallingIdentity();
13376 synchronized (this) {
13377 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13381 final boolean translucentChanged = r.changeWindowTranslucency(true);
13382 if (translucentChanged) {
13383 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13385 mWindowManager.setAppFullscreen(token, true);
13386 return translucentChanged;
13389 Binder.restoreCallingIdentity(origId);
13394 public boolean convertToTranslucent(IBinder token, Bundle options) {
13395 final long origId = Binder.clearCallingIdentity();
13397 synchronized (this) {
13398 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13402 final TaskRecord task = r.getTask();
13403 int index = task.mActivities.lastIndexOf(r);
13405 ActivityRecord under = task.mActivities.get(index - 1);
13406 under.returningOptions = ActivityOptions.fromBundle(options);
13408 final boolean translucentChanged = r.changeWindowTranslucency(false);
13409 if (translucentChanged) {
13410 r.getStack().convertActivityToTranslucent(r);
13412 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13413 mWindowManager.setAppFullscreen(token, false);
13414 return translucentChanged;
13417 Binder.restoreCallingIdentity(origId);
13422 public Bundle getActivityOptions(IBinder token) {
13423 final long origId = Binder.clearCallingIdentity();
13425 synchronized (this) {
13426 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13428 final ActivityOptions activityOptions = r.takeOptionsLocked();
13429 return activityOptions == null ? null : activityOptions.toBundle();
13434 Binder.restoreCallingIdentity(origId);
13439 public void setImmersive(IBinder token, boolean immersive) {
13440 synchronized(this) {
13441 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13443 throw new IllegalArgumentException();
13445 r.immersive = immersive;
13447 // update associated state if we're frontmost
13448 if (r == mStackSupervisor.getResumedActivityLocked()) {
13449 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13450 applyUpdateLockStateLocked(r);
13456 public boolean isImmersive(IBinder token) {
13457 synchronized (this) {
13458 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13460 throw new IllegalArgumentException();
13462 return r.immersive;
13467 public void setVrThread(int tid) {
13468 enforceSystemHasVrFeature();
13469 synchronized (this) {
13470 synchronized (mPidsSelfLocked) {
13471 final int pid = Binder.getCallingPid();
13472 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13473 mVrController.setVrThreadLocked(tid, pid, proc);
13479 public void setPersistentVrThread(int tid) {
13480 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13481 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13482 + Binder.getCallingPid()
13483 + ", uid=" + Binder.getCallingUid()
13484 + " requires " + permission.RESTRICTED_VR_ACCESS;
13486 throw new SecurityException(msg);
13488 enforceSystemHasVrFeature();
13489 synchronized (this) {
13490 synchronized (mPidsSelfLocked) {
13491 final int pid = Binder.getCallingPid();
13492 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13493 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13499 * Schedule the given thread a normal scheduling priority.
13501 * @param tid the tid of the thread to adjust the scheduling of.
13502 * @param suppressLogs {@code true} if any error logging should be disabled.
13504 * @return {@code true} if this succeeded.
13506 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13508 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13510 } catch (IllegalArgumentException e) {
13511 if (!suppressLogs) {
13512 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13514 } catch (SecurityException e) {
13515 if (!suppressLogs) {
13516 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13523 * Schedule the given thread an FIFO scheduling priority.
13525 * @param tid the tid of the thread to adjust the scheduling of.
13526 * @param suppressLogs {@code true} if any error logging should be disabled.
13528 * @return {@code true} if this succeeded.
13530 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13532 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13534 } catch (IllegalArgumentException e) {
13535 if (!suppressLogs) {
13536 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13538 } catch (SecurityException e) {
13539 if (!suppressLogs) {
13540 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13547 * Check that we have the features required for VR-related API calls, and throw an exception if
13550 private void enforceSystemHasVrFeature() {
13551 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13552 throw new UnsupportedOperationException("VR mode not supported on this device!");
13557 public void setRenderThread(int tid) {
13558 synchronized (this) {
13559 ProcessRecord proc;
13560 int pid = Binder.getCallingPid();
13561 if (pid == Process.myPid()) {
13562 demoteSystemServerRenderThread(tid);
13565 synchronized (mPidsSelfLocked) {
13566 proc = mPidsSelfLocked.get(pid);
13567 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13568 // ensure the tid belongs to the process
13569 if (!isThreadInProcess(pid, tid)) {
13570 throw new IllegalArgumentException(
13571 "Render thread does not belong to process");
13573 proc.renderThreadTid = tid;
13574 if (DEBUG_OOM_ADJ) {
13575 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13577 // promote to FIFO now
13578 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13579 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13580 if (mUseFifoUiScheduling) {
13581 setThreadScheduler(proc.renderThreadTid,
13582 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13584 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13588 if (DEBUG_OOM_ADJ) {
13589 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13590 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13591 mUseFifoUiScheduling);
13599 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13600 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13602 * @param tid the tid of the RenderThread
13604 private void demoteSystemServerRenderThread(int tid) {
13605 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13609 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13610 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13611 throw new UnsupportedOperationException("VR mode not supported on this device!");
13614 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13617 synchronized (this) {
13618 r = ActivityRecord.isInStackLocked(token);
13622 throw new IllegalArgumentException();
13626 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13627 VrManagerInternal.NO_ERROR) {
13631 synchronized(this) {
13632 r.requestedVrComponent = (enabled) ? packageName : null;
13634 // Update associated state if this activity is currently focused
13635 if (r == mStackSupervisor.getResumedActivityLocked()) {
13636 applyUpdateVrModeLocked(r);
13643 public boolean isVrModePackageEnabled(ComponentName packageName) {
13644 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13645 throw new UnsupportedOperationException("VR mode not supported on this device!");
13648 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13650 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13651 VrManagerInternal.NO_ERROR;
13654 public boolean isTopActivityImmersive() {
13655 enforceNotIsolatedCaller("startActivity");
13656 synchronized (this) {
13657 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13658 return (r != null) ? r.immersive : false;
13663 * @return whether the system should disable UI modes incompatible with VR mode.
13665 boolean shouldDisableNonVrUiLocked() {
13666 return mVrController.shouldDisableNonVrUiLocked();
13670 public boolean isTopOfTask(IBinder token) {
13671 synchronized (this) {
13672 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13674 throw new IllegalArgumentException();
13676 return r.getTask().getTopActivity() == r;
13681 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13682 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13683 String msg = "Permission Denial: setHasTopUi() from pid="
13684 + Binder.getCallingPid()
13685 + ", uid=" + Binder.getCallingUid()
13686 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13688 throw new SecurityException(msg);
13690 final int pid = Binder.getCallingPid();
13691 final long origId = Binder.clearCallingIdentity();
13693 synchronized (this) {
13694 boolean changed = false;
13696 synchronized (mPidsSelfLocked) {
13697 pr = mPidsSelfLocked.get(pid);
13699 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13702 if (pr.hasTopUi != hasTopUi) {
13703 if (DEBUG_OOM_ADJ) {
13704 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13706 pr.hasTopUi = hasTopUi;
13711 updateOomAdjLocked(pr, true);
13715 Binder.restoreCallingIdentity(origId);
13719 public final void enterSafeMode() {
13720 synchronized(this) {
13721 // It only makes sense to do this before the system is ready
13722 // and started launching other packages.
13723 if (!mSystemReady) {
13725 AppGlobals.getPackageManager().enterSafeMode();
13726 } catch (RemoteException e) {
13734 public final void showSafeModeOverlay() {
13735 View v = LayoutInflater.from(mContext).inflate(
13736 com.android.internal.R.layout.safe_mode, null);
13737 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13738 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13739 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13740 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13741 lp.gravity = Gravity.BOTTOM | Gravity.START;
13742 lp.format = v.getBackground().getOpacity();
13743 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13744 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13745 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13746 ((WindowManager)mContext.getSystemService(
13747 Context.WINDOW_SERVICE)).addView(v, lp);
13750 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13751 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13754 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13755 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13756 synchronized (stats) {
13757 if (mBatteryStatsService.isOnBattery()) {
13758 mBatteryStatsService.enforceCallingPermission();
13759 int MY_UID = Binder.getCallingUid();
13761 if (sender == null) {
13764 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13766 BatteryStatsImpl.Uid.Pkg pkg =
13767 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13768 sourcePkg != null ? sourcePkg : rec.key.packageName);
13769 pkg.noteWakeupAlarmLocked(tag);
13774 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13775 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13778 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13779 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13780 synchronized (stats) {
13781 mBatteryStatsService.enforceCallingPermission();
13782 int MY_UID = Binder.getCallingUid();
13784 if (sender == null) {
13787 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13789 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13793 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13794 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13797 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13798 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13799 synchronized (stats) {
13800 mBatteryStatsService.enforceCallingPermission();
13801 int MY_UID = Binder.getCallingUid();
13803 if (sender == null) {
13806 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13808 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13812 public boolean killPids(int[] pids, String pReason, boolean secure) {
13813 if (Binder.getCallingUid() != SYSTEM_UID) {
13814 throw new SecurityException("killPids only available to the system");
13816 String reason = (pReason == null) ? "Unknown" : pReason;
13817 // XXX Note: don't acquire main activity lock here, because the window
13818 // manager calls in with its locks held.
13820 boolean killed = false;
13821 synchronized (mPidsSelfLocked) {
13823 for (int i=0; i<pids.length; i++) {
13824 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13825 if (proc != null) {
13826 int type = proc.setAdj;
13827 if (type > worstType) {
13833 // If the worst oom_adj is somewhere in the cached proc LRU range,
13834 // then constrain it so we will kill all cached procs.
13835 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13836 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13837 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13840 // If this is not a secure call, don't let it kill processes that
13842 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13843 worstType = ProcessList.SERVICE_ADJ;
13846 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13847 for (int i=0; i<pids.length; i++) {
13848 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13849 if (proc == null) {
13852 int adj = proc.setAdj;
13853 if (adj >= worstType && !proc.killedByAm) {
13854 proc.kill(reason, true);
13863 public void killUid(int appId, int userId, String reason) {
13864 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13865 synchronized (this) {
13866 final long identity = Binder.clearCallingIdentity();
13868 killPackageProcessesLocked(null, appId, userId,
13869 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13870 reason != null ? reason : "kill uid");
13872 Binder.restoreCallingIdentity(identity);
13878 public boolean killProcessesBelowForeground(String reason) {
13879 if (Binder.getCallingUid() != SYSTEM_UID) {
13880 throw new SecurityException("killProcessesBelowForeground() only available to system");
13883 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13886 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13887 if (Binder.getCallingUid() != SYSTEM_UID) {
13888 throw new SecurityException("killProcessesBelowAdj() only available to system");
13891 boolean killed = false;
13892 synchronized (mPidsSelfLocked) {
13893 final int size = mPidsSelfLocked.size();
13894 for (int i = 0; i < size; i++) {
13895 final int pid = mPidsSelfLocked.keyAt(i);
13896 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13897 if (proc == null) continue;
13899 final int adj = proc.setAdj;
13900 if (adj > belowAdj && !proc.killedByAm) {
13901 proc.kill(reason, true);
13910 public void hang(final IBinder who, boolean allowRestart) {
13911 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13912 != PackageManager.PERMISSION_GRANTED) {
13913 throw new SecurityException("Requires permission "
13914 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13917 final IBinder.DeathRecipient death = new DeathRecipient() {
13919 public void binderDied() {
13920 synchronized (this) {
13927 who.linkToDeath(death, 0);
13928 } catch (RemoteException e) {
13929 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13933 synchronized (this) {
13934 Watchdog.getInstance().setAllowRestart(allowRestart);
13935 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13936 synchronized (death) {
13937 while (who.isBinderAlive()) {
13940 } catch (InterruptedException e) {
13944 Watchdog.getInstance().setAllowRestart(true);
13949 public void restart() {
13950 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13951 != PackageManager.PERMISSION_GRANTED) {
13952 throw new SecurityException("Requires permission "
13953 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13956 Log.i(TAG, "Sending shutdown broadcast...");
13958 BroadcastReceiver br = new BroadcastReceiver() {
13959 @Override public void onReceive(Context context, Intent intent) {
13960 // Now the broadcast is done, finish up the low-level shutdown.
13961 Log.i(TAG, "Shutting down activity manager...");
13963 Log.i(TAG, "Shutdown complete, restarting!");
13964 killProcess(myPid());
13969 // First send the high-level shut down broadcast.
13970 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13971 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13972 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13973 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13974 mContext.sendOrderedBroadcastAsUser(intent,
13975 UserHandle.ALL, null, br, mHandler, 0, null, null);
13977 br.onReceive(mContext, intent);
13980 private long getLowRamTimeSinceIdle(long now) {
13981 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13985 public void performIdleMaintenance() {
13986 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13987 != PackageManager.PERMISSION_GRANTED) {
13988 throw new SecurityException("Requires permission "
13989 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13992 synchronized (this) {
13993 final long now = SystemClock.uptimeMillis();
13994 final long timeSinceLastIdle = now - mLastIdleTime;
13995 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13996 mLastIdleTime = now;
13997 mLowRamTimeSinceLastIdle = 0;
13998 if (mLowRamStartTime != 0) {
13999 mLowRamStartTime = now;
14002 StringBuilder sb = new StringBuilder(128);
14003 sb.append("Idle maintenance over ");
14004 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14005 sb.append(" low RAM for ");
14006 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14007 Slog.i(TAG, sb.toString());
14009 // If at least 1/3 of our time since the last idle period has been spent
14010 // with RAM low, then we want to kill processes.
14011 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14013 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14014 ProcessRecord proc = mLruProcesses.get(i);
14015 if (proc.notCachedSinceIdle) {
14016 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14017 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14018 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14019 if (doKilling && proc.initialIdlePss != 0
14020 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14021 sb = new StringBuilder(128);
14023 sb.append(proc.processName);
14024 sb.append(" in idle maint: pss=");
14025 sb.append(proc.lastPss);
14026 sb.append(", swapPss=");
14027 sb.append(proc.lastSwapPss);
14028 sb.append(", initialPss=");
14029 sb.append(proc.initialIdlePss);
14030 sb.append(", period=");
14031 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14032 sb.append(", lowRamPeriod=");
14033 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14034 Slog.wtfQuiet(TAG, sb.toString());
14035 proc.kill("idle maint (pss " + proc.lastPss
14036 + " from " + proc.initialIdlePss + ")", true);
14039 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14040 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14041 proc.notCachedSinceIdle = true;
14042 proc.initialIdlePss = 0;
14043 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14044 mTestPssMode, isSleepingLocked(), now);
14048 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14049 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14054 public void sendIdleJobTrigger() {
14055 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14056 != PackageManager.PERMISSION_GRANTED) {
14057 throw new SecurityException("Requires permission "
14058 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14061 final long ident = Binder.clearCallingIdentity();
14063 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14064 .setPackage("android")
14065 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14066 broadcastIntent(null, intent, null, null, 0, null, null, null,
14067 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14069 Binder.restoreCallingIdentity(ident);
14073 private void retrieveSettings() {
14074 final ContentResolver resolver = mContext.getContentResolver();
14075 final boolean freeformWindowManagement =
14076 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14077 || Settings.Global.getInt(
14078 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14080 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14081 final boolean supportsPictureInPicture = supportsMultiWindow &&
14082 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14083 final boolean supportsSplitScreenMultiWindow =
14084 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14085 final boolean supportsMultiDisplay = mContext.getPackageManager()
14086 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14087 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14088 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14089 final boolean alwaysFinishActivities =
14090 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14091 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14092 final boolean forceResizable = Settings.Global.getInt(
14093 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14094 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14095 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14096 final boolean supportsLeanbackOnly =
14097 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14099 // Transfer any global setting for forcing RTL layout, into a System Property
14100 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14102 final Configuration configuration = new Configuration();
14103 Settings.System.getConfiguration(resolver, configuration);
14105 // This will take care of setting the correct layout direction flags
14106 configuration.setLayoutDirection(configuration.locale);
14109 synchronized (this) {
14110 mDebugApp = mOrigDebugApp = debugApp;
14111 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14112 mAlwaysFinishActivities = alwaysFinishActivities;
14113 mSupportsLeanbackOnly = supportsLeanbackOnly;
14114 mForceResizableActivities = forceResizable;
14115 final boolean multiWindowFormEnabled = freeformWindowManagement
14116 || supportsSplitScreenMultiWindow
14117 || supportsPictureInPicture
14118 || supportsMultiDisplay;
14119 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14120 mSupportsMultiWindow = true;
14121 mSupportsFreeformWindowManagement = freeformWindowManagement;
14122 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14123 mSupportsPictureInPicture = supportsPictureInPicture;
14124 mSupportsMultiDisplay = supportsMultiDisplay;
14126 mSupportsMultiWindow = false;
14127 mSupportsFreeformWindowManagement = false;
14128 mSupportsSplitScreenMultiWindow = false;
14129 mSupportsPictureInPicture = false;
14130 mSupportsMultiDisplay = false;
14132 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14133 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14134 // This happens before any activities are started, so we can change global configuration
14136 updateConfigurationLocked(configuration, null, true);
14137 final Configuration globalConfig = getGlobalConfiguration();
14138 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14140 // Load resources only after the current configuration has been set.
14141 final Resources res = mContext.getResources();
14142 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14143 mThumbnailWidth = res.getDimensionPixelSize(
14144 com.android.internal.R.dimen.thumbnail_width);
14145 mThumbnailHeight = res.getDimensionPixelSize(
14146 com.android.internal.R.dimen.thumbnail_height);
14147 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14148 com.android.internal.R.string.config_appsNotReportingCrashes));
14149 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14150 com.android.internal.R.bool.config_customUserSwitchUi);
14151 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14152 mFullscreenThumbnailScale = (float) res
14153 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14154 (float) globalConfig.screenWidthDp;
14156 mFullscreenThumbnailScale = res.getFraction(
14157 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14159 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14163 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14164 traceLog.traceBegin("PhaseActivityManagerReady");
14165 synchronized(this) {
14166 if (mSystemReady) {
14167 // If we're done calling all the receivers, run the next "boot phase" passed in
14168 // by the SystemServer
14169 if (goingCallback != null) {
14170 goingCallback.run();
14175 mLocalDeviceIdleController
14176 = LocalServices.getService(DeviceIdleController.LocalService.class);
14177 mAssistUtils = new AssistUtils(mContext);
14178 mVrController.onSystemReady();
14179 // Make sure we have the current profile info, since it is needed for security checks.
14180 mUserController.onSystemReady();
14181 mRecentTasks.onSystemReadyLocked();
14182 mAppOpsService.systemReady();
14183 mSystemReady = true;
14187 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14188 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14190 } catch (RemoteException e) {}
14192 ArrayList<ProcessRecord> procsToKill = null;
14193 synchronized(mPidsSelfLocked) {
14194 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14195 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14196 if (!isAllowedWhileBooting(proc.info)){
14197 if (procsToKill == null) {
14198 procsToKill = new ArrayList<ProcessRecord>();
14200 procsToKill.add(proc);
14205 synchronized(this) {
14206 if (procsToKill != null) {
14207 for (int i=procsToKill.size()-1; i>=0; i--) {
14208 ProcessRecord proc = procsToKill.get(i);
14209 Slog.i(TAG, "Removing system update proc: " + proc);
14210 removeProcessLocked(proc, true, false, "system update done");
14214 // Now that we have cleaned up any update processes, we
14215 // are ready to start launching real processes and know that
14216 // we won't trample on them any more.
14217 mProcessesReady = true;
14220 Slog.i(TAG, "System now ready");
14221 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14222 SystemClock.uptimeMillis());
14224 synchronized(this) {
14225 // Make sure we have no pre-ready processes sitting around.
14227 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14228 ResolveInfo ri = mContext.getPackageManager()
14229 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14231 CharSequence errorMsg = null;
14233 ActivityInfo ai = ri.activityInfo;
14234 ApplicationInfo app = ai.applicationInfo;
14235 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14236 mTopAction = Intent.ACTION_FACTORY_TEST;
14238 mTopComponent = new ComponentName(app.packageName,
14241 errorMsg = mContext.getResources().getText(
14242 com.android.internal.R.string.factorytest_not_system);
14245 errorMsg = mContext.getResources().getText(
14246 com.android.internal.R.string.factorytest_no_action);
14248 if (errorMsg != null) {
14251 mTopComponent = null;
14252 Message msg = Message.obtain();
14253 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14254 msg.getData().putCharSequence("msg", errorMsg);
14255 mUiHandler.sendMessage(msg);
14260 retrieveSettings();
14261 final int currentUserId;
14262 synchronized (this) {
14263 currentUserId = mUserController.getCurrentUserIdLocked();
14264 readGrantedUriPermissionsLocked();
14267 if (goingCallback != null) goingCallback.run();
14268 traceLog.traceBegin("ActivityManagerStartApps");
14269 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14270 Integer.toString(currentUserId), currentUserId);
14271 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14272 Integer.toString(currentUserId), currentUserId);
14273 mSystemServiceManager.startUser(currentUserId);
14275 synchronized (this) {
14276 // Only start up encryption-aware persistent apps; once user is
14277 // unlocked we'll come back around and start unaware apps
14278 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14280 // Start up initial activity.
14282 // Enable home activity for system user, so that the system can always boot. We don't
14283 // do this when the system user is not setup since the setup wizard should be the one
14284 // to handle home activity in this case.
14285 if (UserManager.isSplitSystemUser() &&
14286 Settings.Secure.getInt(mContext.getContentResolver(),
14287 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14288 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14290 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14291 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14292 UserHandle.USER_SYSTEM);
14293 } catch (RemoteException e) {
14294 throw e.rethrowAsRuntimeException();
14297 startHomeActivityLocked(currentUserId, "systemReady");
14300 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14301 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14302 + " data partition or your device will be unstable.");
14303 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14305 } catch (RemoteException e) {
14308 if (!Build.isBuildConsistent()) {
14309 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14310 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14313 long ident = Binder.clearCallingIdentity();
14315 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14316 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14317 | Intent.FLAG_RECEIVER_FOREGROUND);
14318 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14319 broadcastIntentLocked(null, null, intent,
14320 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14321 null, false, false, MY_PID, SYSTEM_UID,
14323 intent = new Intent(Intent.ACTION_USER_STARTING);
14324 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14325 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14326 broadcastIntentLocked(null, null, intent,
14327 null, new IIntentReceiver.Stub() {
14329 public void performReceive(Intent intent, int resultCode, String data,
14330 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14331 throws RemoteException {
14334 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14335 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14336 } catch (Throwable t) {
14337 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14339 Binder.restoreCallingIdentity(ident);
14341 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14342 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14343 traceLog.traceEnd(); // ActivityManagerStartApps
14344 traceLog.traceEnd(); // PhaseActivityManagerReady
14348 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14349 synchronized (this) {
14350 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14354 void skipCurrentReceiverLocked(ProcessRecord app) {
14355 for (BroadcastQueue queue : mBroadcastQueues) {
14356 queue.skipCurrentReceiverLocked(app);
14361 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14362 * The application process will exit immediately after this call returns.
14363 * @param app object of the crashing app, null for the system server
14364 * @param crashInfo describing the exception
14366 public void handleApplicationCrash(IBinder app,
14367 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14368 ProcessRecord r = findAppProcess(app, "Crash");
14369 final String processName = app == null ? "system_server"
14370 : (r == null ? "unknown" : r.processName);
14372 handleApplicationCrashInner("crash", r, processName, crashInfo);
14375 /* Native crash reporting uses this inner version because it needs to be somewhat
14376 * decoupled from the AM-managed cleanup lifecycle
14378 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14379 ApplicationErrorReport.CrashInfo crashInfo) {
14380 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14381 UserHandle.getUserId(Binder.getCallingUid()), processName,
14382 r == null ? -1 : r.info.flags,
14383 crashInfo.exceptionClassName,
14384 crashInfo.exceptionMessage,
14385 crashInfo.throwFileName,
14386 crashInfo.throwLineNumber);
14388 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14390 mAppErrors.crashApplication(r, crashInfo);
14393 public void handleApplicationStrictModeViolation(
14396 StrictMode.ViolationInfo info) {
14397 ProcessRecord r = findAppProcess(app, "StrictMode");
14402 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14403 Integer stackFingerprint = info.hashCode();
14404 boolean logIt = true;
14405 synchronized (mAlreadyLoggedViolatedStacks) {
14406 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14408 // TODO: sub-sample into EventLog for these, with
14409 // the info.durationMillis? Then we'd get
14410 // the relative pain numbers, without logging all
14411 // the stack traces repeatedly. We'd want to do
14412 // likewise in the client code, which also does
14413 // dup suppression, before the Binder call.
14415 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14416 mAlreadyLoggedViolatedStacks.clear();
14418 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14422 logStrictModeViolationToDropBox(r, info);
14426 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14427 AppErrorResult result = new AppErrorResult();
14428 synchronized (this) {
14429 final long origId = Binder.clearCallingIdentity();
14431 Message msg = Message.obtain();
14432 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14433 HashMap<String, Object> data = new HashMap<String, Object>();
14434 data.put("result", result);
14435 data.put("app", r);
14436 data.put("violationMask", violationMask);
14437 data.put("info", info);
14439 mUiHandler.sendMessage(msg);
14441 Binder.restoreCallingIdentity(origId);
14443 int res = result.get();
14444 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14448 // Depending on the policy in effect, there could be a bunch of
14449 // these in quick succession so we try to batch these together to
14450 // minimize disk writes, number of dropbox entries, and maximize
14451 // compression, by having more fewer, larger records.
14452 private void logStrictModeViolationToDropBox(
14453 ProcessRecord process,
14454 StrictMode.ViolationInfo info) {
14455 if (info == null) {
14458 final boolean isSystemApp = process == null ||
14459 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14460 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14461 final String processName = process == null ? "unknown" : process.processName;
14462 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14463 final DropBoxManager dbox = (DropBoxManager)
14464 mContext.getSystemService(Context.DROPBOX_SERVICE);
14466 // Exit early if the dropbox isn't configured to accept this report type.
14467 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14469 boolean bufferWasEmpty;
14470 boolean needsFlush;
14471 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14472 synchronized (sb) {
14473 bufferWasEmpty = sb.length() == 0;
14474 appendDropBoxProcessHeaders(process, processName, sb);
14475 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14476 sb.append("System-App: ").append(isSystemApp).append("\n");
14477 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14478 if (info.violationNumThisLoop != 0) {
14479 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14481 if (info.numAnimationsRunning != 0) {
14482 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14484 if (info.broadcastIntentAction != null) {
14485 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14487 if (info.durationMillis != -1) {
14488 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14490 if (info.numInstances != -1) {
14491 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14493 if (info.tags != null) {
14494 for (String tag : info.tags) {
14495 sb.append("Span-Tag: ").append(tag).append("\n");
14499 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14500 sb.append(info.crashInfo.stackTrace);
14503 if (info.message != null) {
14504 sb.append(info.message);
14508 // Only buffer up to ~64k. Various logging bits truncate
14510 needsFlush = (sb.length() > 64 * 1024);
14513 // Flush immediately if the buffer's grown too large, or this
14514 // is a non-system app. Non-system apps are isolated with a
14515 // different tag & policy and not batched.
14517 // Batching is useful during internal testing with
14518 // StrictMode settings turned up high. Without batching,
14519 // thousands of separate files could be created on boot.
14520 if (!isSystemApp || needsFlush) {
14521 new Thread("Error dump: " + dropboxTag) {
14523 public void run() {
14525 synchronized (sb) {
14526 report = sb.toString();
14527 sb.delete(0, sb.length());
14530 if (report.length() != 0) {
14531 dbox.addText(dropboxTag, report);
14538 // System app batching:
14539 if (!bufferWasEmpty) {
14540 // An existing dropbox-writing thread is outstanding, so
14541 // we don't need to start it up. The existing thread will
14542 // catch the buffer appends we just did.
14546 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14547 // (After this point, we shouldn't access AMS internal data structures.)
14548 new Thread("Error dump: " + dropboxTag) {
14550 public void run() {
14551 // 5 second sleep to let stacks arrive and be batched together
14553 Thread.sleep(5000); // 5 seconds
14554 } catch (InterruptedException e) {}
14556 String errorReport;
14557 synchronized (mStrictModeBuffer) {
14558 errorReport = mStrictModeBuffer.toString();
14559 if (errorReport.length() == 0) {
14562 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14563 mStrictModeBuffer.trimToSize();
14565 dbox.addText(dropboxTag, errorReport);
14571 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14572 * @param app object of the crashing app, null for the system server
14573 * @param tag reported by the caller
14574 * @param system whether this wtf is coming from the system
14575 * @param crashInfo describing the context of the error
14576 * @return true if the process should exit immediately (WTF is fatal)
14578 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14579 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14580 final int callingUid = Binder.getCallingUid();
14581 final int callingPid = Binder.getCallingPid();
14584 // If this is coming from the system, we could very well have low-level
14585 // system locks held, so we want to do this all asynchronously. And we
14586 // never want this to become fatal, so there is that too.
14587 mHandler.post(new Runnable() {
14588 @Override public void run() {
14589 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14595 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14598 final boolean isFatal = Build.IS_ENG || Settings.Global
14599 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14600 final boolean isSystem = (r == null) || r.persistent;
14602 if (isFatal && !isSystem) {
14603 mAppErrors.crashApplication(r, crashInfo);
14610 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14611 final ApplicationErrorReport.CrashInfo crashInfo) {
14612 final ProcessRecord r = findAppProcess(app, "WTF");
14613 final String processName = app == null ? "system_server"
14614 : (r == null ? "unknown" : r.processName);
14616 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14617 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14619 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14625 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14626 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14628 private ProcessRecord findAppProcess(IBinder app, String reason) {
14633 synchronized (this) {
14634 final int NP = mProcessNames.getMap().size();
14635 for (int ip=0; ip<NP; ip++) {
14636 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14637 final int NA = apps.size();
14638 for (int ia=0; ia<NA; ia++) {
14639 ProcessRecord p = apps.valueAt(ia);
14640 if (p.thread != null && p.thread.asBinder() == app) {
14646 Slog.w(TAG, "Can't find mystery application for " + reason
14647 + " from pid=" + Binder.getCallingPid()
14648 + " uid=" + Binder.getCallingUid() + ": " + app);
14654 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14655 * to append various headers to the dropbox log text.
14657 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14658 StringBuilder sb) {
14659 // Watchdog thread ends up invoking this function (with
14660 // a null ProcessRecord) to add the stack file to dropbox.
14661 // Do not acquire a lock on this (am) in such cases, as it
14662 // could cause a potential deadlock, if and when watchdog
14663 // is invoked due to unavailability of lock on am and it
14664 // would prevent watchdog from killing system_server.
14665 if (process == null) {
14666 sb.append("Process: ").append(processName).append("\n");
14669 // Note: ProcessRecord 'process' is guarded by the service
14670 // instance. (notably process.pkgList, which could otherwise change
14671 // concurrently during execution of this method)
14672 synchronized (this) {
14673 sb.append("Process: ").append(processName).append("\n");
14674 sb.append("PID: ").append(process.pid).append("\n");
14675 int flags = process.info.flags;
14676 IPackageManager pm = AppGlobals.getPackageManager();
14677 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14678 for (int ip=0; ip<process.pkgList.size(); ip++) {
14679 String pkg = process.pkgList.keyAt(ip);
14680 sb.append("Package: ").append(pkg);
14682 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14684 sb.append(" v").append(pi.versionCode);
14685 if (pi.versionName != null) {
14686 sb.append(" (").append(pi.versionName).append(")");
14689 } catch (RemoteException e) {
14690 Slog.e(TAG, "Error getting package info: " + pkg, e);
14694 if (process.info.isInstantApp()) {
14695 sb.append("Instant-App: true\n");
14700 private static String processClass(ProcessRecord process) {
14701 if (process == null || process.pid == MY_PID) {
14702 return "system_server";
14703 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14704 return "system_app";
14710 private volatile long mWtfClusterStart;
14711 private volatile int mWtfClusterCount;
14714 * Write a description of an error (crash, WTF, ANR) to the drop box.
14715 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14716 * @param process which caused the error, null means the system server
14717 * @param activity which triggered the error, null if unknown
14718 * @param parent activity related to the error, null if unknown
14719 * @param subject line related to the error, null if absent
14720 * @param report in long form describing the error, null if absent
14721 * @param dataFile text file to include in the report, null if none
14722 * @param crashInfo giving an application stack trace, null if absent
14724 public void addErrorToDropBox(String eventType,
14725 ProcessRecord process, String processName, ActivityRecord activity,
14726 ActivityRecord parent, String subject,
14727 final String report, final File dataFile,
14728 final ApplicationErrorReport.CrashInfo crashInfo) {
14729 // NOTE -- this must never acquire the ActivityManagerService lock,
14730 // otherwise the watchdog may be prevented from resetting the system.
14732 // Bail early if not published yet
14733 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14734 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14736 // Exit early if the dropbox isn't configured to accept this report type.
14737 final String dropboxTag = processClass(process) + "_" + eventType;
14738 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14740 // Rate-limit how often we're willing to do the heavy lifting below to
14741 // collect and record logs; currently 5 logs per 10 second period.
14742 final long now = SystemClock.elapsedRealtime();
14743 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14744 mWtfClusterStart = now;
14745 mWtfClusterCount = 1;
14747 if (mWtfClusterCount++ >= 5) return;
14750 final StringBuilder sb = new StringBuilder(1024);
14751 appendDropBoxProcessHeaders(process, processName, sb);
14752 if (process != null) {
14753 sb.append("Foreground: ")
14754 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14757 if (activity != null) {
14758 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14760 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14761 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14763 if (parent != null && parent != activity) {
14764 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14766 if (subject != null) {
14767 sb.append("Subject: ").append(subject).append("\n");
14769 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14770 if (Debug.isDebuggerConnected()) {
14771 sb.append("Debugger: Connected\n");
14775 // Do the rest in a worker thread to avoid blocking the caller on I/O
14776 // (After this point, we shouldn't access AMS internal data structures.)
14777 Thread worker = new Thread("Error dump: " + dropboxTag) {
14779 public void run() {
14780 if (report != null) {
14784 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14785 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14786 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14787 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14789 if (dataFile != null && maxDataFileSize > 0) {
14791 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14792 "\n\n[[TRUNCATED]]"));
14793 } catch (IOException e) {
14794 Slog.e(TAG, "Error reading " + dataFile, e);
14797 if (crashInfo != null && crashInfo.stackTrace != null) {
14798 sb.append(crashInfo.stackTrace);
14804 // Merge several logcat streams, and take the last N lines
14805 InputStreamReader input = null;
14807 java.lang.Process logcat = new ProcessBuilder(
14808 "/system/bin/timeout", "-k", "15s", "10s",
14809 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14810 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14811 .redirectErrorStream(true).start();
14813 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14814 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14815 input = new InputStreamReader(logcat.getInputStream());
14818 char[] buf = new char[8192];
14819 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14820 } catch (IOException e) {
14821 Slog.e(TAG, "Error running logcat", e);
14823 if (input != null) try { input.close(); } catch (IOException e) {}
14827 dbox.addText(dropboxTag, sb.toString());
14831 if (process == null) {
14832 // If process is null, we are being called from some internal code
14833 // and may be about to die -- run this synchronously.
14841 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14842 enforceNotIsolatedCaller("getProcessesInErrorState");
14843 // assume our apps are happy - lazy create the list
14844 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14846 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14847 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14848 int userId = UserHandle.getUserId(Binder.getCallingUid());
14850 synchronized (this) {
14852 // iterate across all processes
14853 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14854 ProcessRecord app = mLruProcesses.get(i);
14855 if (!allUsers && app.userId != userId) {
14858 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14859 // This one's in trouble, so we'll generate a report for it
14860 // crashes are higher priority (in case there's a crash *and* an anr)
14861 ActivityManager.ProcessErrorStateInfo report = null;
14862 if (app.crashing) {
14863 report = app.crashingReport;
14864 } else if (app.notResponding) {
14865 report = app.notRespondingReport;
14868 if (report != null) {
14869 if (errList == null) {
14870 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14872 errList.add(report);
14874 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14875 " crashing = " + app.crashing +
14876 " notResponding = " + app.notResponding);
14885 static int procStateToImportance(int procState, int memAdj,
14886 ActivityManager.RunningAppProcessInfo currApp,
14887 int clientTargetSdk) {
14888 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14889 procState, clientTargetSdk);
14890 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14891 currApp.lru = memAdj;
14898 private void fillInProcMemInfo(ProcessRecord app,
14899 ActivityManager.RunningAppProcessInfo outInfo,
14900 int clientTargetSdk) {
14901 outInfo.pid = app.pid;
14902 outInfo.uid = app.info.uid;
14903 if (mHeavyWeightProcess == app) {
14904 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14906 if (app.persistent) {
14907 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14909 if (app.activities.size() > 0) {
14910 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14912 outInfo.lastTrimLevel = app.trimMemoryLevel;
14913 int adj = app.curAdj;
14914 int procState = app.curProcState;
14915 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14916 outInfo.importanceReasonCode = app.adjTypeCode;
14917 outInfo.processState = app.curProcState;
14921 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14922 enforceNotIsolatedCaller("getRunningAppProcesses");
14924 final int callingUid = Binder.getCallingUid();
14925 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14927 // Lazy instantiation of list
14928 List<ActivityManager.RunningAppProcessInfo> runList = null;
14929 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14930 callingUid) == PackageManager.PERMISSION_GRANTED;
14931 final int userId = UserHandle.getUserId(callingUid);
14932 final boolean allUids = isGetTasksAllowed(
14933 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14935 synchronized (this) {
14936 // Iterate across all processes
14937 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14938 ProcessRecord app = mLruProcesses.get(i);
14939 if ((!allUsers && app.userId != userId)
14940 || (!allUids && app.uid != callingUid)) {
14943 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14944 // Generate process state info for running application
14945 ActivityManager.RunningAppProcessInfo currApp =
14946 new ActivityManager.RunningAppProcessInfo(app.processName,
14947 app.pid, app.getPackageList());
14948 fillInProcMemInfo(app, currApp, clientTargetSdk);
14949 if (app.adjSource instanceof ProcessRecord) {
14950 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14951 currApp.importanceReasonImportance =
14952 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14953 app.adjSourceProcState);
14954 } else if (app.adjSource instanceof ActivityRecord) {
14955 ActivityRecord r = (ActivityRecord)app.adjSource;
14956 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14958 if (app.adjTarget instanceof ComponentName) {
14959 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14961 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14962 // + " lru=" + currApp.lru);
14963 if (runList == null) {
14964 runList = new ArrayList<>();
14966 runList.add(currApp);
14974 public List<ApplicationInfo> getRunningExternalApplications() {
14975 enforceNotIsolatedCaller("getRunningExternalApplications");
14976 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14977 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14978 if (runningApps != null && runningApps.size() > 0) {
14979 Set<String> extList = new HashSet<String>();
14980 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14981 if (app.pkgList != null) {
14982 for (String pkg : app.pkgList) {
14987 IPackageManager pm = AppGlobals.getPackageManager();
14988 for (String pkg : extList) {
14990 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14991 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14994 } catch (RemoteException e) {
15002 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15003 enforceNotIsolatedCaller("getMyMemoryState");
15005 final int callingUid = Binder.getCallingUid();
15006 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15008 synchronized (this) {
15009 ProcessRecord proc;
15010 synchronized (mPidsSelfLocked) {
15011 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15013 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15018 public int getMemoryTrimLevel() {
15019 enforceNotIsolatedCaller("getMyMemoryState");
15020 synchronized (this) {
15021 return mLastMemoryLevel;
15026 public void onShellCommand(FileDescriptor in, FileDescriptor out,
15027 FileDescriptor err, String[] args, ShellCallback callback,
15028 ResultReceiver resultReceiver) {
15029 (new ActivityManagerShellCommand(this, false)).exec(
15030 this, in, out, err, args, callback, resultReceiver);
15033 SleepToken acquireSleepToken(String tag, int displayId) {
15034 synchronized (this) {
15035 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15036 updateSleepIfNeededLocked();
15042 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15043 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15045 boolean dumpAll = false;
15046 boolean dumpClient = false;
15047 boolean dumpCheckin = false;
15048 boolean dumpCheckinFormat = false;
15049 boolean dumpVisibleStacksOnly = false;
15050 boolean dumpFocusedStackOnly = false;
15051 String dumpPackage = null;
15054 while (opti < args.length) {
15055 String opt = args[opti];
15056 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15060 if ("-a".equals(opt)) {
15062 } else if ("-c".equals(opt)) {
15064 } else if ("-v".equals(opt)) {
15065 dumpVisibleStacksOnly = true;
15066 } else if ("-f".equals(opt)) {
15067 dumpFocusedStackOnly = true;
15068 } else if ("-p".equals(opt)) {
15069 if (opti < args.length) {
15070 dumpPackage = args[opti];
15073 pw.println("Error: -p option requires package argument");
15077 } else if ("--checkin".equals(opt)) {
15078 dumpCheckin = dumpCheckinFormat = true;
15079 } else if ("-C".equals(opt)) {
15080 dumpCheckinFormat = true;
15081 } else if ("-h".equals(opt)) {
15082 ActivityManagerShellCommand.dumpHelp(pw, true);
15085 pw.println("Unknown argument: " + opt + "; use -h for help");
15089 long origId = Binder.clearCallingIdentity();
15090 boolean more = false;
15091 // Is the caller requesting to dump a particular piece of data?
15092 if (opti < args.length) {
15093 String cmd = args[opti];
15095 if ("activities".equals(cmd) || "a".equals(cmd)) {
15096 synchronized (this) {
15097 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15099 } else if ("lastanr".equals(cmd)) {
15100 synchronized (this) {
15101 dumpLastANRLocked(pw);
15103 } else if ("starter".equals(cmd)) {
15104 synchronized (this) {
15105 dumpActivityStarterLocked(pw, dumpPackage);
15107 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15108 synchronized (this) {
15109 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15111 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15114 if (opti >= args.length) {
15116 newArgs = EMPTY_STRING_ARRAY;
15118 dumpPackage = args[opti];
15120 newArgs = new String[args.length - opti];
15121 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15122 args.length - opti);
15124 synchronized (this) {
15125 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15127 } else if ("broadcast-stats".equals(cmd)) {
15130 if (opti >= args.length) {
15132 newArgs = EMPTY_STRING_ARRAY;
15134 dumpPackage = args[opti];
15136 newArgs = new String[args.length - opti];
15137 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15138 args.length - opti);
15140 synchronized (this) {
15141 if (dumpCheckinFormat) {
15142 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15145 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15148 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15151 if (opti >= args.length) {
15153 newArgs = EMPTY_STRING_ARRAY;
15155 dumpPackage = args[opti];
15157 newArgs = new String[args.length - opti];
15158 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15159 args.length - opti);
15161 synchronized (this) {
15162 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15164 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15167 if (opti >= args.length) {
15169 newArgs = EMPTY_STRING_ARRAY;
15171 dumpPackage = args[opti];
15173 newArgs = new String[args.length - opti];
15174 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15175 args.length - opti);
15177 synchronized (this) {
15178 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15180 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15181 synchronized (this) {
15182 dumpOomLocked(fd, pw, args, opti, true);
15184 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15185 synchronized (this) {
15186 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15188 } else if ("provider".equals(cmd)) {
15191 if (opti >= args.length) {
15193 newArgs = EMPTY_STRING_ARRAY;
15197 newArgs = new String[args.length - opti];
15198 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15200 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15201 pw.println("No providers match: " + name);
15202 pw.println("Use -h for help.");
15204 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15205 synchronized (this) {
15206 dumpProvidersLocked(fd, pw, args, opti, true, null);
15208 } else if ("service".equals(cmd)) {
15211 if (opti >= args.length) {
15213 newArgs = EMPTY_STRING_ARRAY;
15217 newArgs = new String[args.length - opti];
15218 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15219 args.length - opti);
15221 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15222 pw.println("No services match: " + name);
15223 pw.println("Use -h for help.");
15225 } else if ("package".equals(cmd)) {
15227 if (opti >= args.length) {
15228 pw.println("package: no package name specified");
15229 pw.println("Use -h for help.");
15231 dumpPackage = args[opti];
15233 newArgs = new String[args.length - opti];
15234 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15235 args.length - opti);
15240 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15241 synchronized (this) {
15242 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15244 } else if ("settings".equals(cmd)) {
15245 synchronized (this) {
15246 mConstants.dump(pw);
15248 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15250 ActiveServices.ServiceDumper dumper;
15251 synchronized (this) {
15252 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15255 dumper.dumpWithClient();
15257 synchronized (this) {
15258 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15259 dumpPackage).dumpLocked();
15262 } else if ("locks".equals(cmd)) {
15263 LockGuard.dump(fd, pw, args);
15265 // Dumping a single activity?
15266 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15267 dumpFocusedStackOnly)) {
15268 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15269 int res = shell.exec(this, null, fd, null, args, null,
15270 new ResultReceiver(null));
15272 pw.println("Bad activity command, or no activities match: " + cmd);
15273 pw.println("Use -h for help.");
15278 Binder.restoreCallingIdentity(origId);
15283 // No piece of data specified, dump everything.
15284 if (dumpCheckinFormat) {
15285 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15286 } else if (dumpClient) {
15287 ActiveServices.ServiceDumper sdumper;
15288 synchronized (this) {
15289 mConstants.dump(pw);
15292 pw.println("-------------------------------------------------------------------------------");
15294 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15297 pw.println("-------------------------------------------------------------------------------");
15299 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15302 pw.println("-------------------------------------------------------------------------------");
15304 if (dumpAll || dumpPackage != null) {
15305 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15308 pw.println("-------------------------------------------------------------------------------");
15311 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15314 pw.println("-------------------------------------------------------------------------------");
15316 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15319 pw.println("-------------------------------------------------------------------------------");
15321 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15324 sdumper.dumpWithClient();
15326 synchronized (this) {
15328 pw.println("-------------------------------------------------------------------------------");
15330 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15333 pw.println("-------------------------------------------------------------------------------");
15335 dumpLastANRLocked(pw);
15338 pw.println("-------------------------------------------------------------------------------");
15340 dumpActivityStarterLocked(pw, dumpPackage);
15343 pw.println("-------------------------------------------------------------------------------");
15345 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15346 if (mAssociations.size() > 0) {
15349 pw.println("-------------------------------------------------------------------------------");
15351 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15355 pw.println("-------------------------------------------------------------------------------");
15357 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15361 synchronized (this) {
15362 mConstants.dump(pw);
15365 pw.println("-------------------------------------------------------------------------------");
15367 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15370 pw.println("-------------------------------------------------------------------------------");
15372 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15375 pw.println("-------------------------------------------------------------------------------");
15377 if (dumpAll || dumpPackage != null) {
15378 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15381 pw.println("-------------------------------------------------------------------------------");
15384 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15387 pw.println("-------------------------------------------------------------------------------");
15389 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15392 pw.println("-------------------------------------------------------------------------------");
15394 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15398 pw.println("-------------------------------------------------------------------------------");
15400 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15403 pw.println("-------------------------------------------------------------------------------");
15405 dumpLastANRLocked(pw);
15408 pw.println("-------------------------------------------------------------------------------");
15410 dumpActivityStarterLocked(pw, dumpPackage);
15413 pw.println("-------------------------------------------------------------------------------");
15415 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15416 if (mAssociations.size() > 0) {
15419 pw.println("-------------------------------------------------------------------------------");
15421 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15425 pw.println("-------------------------------------------------------------------------------");
15427 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15430 Binder.restoreCallingIdentity(origId);
15433 private void dumpLastANRLocked(PrintWriter pw) {
15434 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15435 if (mLastANRState == null) {
15436 pw.println(" <no ANR has occurred since boot>");
15438 pw.println(mLastANRState);
15442 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15443 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15444 mActivityStarter.dump(pw, "", dumpPackage);
15447 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15448 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15449 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15450 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15453 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15454 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15455 pw.println(header);
15457 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15459 boolean needSep = printedAnything;
15461 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15462 mStackSupervisor.getResumedActivityLocked(),
15463 dumpPackage, needSep, " ResumedActivity: ");
15465 printedAnything = true;
15469 if (dumpPackage == null) {
15473 printedAnything = true;
15474 mStackSupervisor.dump(pw, " ");
15477 if (!printedAnything) {
15478 pw.println(" (nothing)");
15482 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15483 int opti, boolean dumpAll, String dumpPackage) {
15484 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15486 boolean printedAnything = false;
15488 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15489 boolean printedHeader = false;
15491 final int N = mRecentTasks.size();
15492 for (int i=0; i<N; i++) {
15493 TaskRecord tr = mRecentTasks.get(i);
15494 if (dumpPackage != null) {
15495 if (tr.realActivity == null ||
15496 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15500 if (!printedHeader) {
15501 pw.println(" Recent tasks:");
15502 printedHeader = true;
15503 printedAnything = true;
15505 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15508 mRecentTasks.get(i).dump(pw, " ");
15513 if (!printedAnything) {
15514 pw.println(" (nothing)");
15518 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15519 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15520 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15523 if (dumpPackage != null) {
15524 IPackageManager pm = AppGlobals.getPackageManager();
15526 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15527 } catch (RemoteException e) {
15531 boolean printedAnything = false;
15533 final long now = SystemClock.uptimeMillis();
15535 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15536 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15537 = mAssociations.valueAt(i1);
15538 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15539 SparseArray<ArrayMap<String, Association>> sourceUids
15540 = targetComponents.valueAt(i2);
15541 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15542 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15543 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15544 Association ass = sourceProcesses.valueAt(i4);
15545 if (dumpPackage != null) {
15546 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15547 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15551 printedAnything = true;
15553 pw.print(ass.mTargetProcess);
15555 UserHandle.formatUid(pw, ass.mTargetUid);
15557 pw.print(ass.mSourceProcess);
15559 UserHandle.formatUid(pw, ass.mSourceUid);
15562 pw.print(ass.mTargetComponent.flattenToShortString());
15565 long dur = ass.mTime;
15566 if (ass.mNesting > 0) {
15567 dur += now - ass.mStartTime;
15569 TimeUtils.formatDuration(dur, pw);
15571 pw.print(ass.mCount);
15572 pw.print(" times)");
15574 for (int i=0; i<ass.mStateTimes.length; i++) {
15575 long amt = ass.mStateTimes[i];
15576 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15577 amt += now - ass.mLastStateUptime;
15581 pw.print(ProcessList.makeProcStateString(
15582 i + ActivityManager.MIN_PROCESS_STATE));
15584 TimeUtils.formatDuration(amt, pw);
15585 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15591 if (ass.mNesting > 0) {
15592 pw.print(" Currently active: ");
15593 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15602 if (!printedAnything) {
15603 pw.println(" (nothing)");
15607 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15608 String header, boolean needSep) {
15609 boolean printed = false;
15610 int whichAppId = -1;
15611 if (dumpPackage != null) {
15613 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15615 whichAppId = UserHandle.getAppId(info.uid);
15616 } catch (NameNotFoundException e) {
15617 e.printStackTrace();
15620 for (int i=0; i<uids.size(); i++) {
15621 UidRecord uidRec = uids.valueAt(i);
15622 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15631 pw.println(header);
15634 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15635 pw.print(": "); pw.println(uidRec);
15640 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15641 int opti, boolean dumpAll, String dumpPackage) {
15642 boolean needSep = false;
15643 boolean printedAnything = false;
15646 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15649 final int NP = mProcessNames.getMap().size();
15650 for (int ip=0; ip<NP; ip++) {
15651 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15652 final int NA = procs.size();
15653 for (int ia=0; ia<NA; ia++) {
15654 ProcessRecord r = procs.valueAt(ia);
15655 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15659 pw.println(" All known processes:");
15661 printedAnything = true;
15663 pw.print(r.persistent ? " *PERS*" : " *APP*");
15664 pw.print(" UID "); pw.print(procs.keyAt(ia));
15665 pw.print(" "); pw.println(r);
15667 if (r.persistent) {
15674 if (mIsolatedProcesses.size() > 0) {
15675 boolean printed = false;
15676 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15677 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15678 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15685 pw.println(" Isolated process list (sorted by uid):");
15686 printedAnything = true;
15690 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15695 if (mActiveInstrumentation.size() > 0) {
15696 boolean printed = false;
15697 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15698 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15699 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15700 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15707 pw.println(" Active instrumentation:");
15708 printedAnything = true;
15712 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15718 if (mActiveUids.size() > 0) {
15719 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15720 printedAnything = needSep = true;
15724 if (mValidateUids.size() > 0) {
15725 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15726 printedAnything = needSep = true;
15731 if (mLruProcesses.size() > 0) {
15735 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15736 pw.print(" total, non-act at ");
15737 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15738 pw.print(", non-svc at ");
15739 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15741 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15743 printedAnything = true;
15746 if (dumpAll || dumpPackage != null) {
15747 synchronized (mPidsSelfLocked) {
15748 boolean printed = false;
15749 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15750 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15751 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15755 if (needSep) pw.println();
15757 pw.println(" PID mappings:");
15759 printedAnything = true;
15761 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15762 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15767 if (mImportantProcesses.size() > 0) {
15768 synchronized (mPidsSelfLocked) {
15769 boolean printed = false;
15770 for (int i = 0; i< mImportantProcesses.size(); i++) {
15771 ProcessRecord r = mPidsSelfLocked.get(
15772 mImportantProcesses.valueAt(i).pid);
15773 if (dumpPackage != null && (r == null
15774 || !r.pkgList.containsKey(dumpPackage))) {
15778 if (needSep) pw.println();
15780 pw.println(" Foreground Processes:");
15782 printedAnything = true;
15784 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15785 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15790 if (mPersistentStartingProcesses.size() > 0) {
15791 if (needSep) pw.println();
15793 printedAnything = true;
15794 pw.println(" Persisent processes that are starting:");
15795 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15796 "Starting Norm", "Restarting PERS", dumpPackage);
15799 if (mRemovedProcesses.size() > 0) {
15800 if (needSep) pw.println();
15802 printedAnything = true;
15803 pw.println(" Processes that are being removed:");
15804 dumpProcessList(pw, this, mRemovedProcesses, " ",
15805 "Removed Norm", "Removed PERS", dumpPackage);
15808 if (mProcessesOnHold.size() > 0) {
15809 if (needSep) pw.println();
15811 printedAnything = true;
15812 pw.println(" Processes that are on old until the system is ready:");
15813 dumpProcessList(pw, this, mProcessesOnHold, " ",
15814 "OnHold Norm", "OnHold PERS", dumpPackage);
15817 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15819 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15821 printedAnything = true;
15824 if (dumpPackage == null) {
15827 mUserController.dump(pw, dumpAll);
15829 if (mHomeProcess != null && (dumpPackage == null
15830 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15835 pw.println(" mHomeProcess: " + mHomeProcess);
15837 if (mPreviousProcess != null && (dumpPackage == null
15838 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15843 pw.println(" mPreviousProcess: " + mPreviousProcess);
15846 StringBuilder sb = new StringBuilder(128);
15847 sb.append(" mPreviousProcessVisibleTime: ");
15848 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15851 if (mHeavyWeightProcess != null && (dumpPackage == null
15852 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15857 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15859 if (dumpPackage == null) {
15860 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15861 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15864 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15865 if (mCompatModePackages.getPackages().size() > 0) {
15866 boolean printed = false;
15867 for (Map.Entry<String, Integer> entry
15868 : mCompatModePackages.getPackages().entrySet()) {
15869 String pkg = entry.getKey();
15870 int mode = entry.getValue();
15871 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15875 pw.println(" mScreenCompatPackages:");
15878 pw.print(" "); pw.print(pkg); pw.print(": ");
15879 pw.print(mode); pw.println();
15882 final int NI = mUidObservers.getRegisteredCallbackCount();
15883 boolean printed = false;
15884 for (int i=0; i<NI; i++) {
15885 final UidObserverRegistration reg = (UidObserverRegistration)
15886 mUidObservers.getRegisteredCallbackCookie(i);
15887 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15889 pw.println(" mUidObservers:");
15892 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15893 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15894 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15897 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15900 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15903 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15904 pw.print(" STATE");
15905 pw.print(" (cut="); pw.print(reg.cutpoint);
15909 if (reg.lastProcStates != null) {
15910 final int NJ = reg.lastProcStates.size();
15911 for (int j=0; j<NJ; j++) {
15912 pw.print(" Last ");
15913 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15914 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15919 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15920 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15921 if (mPendingTempWhitelist.size() > 0) {
15922 pw.println(" mPendingTempWhitelist:");
15923 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15924 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15926 UserHandle.formatUid(pw, ptw.targetUid);
15928 TimeUtils.formatDuration(ptw.duration, pw);
15930 pw.println(ptw.tag);
15934 if (dumpPackage == null) {
15935 pw.println(" mWakefulness="
15936 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15937 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
15938 pw.println(" mSleeping=" + mSleeping);
15939 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15940 if (mRunningVoice != null) {
15941 pw.println(" mRunningVoice=" + mRunningVoice);
15942 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15945 pw.println(" mVrController=" + mVrController);
15946 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15947 || mOrigWaitForDebugger) {
15948 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15949 || dumpPackage.equals(mOrigDebugApp)) {
15954 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15955 + " mDebugTransient=" + mDebugTransient
15956 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15959 if (mCurAppTimeTracker != null) {
15960 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15962 if (mMemWatchProcesses.getMap().size() > 0) {
15963 pw.println(" Mem watch processes:");
15964 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15965 = mMemWatchProcesses.getMap();
15966 for (int i=0; i<procs.size(); i++) {
15967 final String proc = procs.keyAt(i);
15968 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15969 for (int j=0; j<uids.size(); j++) {
15974 StringBuilder sb = new StringBuilder();
15975 sb.append(" ").append(proc).append('/');
15976 UserHandle.formatUid(sb, uids.keyAt(j));
15977 Pair<Long, String> val = uids.valueAt(j);
15978 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15979 if (val.second != null) {
15980 sb.append(", report to ").append(val.second);
15982 pw.println(sb.toString());
15985 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15986 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15987 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15988 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15990 if (mTrackAllocationApp != null) {
15991 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15996 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15999 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16000 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16001 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16006 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16007 if (mProfilerInfo != null) {
16008 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16009 mProfilerInfo.profileFd);
16010 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
16011 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16012 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16013 pw.println(" mProfileType=" + mProfileType);
16017 if (mNativeDebuggingApp != null) {
16018 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16023 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
16026 if (dumpPackage == null) {
16027 if (mAlwaysFinishActivities) {
16028 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16030 if (mController != null) {
16031 pw.println(" mController=" + mController
16032 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16035 pw.println(" Total persistent processes: " + numPers);
16036 pw.println(" mProcessesReady=" + mProcessesReady
16037 + " mSystemReady=" + mSystemReady
16038 + " mBooted=" + mBooted
16039 + " mFactoryTest=" + mFactoryTest);
16040 pw.println(" mBooting=" + mBooting
16041 + " mCallFinishBooting=" + mCallFinishBooting
16042 + " mBootAnimationComplete=" + mBootAnimationComplete);
16043 pw.print(" mLastPowerCheckUptime=");
16044 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16046 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16047 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16048 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16049 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
16050 + " (" + mLruProcesses.size() + " total)"
16051 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16052 + " mNumServiceProcs=" + mNumServiceProcs
16053 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16054 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
16055 + " mLastMemoryLevel=" + mLastMemoryLevel
16056 + " mLastNumProcesses=" + mLastNumProcesses);
16057 long now = SystemClock.uptimeMillis();
16058 pw.print(" mLastIdleTime=");
16059 TimeUtils.formatDuration(now, mLastIdleTime, pw);
16060 pw.print(" mLowRamSinceLastIdle=");
16061 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16066 if (!printedAnything) {
16067 pw.println(" (nothing)");
16071 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16072 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16073 if (mProcessesToGc.size() > 0) {
16074 boolean printed = false;
16075 long now = SystemClock.uptimeMillis();
16076 for (int i=0; i<mProcessesToGc.size(); i++) {
16077 ProcessRecord proc = mProcessesToGc.get(i);
16078 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16082 if (needSep) pw.println();
16084 pw.println(" Processes that are waiting to GC:");
16087 pw.print(" Process "); pw.println(proc);
16088 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16089 pw.print(", last gced=");
16090 pw.print(now-proc.lastRequestedGc);
16091 pw.print(" ms ago, last lowMem=");
16092 pw.print(now-proc.lastLowMemory);
16093 pw.println(" ms ago");
16100 void printOomLevel(PrintWriter pw, String name, int adj) {
16104 if (adj < 10) pw.print(' ');
16106 if (adj > -10) pw.print(' ');
16112 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16116 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16117 int opti, boolean dumpAll) {
16118 boolean needSep = false;
16120 if (mLruProcesses.size() > 0) {
16121 if (needSep) pw.println();
16123 pw.println(" OOM levels:");
16124 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16125 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16126 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16127 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16128 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16129 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16130 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16131 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16132 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16133 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16134 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16135 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16136 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16137 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16139 if (needSep) pw.println();
16140 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16141 pw.print(" total, non-act at ");
16142 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16143 pw.print(", non-svc at ");
16144 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16146 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16150 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16153 pw.println(" mHomeProcess: " + mHomeProcess);
16154 pw.println(" mPreviousProcess: " + mPreviousProcess);
16155 if (mHeavyWeightProcess != null) {
16156 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16163 * There are three ways to call this:
16164 * - no provider specified: dump all the providers
16165 * - a flattened component name that matched an existing provider was specified as the
16166 * first arg: dump that one provider
16167 * - the first arg isn't the flattened component name of an existing provider:
16168 * dump all providers whose component contains the first arg as a substring
16170 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16171 int opti, boolean dumpAll) {
16172 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16175 static class ItemMatcher {
16176 ArrayList<ComponentName> components;
16177 ArrayList<String> strings;
16178 ArrayList<Integer> objects;
16185 void build(String name) {
16186 ComponentName componentName = ComponentName.unflattenFromString(name);
16187 if (componentName != null) {
16188 if (components == null) {
16189 components = new ArrayList<ComponentName>();
16191 components.add(componentName);
16195 // Not a '/' separated full component name; maybe an object ID?
16197 objectId = Integer.parseInt(name, 16);
16198 if (objects == null) {
16199 objects = new ArrayList<Integer>();
16201 objects.add(objectId);
16203 } catch (RuntimeException e) {
16204 // Not an integer; just do string match.
16205 if (strings == null) {
16206 strings = new ArrayList<String>();
16214 int build(String[] args, int opti) {
16215 for (; opti<args.length; opti++) {
16216 String name = args[opti];
16217 if ("--".equals(name)) {
16225 boolean match(Object object, ComponentName comp) {
16229 if (components != null) {
16230 for (int i=0; i<components.size(); i++) {
16231 if (components.get(i).equals(comp)) {
16236 if (objects != null) {
16237 for (int i=0; i<objects.size(); i++) {
16238 if (System.identityHashCode(object) == objects.get(i)) {
16243 if (strings != null) {
16244 String flat = comp.flattenToString();
16245 for (int i=0; i<strings.size(); i++) {
16246 if (flat.contains(strings.get(i))) {
16256 * There are three things that cmd can be:
16257 * - a flattened component name that matches an existing activity
16258 * - the cmd arg isn't the flattened component name of an existing activity:
16259 * dump all activity whose component contains the cmd as a substring
16260 * - A hex number of the ActivityRecord object instance.
16262 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16263 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16265 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16266 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16267 ArrayList<ActivityRecord> activities;
16269 synchronized (this) {
16270 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16271 dumpFocusedStackOnly);
16274 if (activities.size() <= 0) {
16278 String[] newArgs = new String[args.length - opti];
16279 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16281 TaskRecord lastTask = null;
16282 boolean needSep = false;
16283 for (int i=activities.size()-1; i>=0; i--) {
16284 ActivityRecord r = activities.get(i);
16289 synchronized (this) {
16290 final TaskRecord task = r.getTask();
16291 if (lastTask != task) {
16293 pw.print("TASK "); pw.print(lastTask.affinity);
16294 pw.print(" id="); pw.print(lastTask.taskId);
16295 pw.print(" userId="); pw.println(lastTask.userId);
16297 lastTask.dump(pw, " ");
16301 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16307 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16308 * there is a thread associated with the activity.
16310 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16311 final ActivityRecord r, String[] args, boolean dumpAll) {
16312 String innerPrefix = prefix + " ";
16313 synchronized (this) {
16314 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16315 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16317 if (r.app != null) pw.println(r.app.pid);
16318 else pw.println("(not running)");
16320 r.dump(pw, innerPrefix);
16323 if (r.app != null && r.app.thread != null) {
16324 // flush anything that is already in the PrintWriter since the thread is going
16325 // to write to the file descriptor directly
16328 TransferPipe tp = new TransferPipe();
16330 r.app.thread.dumpActivity(tp.getWriteFd(),
16331 r.appToken, innerPrefix, args);
16336 } catch (IOException e) {
16337 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16338 } catch (RemoteException e) {
16339 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16344 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16345 int opti, boolean dumpAll, String dumpPackage) {
16346 boolean needSep = false;
16347 boolean onlyHistory = false;
16348 boolean printedAnything = false;
16350 if ("history".equals(dumpPackage)) {
16351 if (opti < args.length && "-s".equals(args[opti])) {
16354 onlyHistory = true;
16355 dumpPackage = null;
16358 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16359 if (!onlyHistory && dumpAll) {
16360 if (mRegisteredReceivers.size() > 0) {
16361 boolean printed = false;
16362 Iterator it = mRegisteredReceivers.values().iterator();
16363 while (it.hasNext()) {
16364 ReceiverList r = (ReceiverList)it.next();
16365 if (dumpPackage != null && (r.app == null ||
16366 !dumpPackage.equals(r.app.info.packageName))) {
16370 pw.println(" Registered Receivers:");
16373 printedAnything = true;
16375 pw.print(" * "); pw.println(r);
16380 if (mReceiverResolver.dump(pw, needSep ?
16381 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16382 " ", dumpPackage, false, false)) {
16384 printedAnything = true;
16388 for (BroadcastQueue q : mBroadcastQueues) {
16389 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16390 printedAnything |= needSep;
16395 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16396 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16401 printedAnything = true;
16402 pw.print(" Sticky broadcasts for user ");
16403 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16404 StringBuilder sb = new StringBuilder(128);
16405 for (Map.Entry<String, ArrayList<Intent>> ent
16406 : mStickyBroadcasts.valueAt(user).entrySet()) {
16407 pw.print(" * Sticky action "); pw.print(ent.getKey());
16410 ArrayList<Intent> intents = ent.getValue();
16411 final int N = intents.size();
16412 for (int i=0; i<N; i++) {
16414 sb.append(" Intent: ");
16415 intents.get(i).toShortString(sb, false, true, false, false);
16416 pw.println(sb.toString());
16417 Bundle bundle = intents.get(i).getExtras();
16418 if (bundle != null) {
16420 pw.println(bundle.toString());
16430 if (!onlyHistory && dumpAll) {
16432 for (BroadcastQueue queue : mBroadcastQueues) {
16433 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16434 + queue.mBroadcastsScheduled);
16436 pw.println(" mHandler:");
16437 mHandler.dump(new PrintWriterPrinter(pw), " ");
16439 printedAnything = true;
16442 if (!printedAnything) {
16443 pw.println(" (nothing)");
16447 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16448 int opti, boolean dumpAll, String dumpPackage) {
16449 if (mCurBroadcastStats == null) {
16453 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16454 final long now = SystemClock.elapsedRealtime();
16455 if (mLastBroadcastStats != null) {
16456 pw.print(" Last stats (from ");
16457 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16459 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16461 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16462 - mLastBroadcastStats.mStartUptime, pw);
16463 pw.println(" uptime):");
16464 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16465 pw.println(" (nothing)");
16469 pw.print(" Current stats (from ");
16470 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16471 pw.print(" to now, ");
16472 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16473 - mCurBroadcastStats.mStartUptime, pw);
16474 pw.println(" uptime):");
16475 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16476 pw.println(" (nothing)");
16480 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16481 int opti, boolean fullCheckin, String dumpPackage) {
16482 if (mCurBroadcastStats == null) {
16486 if (mLastBroadcastStats != null) {
16487 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16489 mLastBroadcastStats = null;
16493 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16495 mCurBroadcastStats = null;
16499 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16500 int opti, boolean dumpAll, String dumpPackage) {
16502 boolean printedAnything = false;
16504 ItemMatcher matcher = new ItemMatcher();
16505 matcher.build(args, opti);
16507 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16509 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16510 printedAnything |= needSep;
16512 if (mLaunchingProviders.size() > 0) {
16513 boolean printed = false;
16514 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16515 ContentProviderRecord r = mLaunchingProviders.get(i);
16516 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16520 if (needSep) pw.println();
16522 pw.println(" Launching content providers:");
16524 printedAnything = true;
16526 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16531 if (!printedAnything) {
16532 pw.println(" (nothing)");
16536 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16537 int opti, boolean dumpAll, String dumpPackage) {
16538 boolean needSep = false;
16539 boolean printedAnything = false;
16541 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16543 if (mGrantedUriPermissions.size() > 0) {
16544 boolean printed = false;
16546 if (dumpPackage != null) {
16548 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16549 MATCH_ANY_USER, 0);
16550 } catch (NameNotFoundException e) {
16554 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16555 int uid = mGrantedUriPermissions.keyAt(i);
16556 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16559 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16561 if (needSep) pw.println();
16563 pw.println(" Granted Uri Permissions:");
16565 printedAnything = true;
16567 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16568 for (UriPermission perm : perms.values()) {
16569 pw.print(" "); pw.println(perm);
16571 perm.dump(pw, " ");
16577 if (!printedAnything) {
16578 pw.println(" (nothing)");
16582 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16583 int opti, boolean dumpAll, String dumpPackage) {
16584 boolean printed = false;
16586 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16588 if (mIntentSenderRecords.size() > 0) {
16589 // Organize these by package name, so they are easier to read.
16590 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16591 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16592 final Iterator<WeakReference<PendingIntentRecord>> it
16593 = mIntentSenderRecords.values().iterator();
16594 while (it.hasNext()) {
16595 WeakReference<PendingIntentRecord> ref = it.next();
16596 PendingIntentRecord rec = ref != null ? ref.get() : null;
16601 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16604 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16605 if (list == null) {
16606 list = new ArrayList<>();
16607 byPackage.put(rec.key.packageName, list);
16611 for (int i = 0; i < byPackage.size(); i++) {
16612 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16614 pw.print(" * "); pw.print(byPackage.keyAt(i));
16615 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16616 for (int j = 0; j < intents.size(); j++) {
16617 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16619 intents.get(j).dump(pw, " ");
16623 if (weakRefs.size() > 0) {
16625 pw.println(" * WEAK REFS:");
16626 for (int i = 0; i < weakRefs.size(); i++) {
16627 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16633 pw.println(" (nothing)");
16637 private static final int dumpProcessList(PrintWriter pw,
16638 ActivityManagerService service, List list,
16639 String prefix, String normalLabel, String persistentLabel,
16640 String dumpPackage) {
16642 final int N = list.size()-1;
16643 for (int i=N; i>=0; i--) {
16644 ProcessRecord r = (ProcessRecord)list.get(i);
16645 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16648 pw.println(String.format("%s%s #%2d: %s",
16649 prefix, (r.persistent ? persistentLabel : normalLabel),
16651 if (r.persistent) {
16658 private static final boolean dumpProcessOomList(PrintWriter pw,
16659 ActivityManagerService service, List<ProcessRecord> origList,
16660 String prefix, String normalLabel, String persistentLabel,
16661 boolean inclDetails, String dumpPackage) {
16663 ArrayList<Pair<ProcessRecord, Integer>> list
16664 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16665 for (int i=0; i<origList.size(); i++) {
16666 ProcessRecord r = origList.get(i);
16667 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16670 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16673 if (list.size() <= 0) {
16677 Comparator<Pair<ProcessRecord, Integer>> comparator
16678 = new Comparator<Pair<ProcessRecord, Integer>>() {
16680 public int compare(Pair<ProcessRecord, Integer> object1,
16681 Pair<ProcessRecord, Integer> object2) {
16682 if (object1.first.setAdj != object2.first.setAdj) {
16683 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16685 if (object1.first.setProcState != object2.first.setProcState) {
16686 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16688 if (object1.second.intValue() != object2.second.intValue()) {
16689 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16695 Collections.sort(list, comparator);
16697 final long curUptime = SystemClock.uptimeMillis();
16698 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16700 for (int i=list.size()-1; i>=0; i--) {
16701 ProcessRecord r = list.get(i).first;
16702 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16704 switch (r.setSchedGroup) {
16705 case ProcessList.SCHED_GROUP_BACKGROUND:
16708 case ProcessList.SCHED_GROUP_DEFAULT:
16711 case ProcessList.SCHED_GROUP_TOP_APP:
16719 if (r.foregroundActivities) {
16721 } else if (r.foregroundServices) {
16726 String procState = ProcessList.makeProcStateString(r.curProcState);
16728 pw.print(r.persistent ? persistentLabel : normalLabel);
16730 int num = (origList.size()-1)-list.get(i).second;
16731 if (num < 10) pw.print(' ');
16736 pw.print(schedGroup);
16738 pw.print(foreground);
16740 pw.print(procState);
16742 if (r.trimMemoryLevel < 10) pw.print(' ');
16743 pw.print(r.trimMemoryLevel);
16745 pw.print(r.toShortString());
16747 pw.print(r.adjType);
16749 if (r.adjSource != null || r.adjTarget != null) {
16752 if (r.adjTarget instanceof ComponentName) {
16753 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16754 } else if (r.adjTarget != null) {
16755 pw.print(r.adjTarget.toString());
16757 pw.print("{null}");
16760 if (r.adjSource instanceof ProcessRecord) {
16762 pw.print(((ProcessRecord)r.adjSource).toShortString());
16764 } else if (r.adjSource != null) {
16765 pw.println(r.adjSource.toString());
16767 pw.println("{null}");
16773 pw.print("oom: max="); pw.print(r.maxAdj);
16774 pw.print(" curRaw="); pw.print(r.curRawAdj);
16775 pw.print(" setRaw="); pw.print(r.setRawAdj);
16776 pw.print(" cur="); pw.print(r.curAdj);
16777 pw.print(" set="); pw.println(r.setAdj);
16780 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16781 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16782 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16783 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16784 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16788 pw.print("cached="); pw.print(r.cached);
16789 pw.print(" empty="); pw.print(r.empty);
16790 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16792 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16793 if (r.lastCpuTime != 0) {
16794 long timeUsed = r.curCpuTime - r.lastCpuTime;
16797 pw.print("run cpu over ");
16798 TimeUtils.formatDuration(uptimeSince, pw);
16799 pw.print(" used ");
16800 TimeUtils.formatDuration(timeUsed, pw);
16802 pw.print((timeUsed*100)/uptimeSince);
16811 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16813 ArrayList<ProcessRecord> procs;
16814 synchronized (this) {
16815 if (args != null && args.length > start
16816 && args[start].charAt(0) != '-') {
16817 procs = new ArrayList<ProcessRecord>();
16820 pid = Integer.parseInt(args[start]);
16821 } catch (NumberFormatException e) {
16823 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16824 ProcessRecord proc = mLruProcesses.get(i);
16825 if (proc.pid == pid) {
16827 } else if (allPkgs && proc.pkgList != null
16828 && proc.pkgList.containsKey(args[start])) {
16830 } else if (proc.processName.equals(args[start])) {
16834 if (procs.size() <= 0) {
16838 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16844 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16845 PrintWriter pw, String[] args) {
16846 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16847 if (procs == null) {
16848 pw.println("No process found for: " + args[0]);
16852 long uptime = SystemClock.uptimeMillis();
16853 long realtime = SystemClock.elapsedRealtime();
16854 pw.println("Applications Graphics Acceleration Info:");
16855 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16857 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16858 ProcessRecord r = procs.get(i);
16859 if (r.thread != null) {
16860 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16863 TransferPipe tp = new TransferPipe();
16865 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16870 } catch (IOException e) {
16871 pw.println("Failure while dumping the app: " + r);
16873 } catch (RemoteException e) {
16874 pw.println("Got a RemoteException while dumping the app " + r);
16881 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16882 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16883 if (procs == null) {
16884 pw.println("No process found for: " + args[0]);
16888 pw.println("Applications Database Info:");
16890 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16891 ProcessRecord r = procs.get(i);
16892 if (r.thread != null) {
16893 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16896 TransferPipe tp = new TransferPipe();
16898 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16903 } catch (IOException e) {
16904 pw.println("Failure while dumping the app: " + r);
16906 } catch (RemoteException e) {
16907 pw.println("Got a RemoteException while dumping the app " + r);
16914 final static class MemItem {
16915 final boolean isProc;
16916 final String label;
16917 final String shortLabel;
16919 final long swapPss;
16921 final boolean hasActivities;
16922 ArrayList<MemItem> subitems;
16924 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16925 boolean _hasActivities) {
16928 shortLabel = _shortLabel;
16930 swapPss = _swapPss;
16932 hasActivities = _hasActivities;
16935 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16938 shortLabel = _shortLabel;
16940 swapPss = _swapPss;
16942 hasActivities = false;
16946 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16947 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16948 if (sort && !isCompact) {
16949 Collections.sort(items, new Comparator<MemItem>() {
16951 public int compare(MemItem lhs, MemItem rhs) {
16952 if (lhs.pss < rhs.pss) {
16954 } else if (lhs.pss > rhs.pss) {
16962 for (int i=0; i<items.size(); i++) {
16963 MemItem mi = items.get(i);
16966 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16967 mi.label, stringifyKBSize(mi.swapPss));
16969 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16971 } else if (mi.isProc) {
16972 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16973 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16974 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16975 pw.println(mi.hasActivities ? ",a" : ",e");
16977 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16978 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16980 if (mi.subitems != null) {
16981 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16982 true, isCompact, dumpSwapPss);
16987 // These are in KB.
16988 static final long[] DUMP_MEM_BUCKETS = new long[] {
16989 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16990 120*1024, 160*1024, 200*1024,
16991 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16992 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16995 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16996 boolean stackLike) {
16997 int start = label.lastIndexOf('.');
16998 if (start >= 0) start++;
17000 int end = label.length();
17001 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
17002 if (DUMP_MEM_BUCKETS[i] >= memKB) {
17003 long bucket = DUMP_MEM_BUCKETS[i]/1024;
17004 out.append(bucket);
17005 out.append(stackLike ? "MB." : "MB ");
17006 out.append(label, start, end);
17010 out.append(memKB/1024);
17011 out.append(stackLike ? "MB." : "MB ");
17012 out.append(label, start, end);
17015 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17016 ProcessList.NATIVE_ADJ,
17017 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17018 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17019 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17020 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17021 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17022 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17024 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17026 "System", "Persistent", "Persistent Service", "Foreground",
17027 "Visible", "Perceptible",
17028 "Heavy Weight", "Backup",
17029 "A Services", "Home",
17030 "Previous", "B Services", "Cached"
17032 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17034 "sys", "pers", "persvc", "fore",
17037 "servicea", "home",
17038 "prev", "serviceb", "cached"
17041 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17042 long realtime, boolean isCheckinRequest, boolean isCompact) {
17044 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17046 if (isCheckinRequest || isCompact) {
17047 // short checkin version
17048 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17050 pw.println("Applications Memory Usage (in Kilobytes):");
17051 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17055 private static final int KSM_SHARED = 0;
17056 private static final int KSM_SHARING = 1;
17057 private static final int KSM_UNSHARED = 2;
17058 private static final int KSM_VOLATILE = 3;
17060 private final long[] getKsmInfo() {
17061 long[] longOut = new long[4];
17062 final int[] SINGLE_LONG_FORMAT = new int[] {
17063 PROC_SPACE_TERM| PROC_OUT_LONG
17065 long[] longTmp = new long[1];
17066 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17067 SINGLE_LONG_FORMAT, null, longTmp, null);
17068 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17070 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17071 SINGLE_LONG_FORMAT, null, longTmp, null);
17072 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17074 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17075 SINGLE_LONG_FORMAT, null, longTmp, null);
17076 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17078 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17079 SINGLE_LONG_FORMAT, null, longTmp, null);
17080 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17084 private static String stringifySize(long size, int order) {
17085 Locale locale = Locale.US;
17088 return String.format(locale, "%,13d", size);
17090 return String.format(locale, "%,9dK", size / 1024);
17092 return String.format(locale, "%,5dM", size / 1024 / 1024);
17093 case 1024 * 1024 * 1024:
17094 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17096 throw new IllegalArgumentException("Invalid size order");
17100 private static String stringifyKBSize(long size) {
17101 return stringifySize(size * 1024, 1024);
17104 // Update this version number in case you change the 'compact' format
17105 private static final int MEMINFO_COMPACT_VERSION = 1;
17107 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17108 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17109 boolean dumpDetails = false;
17110 boolean dumpFullDetails = false;
17111 boolean dumpDalvik = false;
17112 boolean dumpSummaryOnly = false;
17113 boolean dumpUnreachable = false;
17114 boolean oomOnly = false;
17115 boolean isCompact = false;
17116 boolean localOnly = false;
17117 boolean packages = false;
17118 boolean isCheckinRequest = false;
17119 boolean dumpSwapPss = false;
17122 while (opti < args.length) {
17123 String opt = args[opti];
17124 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17128 if ("-a".equals(opt)) {
17129 dumpDetails = true;
17130 dumpFullDetails = true;
17132 dumpSwapPss = true;
17133 } else if ("-d".equals(opt)) {
17135 } else if ("-c".equals(opt)) {
17137 } else if ("-s".equals(opt)) {
17138 dumpDetails = true;
17139 dumpSummaryOnly = true;
17140 } else if ("-S".equals(opt)) {
17141 dumpSwapPss = true;
17142 } else if ("--unreachable".equals(opt)) {
17143 dumpUnreachable = true;
17144 } else if ("--oom".equals(opt)) {
17146 } else if ("--local".equals(opt)) {
17148 } else if ("--package".equals(opt)) {
17150 } else if ("--checkin".equals(opt)) {
17151 isCheckinRequest = true;
17153 } else if ("-h".equals(opt)) {
17154 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17155 pw.println(" -a: include all available information for each process.");
17156 pw.println(" -d: include dalvik details.");
17157 pw.println(" -c: dump in a compact machine-parseable representation.");
17158 pw.println(" -s: dump only summary of application memory usage.");
17159 pw.println(" -S: dump also SwapPss.");
17160 pw.println(" --oom: only show processes organized by oom adj.");
17161 pw.println(" --local: only collect details locally, don't call process.");
17162 pw.println(" --package: interpret process arg as package, dumping all");
17163 pw.println(" processes that have loaded that package.");
17164 pw.println(" --checkin: dump data for a checkin");
17165 pw.println("If [process] is specified it can be the name or ");
17166 pw.println("pid of a specific process to dump.");
17169 pw.println("Unknown argument: " + opt + "; use -h for help");
17173 long uptime = SystemClock.uptimeMillis();
17174 long realtime = SystemClock.elapsedRealtime();
17175 final long[] tmpLong = new long[1];
17177 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17178 if (procs == null) {
17179 // No Java processes. Maybe they want to print a native process.
17180 if (args != null && args.length > opti
17181 && args[opti].charAt(0) != '-') {
17182 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17183 = new ArrayList<ProcessCpuTracker.Stats>();
17184 updateCpuStatsNow();
17187 findPid = Integer.parseInt(args[opti]);
17188 } catch (NumberFormatException e) {
17190 synchronized (mProcessCpuTracker) {
17191 final int N = mProcessCpuTracker.countStats();
17192 for (int i=0; i<N; i++) {
17193 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17194 if (st.pid == findPid || (st.baseName != null
17195 && st.baseName.equals(args[opti]))) {
17196 nativeProcs.add(st);
17200 if (nativeProcs.size() > 0) {
17201 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17203 Debug.MemoryInfo mi = null;
17204 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17205 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17206 final int pid = r.pid;
17207 if (!isCheckinRequest && dumpDetails) {
17208 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17211 mi = new Debug.MemoryInfo();
17213 if (dumpDetails || (!brief && !oomOnly)) {
17214 Debug.getMemoryInfo(pid, mi);
17216 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17217 mi.dalvikPrivateDirty = (int)tmpLong[0];
17219 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17220 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17221 if (isCheckinRequest) {
17228 pw.println("No process found for: " + args[opti]);
17232 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17233 dumpDetails = true;
17236 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17238 String[] innerArgs = new String[args.length-opti];
17239 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17241 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17242 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17243 long nativePss = 0;
17244 long nativeSwapPss = 0;
17245 long dalvikPss = 0;
17246 long dalvikSwapPss = 0;
17247 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17249 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17252 long otherSwapPss = 0;
17253 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17254 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17256 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17257 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17258 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17259 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17262 long totalSwapPss = 0;
17263 long cachedPss = 0;
17264 long cachedSwapPss = 0;
17265 boolean hasSwapPss = false;
17267 Debug.MemoryInfo mi = null;
17268 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17269 final ProcessRecord r = procs.get(i);
17270 final IApplicationThread thread;
17273 final boolean hasActivities;
17274 synchronized (this) {
17277 oomAdj = r.getSetAdjWithServices();
17278 hasActivities = r.activities.size() > 0;
17280 if (thread != null) {
17281 if (!isCheckinRequest && dumpDetails) {
17282 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17285 mi = new Debug.MemoryInfo();
17287 if (dumpDetails || (!brief && !oomOnly)) {
17288 Debug.getMemoryInfo(pid, mi);
17289 hasSwapPss = mi.hasSwappedOutPss;
17291 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17292 mi.dalvikPrivateDirty = (int)tmpLong[0];
17296 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17297 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17298 if (isCheckinRequest) {
17304 TransferPipe tp = new TransferPipe();
17306 thread.dumpMemInfo(tp.getWriteFd(),
17307 mi, isCheckinRequest, dumpFullDetails,
17308 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17313 } catch (IOException e) {
17314 if (!isCheckinRequest) {
17315 pw.println("Got IoException! " + e);
17318 } catch (RemoteException e) {
17319 if (!isCheckinRequest) {
17320 pw.println("Got RemoteException! " + e);
17327 final long myTotalPss = mi.getTotalPss();
17328 final long myTotalUss = mi.getTotalUss();
17329 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17331 synchronized (this) {
17332 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17333 // Record this for posterity if the process has been stable.
17334 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17338 if (!isCheckinRequest && mi != null) {
17339 totalPss += myTotalPss;
17340 totalSwapPss += myTotalSwapPss;
17341 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17342 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17343 myTotalSwapPss, pid, hasActivities);
17344 procMems.add(pssItem);
17345 procMemsMap.put(pid, pssItem);
17347 nativePss += mi.nativePss;
17348 nativeSwapPss += mi.nativeSwappedOutPss;
17349 dalvikPss += mi.dalvikPss;
17350 dalvikSwapPss += mi.dalvikSwappedOutPss;
17351 for (int j=0; j<dalvikSubitemPss.length; j++) {
17352 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17353 dalvikSubitemSwapPss[j] +=
17354 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17356 otherPss += mi.otherPss;
17357 otherSwapPss += mi.otherSwappedOutPss;
17358 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17359 long mem = mi.getOtherPss(j);
17362 mem = mi.getOtherSwappedOutPss(j);
17363 miscSwapPss[j] += mem;
17364 otherSwapPss -= mem;
17367 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17368 cachedPss += myTotalPss;
17369 cachedSwapPss += myTotalSwapPss;
17372 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17373 if (oomIndex == (oomPss.length - 1)
17374 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17375 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17376 oomPss[oomIndex] += myTotalPss;
17377 oomSwapPss[oomIndex] += myTotalSwapPss;
17378 if (oomProcs[oomIndex] == null) {
17379 oomProcs[oomIndex] = new ArrayList<MemItem>();
17381 oomProcs[oomIndex].add(pssItem);
17389 long nativeProcTotalPss = 0;
17391 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17392 // If we are showing aggregations, also look for native processes to
17393 // include so that our aggregations are more accurate.
17394 updateCpuStatsNow();
17396 synchronized (mProcessCpuTracker) {
17397 final int N = mProcessCpuTracker.countStats();
17398 for (int i=0; i<N; i++) {
17399 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17400 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17402 mi = new Debug.MemoryInfo();
17404 if (!brief && !oomOnly) {
17405 Debug.getMemoryInfo(st.pid, mi);
17407 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17408 mi.nativePrivateDirty = (int)tmpLong[0];
17411 final long myTotalPss = mi.getTotalPss();
17412 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17413 totalPss += myTotalPss;
17414 nativeProcTotalPss += myTotalPss;
17416 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17417 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17418 procMems.add(pssItem);
17420 nativePss += mi.nativePss;
17421 nativeSwapPss += mi.nativeSwappedOutPss;
17422 dalvikPss += mi.dalvikPss;
17423 dalvikSwapPss += mi.dalvikSwappedOutPss;
17424 for (int j=0; j<dalvikSubitemPss.length; j++) {
17425 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17426 dalvikSubitemSwapPss[j] +=
17427 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17429 otherPss += mi.otherPss;
17430 otherSwapPss += mi.otherSwappedOutPss;
17431 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17432 long mem = mi.getOtherPss(j);
17435 mem = mi.getOtherSwappedOutPss(j);
17436 miscSwapPss[j] += mem;
17437 otherSwapPss -= mem;
17439 oomPss[0] += myTotalPss;
17440 oomSwapPss[0] += myTotalSwapPss;
17441 if (oomProcs[0] == null) {
17442 oomProcs[0] = new ArrayList<MemItem>();
17444 oomProcs[0].add(pssItem);
17449 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17451 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17452 final int dalvikId = -2;
17453 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17454 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17455 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17456 String label = Debug.MemoryInfo.getOtherLabel(j);
17457 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17459 if (dalvikSubitemPss.length > 0) {
17460 // Add dalvik subitems.
17461 for (MemItem memItem : catMems) {
17462 int memItemStart = 0, memItemEnd = 0;
17463 if (memItem.id == dalvikId) {
17464 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17465 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17466 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17467 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17468 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17469 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17470 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17471 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17472 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17473 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17474 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17476 continue; // No subitems, continue.
17478 memItem.subitems = new ArrayList<MemItem>();
17479 for (int j=memItemStart; j<=memItemEnd; j++) {
17480 final String name = Debug.MemoryInfo.getOtherLabel(
17481 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17482 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17483 dalvikSubitemSwapPss[j], j));
17488 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17489 for (int j=0; j<oomPss.length; j++) {
17490 if (oomPss[j] != 0) {
17491 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17492 : DUMP_MEM_OOM_LABEL[j];
17493 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17494 DUMP_MEM_OOM_ADJ[j]);
17495 item.subitems = oomProcs[j];
17500 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17501 if (!brief && !oomOnly && !isCompact) {
17503 pw.println("Total PSS by process:");
17504 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17508 pw.println("Total PSS by OOM adjustment:");
17510 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17511 if (!brief && !oomOnly) {
17512 PrintWriter out = categoryPw != null ? categoryPw : pw;
17515 out.println("Total PSS by category:");
17517 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17522 MemInfoReader memInfo = new MemInfoReader();
17523 memInfo.readMemInfo();
17524 if (nativeProcTotalPss > 0) {
17525 synchronized (this) {
17526 final long cachedKb = memInfo.getCachedSizeKb();
17527 final long freeKb = memInfo.getFreeSizeKb();
17528 final long zramKb = memInfo.getZramTotalSizeKb();
17529 final long kernelKb = memInfo.getKernelUsedSizeKb();
17530 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17531 kernelKb*1024, nativeProcTotalPss*1024);
17532 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17533 nativeProcTotalPss);
17538 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17539 pw.print(" (status ");
17540 switch (mLastMemoryLevel) {
17541 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17542 pw.println("normal)");
17544 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17545 pw.println("moderate)");
17547 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17548 pw.println("low)");
17550 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17551 pw.println("critical)");
17554 pw.print(mLastMemoryLevel);
17558 pw.print(" Free RAM: ");
17559 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17560 + memInfo.getFreeSizeKb()));
17562 pw.print(stringifyKBSize(cachedPss));
17563 pw.print(" cached pss + ");
17564 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17565 pw.print(" cached kernel + ");
17566 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17567 pw.println(" free)");
17569 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17570 pw.print(cachedPss + memInfo.getCachedSizeKb()
17571 + memInfo.getFreeSizeKb()); pw.print(",");
17572 pw.println(totalPss - cachedPss);
17575 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17576 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17577 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17579 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17580 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17581 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17582 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17583 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17585 pw.print("lostram,"); pw.println(lostRAM);
17588 if (memInfo.getZramTotalSizeKb() != 0) {
17590 pw.print(" ZRAM: ");
17591 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17592 pw.print(" physical used for ");
17593 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17594 - memInfo.getSwapFreeSizeKb()));
17595 pw.print(" in swap (");
17596 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17597 pw.println(" total swap)");
17599 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17600 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17601 pw.println(memInfo.getSwapFreeSizeKb());
17604 final long[] ksm = getKsmInfo();
17606 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17607 || ksm[KSM_VOLATILE] != 0) {
17608 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17609 pw.print(" saved from shared ");
17610 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17611 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17612 pw.print(" unshared; ");
17613 pw.print(stringifyKBSize(
17614 ksm[KSM_VOLATILE])); pw.println(" volatile");
17616 pw.print(" Tuning: ");
17617 pw.print(ActivityManager.staticGetMemoryClass());
17618 pw.print(" (large ");
17619 pw.print(ActivityManager.staticGetLargeMemoryClass());
17620 pw.print("), oom ");
17621 pw.print(stringifySize(
17622 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17623 pw.print(", restore limit ");
17624 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17625 if (ActivityManager.isLowRamDeviceStatic()) {
17626 pw.print(" (low-ram)");
17628 if (ActivityManager.isHighEndGfx()) {
17629 pw.print(" (high-end-gfx)");
17633 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17634 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17635 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17636 pw.print("tuning,");
17637 pw.print(ActivityManager.staticGetMemoryClass());
17639 pw.print(ActivityManager.staticGetLargeMemoryClass());
17641 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17642 if (ActivityManager.isLowRamDeviceStatic()) {
17643 pw.print(",low-ram");
17645 if (ActivityManager.isHighEndGfx()) {
17646 pw.print(",high-end-gfx");
17654 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17655 long memtrack, String name) {
17657 sb.append(ProcessList.makeOomAdjString(oomAdj));
17659 sb.append(ProcessList.makeProcStateString(procState));
17661 ProcessList.appendRamKb(sb, pss);
17664 if (memtrack > 0) {
17666 sb.append(stringifyKBSize(memtrack));
17667 sb.append(" memtrack)");
17671 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17672 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17673 sb.append(" (pid ");
17676 sb.append(mi.adjType);
17678 if (mi.adjReason != null) {
17680 sb.append(mi.adjReason);
17685 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17686 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17687 for (int i=0, N=memInfos.size(); i<N; i++) {
17688 ProcessMemInfo mi = memInfos.get(i);
17689 infoMap.put(mi.pid, mi);
17691 updateCpuStatsNow();
17692 long[] memtrackTmp = new long[1];
17693 final List<ProcessCpuTracker.Stats> stats;
17694 // Get a list of Stats that have vsize > 0
17695 synchronized (mProcessCpuTracker) {
17696 stats = mProcessCpuTracker.getStats((st) -> {
17697 return st.vsize > 0;
17700 final int statsCount = stats.size();
17701 for (int i = 0; i < statsCount; i++) {
17702 ProcessCpuTracker.Stats st = stats.get(i);
17703 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17705 if (infoMap.indexOfKey(st.pid) < 0) {
17706 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17707 ProcessList.NATIVE_ADJ, -1, "native", null);
17709 mi.memtrack = memtrackTmp[0];
17716 long totalMemtrack = 0;
17717 for (int i=0, N=memInfos.size(); i<N; i++) {
17718 ProcessMemInfo mi = memInfos.get(i);
17720 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17721 mi.memtrack = memtrackTmp[0];
17723 totalPss += mi.pss;
17724 totalMemtrack += mi.memtrack;
17726 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17727 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17728 if (lhs.oomAdj != rhs.oomAdj) {
17729 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17731 if (lhs.pss != rhs.pss) {
17732 return lhs.pss < rhs.pss ? 1 : -1;
17738 StringBuilder tag = new StringBuilder(128);
17739 StringBuilder stack = new StringBuilder(128);
17740 tag.append("Low on memory -- ");
17741 appendMemBucket(tag, totalPss, "total", false);
17742 appendMemBucket(stack, totalPss, "total", true);
17744 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17745 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17746 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17748 boolean firstLine = true;
17749 int lastOomAdj = Integer.MIN_VALUE;
17750 long extraNativeRam = 0;
17751 long extraNativeMemtrack = 0;
17752 long cachedPss = 0;
17753 for (int i=0, N=memInfos.size(); i<N; i++) {
17754 ProcessMemInfo mi = memInfos.get(i);
17756 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17757 cachedPss += mi.pss;
17760 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17761 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17762 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17763 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17764 if (lastOomAdj != mi.oomAdj) {
17765 lastOomAdj = mi.oomAdj;
17766 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17769 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17774 stack.append("\n\t at ");
17782 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17783 appendMemBucket(tag, mi.pss, mi.name, false);
17785 appendMemBucket(stack, mi.pss, mi.name, true);
17786 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17787 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17789 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17790 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17791 stack.append(DUMP_MEM_OOM_LABEL[k]);
17793 stack.append(DUMP_MEM_OOM_ADJ[k]);
17800 appendMemInfo(fullNativeBuilder, mi);
17801 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17802 // The short form only has native processes that are >= 512K.
17803 if (mi.pss >= 512) {
17804 appendMemInfo(shortNativeBuilder, mi);
17806 extraNativeRam += mi.pss;
17807 extraNativeMemtrack += mi.memtrack;
17810 // Short form has all other details, but if we have collected RAM
17811 // from smaller native processes let's dump a summary of that.
17812 if (extraNativeRam > 0) {
17813 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17814 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17815 shortNativeBuilder.append('\n');
17816 extraNativeRam = 0;
17818 appendMemInfo(fullJavaBuilder, mi);
17822 fullJavaBuilder.append(" ");
17823 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17824 fullJavaBuilder.append(": TOTAL");
17825 if (totalMemtrack > 0) {
17826 fullJavaBuilder.append(" (");
17827 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17828 fullJavaBuilder.append(" memtrack)");
17831 fullJavaBuilder.append("\n");
17833 MemInfoReader memInfo = new MemInfoReader();
17834 memInfo.readMemInfo();
17835 final long[] infos = memInfo.getRawInfo();
17837 StringBuilder memInfoBuilder = new StringBuilder(1024);
17838 Debug.getMemInfo(infos);
17839 memInfoBuilder.append(" MemInfo: ");
17840 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17841 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17842 memInfoBuilder.append(stringifyKBSize(
17843 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17844 memInfoBuilder.append(stringifyKBSize(
17845 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17846 memInfoBuilder.append(stringifyKBSize(
17847 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17848 memInfoBuilder.append(" ");
17849 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17850 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17851 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17852 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17853 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17854 memInfoBuilder.append(" ZRAM: ");
17855 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17856 memInfoBuilder.append(" RAM, ");
17857 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17858 memInfoBuilder.append(" swap total, ");
17859 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17860 memInfoBuilder.append(" swap free\n");
17862 final long[] ksm = getKsmInfo();
17863 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17864 || ksm[KSM_VOLATILE] != 0) {
17865 memInfoBuilder.append(" KSM: ");
17866 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17867 memInfoBuilder.append(" saved from shared ");
17868 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17869 memInfoBuilder.append("\n ");
17870 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17871 memInfoBuilder.append(" unshared; ");
17872 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17873 memInfoBuilder.append(" volatile\n");
17875 memInfoBuilder.append(" Free RAM: ");
17876 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17877 + memInfo.getFreeSizeKb()));
17878 memInfoBuilder.append("\n");
17879 memInfoBuilder.append(" Used RAM: ");
17880 memInfoBuilder.append(stringifyKBSize(
17881 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17882 memInfoBuilder.append("\n");
17883 memInfoBuilder.append(" Lost RAM: ");
17884 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17885 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17886 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17887 memInfoBuilder.append("\n");
17888 Slog.i(TAG, "Low on memory:");
17889 Slog.i(TAG, shortNativeBuilder.toString());
17890 Slog.i(TAG, fullJavaBuilder.toString());
17891 Slog.i(TAG, memInfoBuilder.toString());
17893 StringBuilder dropBuilder = new StringBuilder(1024);
17895 StringWriter oomSw = new StringWriter();
17896 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17897 StringWriter catSw = new StringWriter();
17898 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17899 String[] emptyArgs = new String[] { };
17900 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17902 String oomString = oomSw.toString();
17904 dropBuilder.append("Low on memory:");
17905 dropBuilder.append(stack);
17906 dropBuilder.append('\n');
17907 dropBuilder.append(fullNativeBuilder);
17908 dropBuilder.append(fullJavaBuilder);
17909 dropBuilder.append('\n');
17910 dropBuilder.append(memInfoBuilder);
17911 dropBuilder.append('\n');
17913 dropBuilder.append(oomString);
17914 dropBuilder.append('\n');
17916 StringWriter catSw = new StringWriter();
17917 synchronized (ActivityManagerService.this) {
17918 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17919 String[] emptyArgs = new String[] { };
17921 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17923 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17924 false, null).dumpLocked();
17926 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17929 dropBuilder.append(catSw.toString());
17930 addErrorToDropBox("lowmem", null, "system_server", null,
17931 null, tag.toString(), dropBuilder.toString(), null, null);
17932 //Slog.i(TAG, "Sent to dropbox:");
17933 //Slog.i(TAG, dropBuilder.toString());
17934 synchronized (ActivityManagerService.this) {
17935 long now = SystemClock.uptimeMillis();
17936 if (mLastMemUsageReportTime < now) {
17937 mLastMemUsageReportTime = now;
17943 * Searches array of arguments for the specified string
17944 * @param args array of argument strings
17945 * @param value value to search for
17946 * @return true if the value is contained in the array
17948 private static boolean scanArgs(String[] args, String value) {
17949 if (args != null) {
17950 for (String arg : args) {
17951 if (value.equals(arg)) {
17959 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17960 ContentProviderRecord cpr, boolean always) {
17961 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17963 if (!inLaunching || always) {
17964 synchronized (cpr) {
17965 cpr.launchingApp = null;
17968 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17969 String names[] = cpr.info.authority.split(";");
17970 for (int j = 0; j < names.length; j++) {
17971 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17975 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17976 ContentProviderConnection conn = cpr.connections.get(i);
17977 if (conn.waiting) {
17978 // If this connection is waiting for the provider, then we don't
17979 // need to mess with its process unless we are always removing
17980 // or for some reason the provider is not currently launching.
17981 if (inLaunching && !always) {
17985 ProcessRecord capp = conn.client;
17987 if (conn.stableCount > 0) {
17988 if (!capp.persistent && capp.thread != null
17990 && capp.pid != MY_PID) {
17991 capp.kill("depends on provider "
17992 + cpr.name.flattenToShortString()
17993 + " in dying proc " + (proc != null ? proc.processName : "??")
17994 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17996 } else if (capp.thread != null && conn.provider.provider != null) {
17998 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17999 } catch (RemoteException e) {
18001 // In the protocol here, we don't expect the client to correctly
18002 // clean up this connection, we'll just remove it.
18003 cpr.connections.remove(i);
18004 if (conn.client.conProviders.remove(conn)) {
18005 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18010 if (inLaunching && always) {
18011 mLaunchingProviders.remove(cpr);
18013 return inLaunching;
18017 * Main code for cleaning up a process when it has gone away. This is
18018 * called both as a result of the process dying, or directly when stopping
18019 * a process when running in single process mode.
18021 * @return Returns true if the given process has been restarted, so the
18022 * app that was passed in must remain on the process lists.
18024 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18025 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18027 removeLruProcessLocked(app);
18028 ProcessList.remove(app.pid);
18031 mProcessesToGc.remove(app);
18032 mPendingPssProcesses.remove(app);
18034 // Dismiss any open dialogs.
18035 if (app.crashDialog != null && !app.forceCrashReport) {
18036 app.crashDialog.dismiss();
18037 app.crashDialog = null;
18039 if (app.anrDialog != null) {
18040 app.anrDialog.dismiss();
18041 app.anrDialog = null;
18043 if (app.waitDialog != null) {
18044 app.waitDialog.dismiss();
18045 app.waitDialog = null;
18048 app.crashing = false;
18049 app.notResponding = false;
18051 app.resetPackageList(mProcessStats);
18052 app.unlinkDeathRecipient();
18053 app.makeInactive(mProcessStats);
18054 app.waitingToKill = null;
18055 app.forcingToImportant = null;
18056 updateProcessForegroundLocked(app, false, false);
18057 app.foregroundActivities = false;
18058 app.hasShownUi = false;
18059 app.treatLikeActivity = false;
18060 app.hasAboveClient = false;
18061 app.hasClientActivities = false;
18063 mServices.killServicesLocked(app, allowRestart);
18065 boolean restart = false;
18067 // Remove published content providers.
18068 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18069 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18070 final boolean always = app.bad || !allowRestart;
18071 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18072 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18073 // We left the provider in the launching list, need to
18078 cpr.provider = null;
18081 app.pubProviders.clear();
18083 // Take care of any launching providers waiting for this process.
18084 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18088 // Unregister from connected content providers.
18089 if (!app.conProviders.isEmpty()) {
18090 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18091 ContentProviderConnection conn = app.conProviders.get(i);
18092 conn.provider.connections.remove(conn);
18093 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18094 conn.provider.name);
18096 app.conProviders.clear();
18099 // At this point there may be remaining entries in mLaunchingProviders
18100 // where we were the only one waiting, so they are no longer of use.
18101 // Look for these and clean up if found.
18102 // XXX Commented out for now. Trying to figure out a way to reproduce
18103 // the actual situation to identify what is actually going on.
18105 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18106 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18107 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18108 synchronized (cpr) {
18109 cpr.launchingApp = null;
18116 skipCurrentReceiverLocked(app);
18118 // Unregister any receivers.
18119 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18120 removeReceiverLocked(app.receivers.valueAt(i));
18122 app.receivers.clear();
18124 // If the app is undergoing backup, tell the backup manager about it
18125 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18126 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18127 + mBackupTarget.appInfo + " died during backup");
18128 mHandler.post(new Runnable() {
18132 IBackupManager bm = IBackupManager.Stub.asInterface(
18133 ServiceManager.getService(Context.BACKUP_SERVICE));
18134 bm.agentDisconnected(app.info.packageName);
18135 } catch (RemoteException e) {
18136 // can't happen; backup manager is local
18142 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18143 ProcessChangeItem item = mPendingProcessChanges.get(i);
18144 if (item.pid == app.pid) {
18145 mPendingProcessChanges.remove(i);
18146 mAvailProcessChanges.add(item);
18149 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18150 null).sendToTarget();
18152 // If the caller is restarting this app, then leave it in its
18153 // current lists and let the caller take care of it.
18158 if (!app.persistent || app.isolated) {
18159 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18160 "Removing non-persistent process during cleanup: " + app);
18161 if (!replacingPid) {
18162 removeProcessNameLocked(app.processName, app.uid, app);
18164 if (mHeavyWeightProcess == app) {
18165 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18166 mHeavyWeightProcess.userId, 0));
18167 mHeavyWeightProcess = null;
18169 } else if (!app.removed) {
18170 // This app is persistent, so we need to keep its record around.
18171 // If it is not already on the pending app list, add it there
18172 // and start a new process for it.
18173 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18174 mPersistentStartingProcesses.add(app);
18178 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18179 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18180 mProcessesOnHold.remove(app);
18182 if (app == mHomeProcess) {
18183 mHomeProcess = null;
18185 if (app == mPreviousProcess) {
18186 mPreviousProcess = null;
18189 if (restart && !app.isolated) {
18190 // We have components that still need to be running in the
18191 // process, so re-launch it.
18193 ProcessList.remove(app.pid);
18195 addProcessNameLocked(app);
18196 startProcessLocked(app, "restart", app.processName);
18198 } else if (app.pid > 0 && app.pid != MY_PID) {
18201 synchronized (mPidsSelfLocked) {
18202 mPidsSelfLocked.remove(app.pid);
18203 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18205 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18206 if (app.isolated) {
18207 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18214 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18215 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18216 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18217 if (cpr.launchingApp == app) {
18224 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18225 // Look through the content providers we are waiting to have launched,
18226 // and if any run in this process then either schedule a restart of
18227 // the process or kill the client waiting for it if this process has
18229 boolean restart = false;
18230 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18231 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18232 if (cpr.launchingApp == app) {
18233 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18236 removeDyingProviderLocked(app, cpr, true);
18243 // =========================================================
18245 // =========================================================
18248 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18250 enforceNotIsolatedCaller("getServices");
18252 final int callingUid = Binder.getCallingUid();
18253 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18254 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18255 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18257 synchronized (this) {
18258 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18259 allowed, canInteractAcrossUsers);
18264 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18265 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18266 synchronized (this) {
18267 return mServices.getRunningServiceControlPanelLocked(name);
18272 public ComponentName startService(IApplicationThread caller, Intent service,
18273 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18274 throws TransactionTooLargeException {
18275 enforceNotIsolatedCaller("startService");
18276 // Refuse possible leaked file descriptors
18277 if (service != null && service.hasFileDescriptors() == true) {
18278 throw new IllegalArgumentException("File descriptors passed in Intent");
18281 if (callingPackage == null) {
18282 throw new IllegalArgumentException("callingPackage cannot be null");
18285 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18286 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18287 synchronized(this) {
18288 final int callingPid = Binder.getCallingPid();
18289 final int callingUid = Binder.getCallingUid();
18290 final long origId = Binder.clearCallingIdentity();
18293 res = mServices.startServiceLocked(caller, service,
18294 resolvedType, callingPid, callingUid,
18295 requireForeground, callingPackage, userId);
18297 Binder.restoreCallingIdentity(origId);
18303 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18304 boolean fgRequired, String callingPackage, int userId)
18305 throws TransactionTooLargeException {
18306 synchronized(this) {
18307 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18308 "startServiceInPackage: " + service + " type=" + resolvedType);
18309 final long origId = Binder.clearCallingIdentity();
18312 res = mServices.startServiceLocked(null, service,
18313 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18315 Binder.restoreCallingIdentity(origId);
18322 public int stopService(IApplicationThread caller, Intent service,
18323 String resolvedType, int userId) {
18324 enforceNotIsolatedCaller("stopService");
18325 // Refuse possible leaked file descriptors
18326 if (service != null && service.hasFileDescriptors() == true) {
18327 throw new IllegalArgumentException("File descriptors passed in Intent");
18330 synchronized(this) {
18331 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18336 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18337 enforceNotIsolatedCaller("peekService");
18338 // Refuse possible leaked file descriptors
18339 if (service != null && service.hasFileDescriptors() == true) {
18340 throw new IllegalArgumentException("File descriptors passed in Intent");
18343 if (callingPackage == null) {
18344 throw new IllegalArgumentException("callingPackage cannot be null");
18347 synchronized(this) {
18348 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18353 public boolean stopServiceToken(ComponentName className, IBinder token,
18355 synchronized(this) {
18356 return mServices.stopServiceTokenLocked(className, token, startId);
18361 public void setServiceForeground(ComponentName className, IBinder token,
18362 int id, Notification notification, int flags) {
18363 synchronized(this) {
18364 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18369 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18370 boolean requireFull, String name, String callerPackage) {
18371 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18372 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18375 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18376 String className, int flags) {
18377 boolean result = false;
18378 // For apps that don't have pre-defined UIDs, check for permission
18379 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18380 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18381 if (ActivityManager.checkUidPermission(
18382 INTERACT_ACROSS_USERS,
18383 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18384 ComponentName comp = new ComponentName(aInfo.packageName, className);
18385 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18386 + " requests FLAG_SINGLE_USER, but app does not hold "
18387 + INTERACT_ACROSS_USERS;
18389 throw new SecurityException(msg);
18391 // Permission passed
18394 } else if ("system".equals(componentProcessName)) {
18396 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18397 // Phone app and persistent apps are allowed to export singleuser providers.
18398 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18399 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18401 if (DEBUG_MU) Slog.v(TAG_MU,
18402 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18403 + Integer.toHexString(flags) + ") = " + result);
18408 * Checks to see if the caller is in the same app as the singleton
18409 * component, or the component is in a special app. It allows special apps
18410 * to export singleton components but prevents exporting singleton
18411 * components for regular apps.
18413 boolean isValidSingletonCall(int callingUid, int componentUid) {
18414 int componentAppId = UserHandle.getAppId(componentUid);
18415 return UserHandle.isSameApp(callingUid, componentUid)
18416 || componentAppId == SYSTEM_UID
18417 || componentAppId == PHONE_UID
18418 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18419 == PackageManager.PERMISSION_GRANTED;
18422 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18423 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18424 int userId) throws TransactionTooLargeException {
18425 enforceNotIsolatedCaller("bindService");
18427 // Refuse possible leaked file descriptors
18428 if (service != null && service.hasFileDescriptors() == true) {
18429 throw new IllegalArgumentException("File descriptors passed in Intent");
18432 if (callingPackage == null) {
18433 throw new IllegalArgumentException("callingPackage cannot be null");
18436 synchronized(this) {
18437 return mServices.bindServiceLocked(caller, token, service,
18438 resolvedType, connection, flags, callingPackage, userId);
18442 public boolean unbindService(IServiceConnection connection) {
18443 synchronized (this) {
18444 return mServices.unbindServiceLocked(connection);
18448 public void publishService(IBinder token, Intent intent, IBinder service) {
18449 // Refuse possible leaked file descriptors
18450 if (intent != null && intent.hasFileDescriptors() == true) {
18451 throw new IllegalArgumentException("File descriptors passed in Intent");
18454 synchronized(this) {
18455 if (!(token instanceof ServiceRecord)) {
18456 throw new IllegalArgumentException("Invalid service token");
18458 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18462 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18463 // Refuse possible leaked file descriptors
18464 if (intent != null && intent.hasFileDescriptors() == true) {
18465 throw new IllegalArgumentException("File descriptors passed in Intent");
18468 synchronized(this) {
18469 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18473 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18474 synchronized(this) {
18475 if (!(token instanceof ServiceRecord)) {
18476 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18477 throw new IllegalArgumentException("Invalid service token");
18479 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18483 // =========================================================
18484 // BACKUP AND RESTORE
18485 // =========================================================
18487 // Cause the target app to be launched if necessary and its backup agent
18488 // instantiated. The backup agent will invoke backupAgentCreated() on the
18489 // activity manager to announce its creation.
18490 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18491 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18492 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18494 IPackageManager pm = AppGlobals.getPackageManager();
18495 ApplicationInfo app = null;
18497 app = pm.getApplicationInfo(packageName, 0, userId);
18498 } catch (RemoteException e) {
18499 // can't happen; package manager is process-local
18502 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18509 synchronized(this) {
18510 // !!! TODO: currently no check here that we're already bound
18511 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18512 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18513 synchronized (stats) {
18514 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18517 // Backup agent is now in use, its package can't be stopped.
18519 AppGlobals.getPackageManager().setPackageStoppedState(
18520 app.packageName, false, UserHandle.getUserId(app.uid));
18521 } catch (RemoteException e) {
18522 } catch (IllegalArgumentException e) {
18523 Slog.w(TAG, "Failed trying to unstop package "
18524 + app.packageName + ": " + e);
18527 BackupRecord r = new BackupRecord(ss, app, backupMode);
18528 ComponentName hostingName =
18529 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18530 ? new ComponentName(app.packageName, app.backupAgentName)
18531 : new ComponentName("android", "FullBackupAgent");
18532 // startProcessLocked() returns existing proc's record if it's already running
18533 ProcessRecord proc = startProcessLocked(app.processName, app,
18534 false, 0, "backup", hostingName, false, false, false);
18535 if (proc == null) {
18536 Slog.e(TAG, "Unable to start backup agent process " + r);
18540 // If the app is a regular app (uid >= 10000) and not the system server or phone
18541 // process, etc, then mark it as being in full backup so that certain calls to the
18542 // process can be blocked. This is not reset to false anywhere because we kill the
18543 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18544 if (UserHandle.isApp(app.uid) &&
18545 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18546 proc.inFullBackup = true;
18549 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18550 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18552 mBackupAppName = app.packageName;
18554 // Try not to kill the process during backup
18555 updateOomAdjLocked(proc, true);
18557 // If the process is already attached, schedule the creation of the backup agent now.
18558 // If it is not yet live, this will be done when it attaches to the framework.
18559 if (proc.thread != null) {
18560 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18562 proc.thread.scheduleCreateBackupAgent(app,
18563 compatibilityInfoForPackageLocked(app), backupMode);
18564 } catch (RemoteException e) {
18565 // Will time out on the backup manager side
18568 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18570 // Invariants: at this point, the target app process exists and the application
18571 // is either already running or in the process of coming up. mBackupTarget and
18572 // mBackupAppName describe the app, so that when it binds back to the AM we
18573 // know that it's scheduled for a backup-agent operation.
18576 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18577 if (oldBackupUid != -1) {
18578 js.removeBackingUpUid(oldBackupUid);
18580 if (newBackupUid != -1) {
18581 js.addBackingUpUid(newBackupUid);
18588 public void clearPendingBackup() {
18589 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18590 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18592 synchronized (this) {
18593 mBackupTarget = null;
18594 mBackupAppName = null;
18597 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18598 js.clearAllBackingUpUids();
18601 // A backup agent has just come up
18602 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18603 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18606 synchronized(this) {
18607 if (!agentPackageName.equals(mBackupAppName)) {
18608 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18613 long oldIdent = Binder.clearCallingIdentity();
18615 IBackupManager bm = IBackupManager.Stub.asInterface(
18616 ServiceManager.getService(Context.BACKUP_SERVICE));
18617 bm.agentConnected(agentPackageName, agent);
18618 } catch (RemoteException e) {
18619 // can't happen; the backup manager service is local
18620 } catch (Exception e) {
18621 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18622 e.printStackTrace();
18624 Binder.restoreCallingIdentity(oldIdent);
18628 // done with this agent
18629 public void unbindBackupAgent(ApplicationInfo appInfo) {
18630 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18631 if (appInfo == null) {
18632 Slog.w(TAG, "unbind backup agent for null app");
18638 synchronized(this) {
18640 if (mBackupAppName == null) {
18641 Slog.w(TAG, "Unbinding backup agent with no active backup");
18645 if (!mBackupAppName.equals(appInfo.packageName)) {
18646 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18650 // Not backing this app up any more; reset its OOM adjustment
18651 final ProcessRecord proc = mBackupTarget.app;
18652 updateOomAdjLocked(proc, true);
18653 proc.inFullBackup = false;
18655 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18657 // If the app crashed during backup, 'thread' will be null here
18658 if (proc.thread != null) {
18660 proc.thread.scheduleDestroyBackupAgent(appInfo,
18661 compatibilityInfoForPackageLocked(appInfo));
18662 } catch (Exception e) {
18663 Slog.e(TAG, "Exception when unbinding backup agent:");
18664 e.printStackTrace();
18668 mBackupTarget = null;
18669 mBackupAppName = null;
18673 if (oldBackupUid != -1) {
18674 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18675 js.removeBackingUpUid(oldBackupUid);
18679 // =========================================================
18681 // =========================================================
18683 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18684 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18687 // Easy case -- we have the app's ProcessRecord.
18688 if (record != null) {
18689 return record.info.isInstantApp();
18691 // Otherwise check with PackageManager.
18692 if (callerPackage == null) {
18693 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18694 throw new IllegalArgumentException("Calling application did not provide package name");
18696 mAppOpsService.checkPackage(uid, callerPackage);
18698 IPackageManager pm = AppGlobals.getPackageManager();
18699 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18700 } catch (RemoteException e) {
18701 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18706 boolean isPendingBroadcastProcessLocked(int pid) {
18707 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18708 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18711 void skipPendingBroadcastLocked(int pid) {
18712 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18713 for (BroadcastQueue queue : mBroadcastQueues) {
18714 queue.skipPendingBroadcastLocked(pid);
18718 // The app just attached; send any pending broadcasts that it should receive
18719 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18720 boolean didSomething = false;
18721 for (BroadcastQueue queue : mBroadcastQueues) {
18722 didSomething |= queue.sendPendingBroadcastsLocked(app);
18724 return didSomething;
18727 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18728 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18730 enforceNotIsolatedCaller("registerReceiver");
18731 ArrayList<Intent> stickyIntents = null;
18732 ProcessRecord callerApp = null;
18733 final boolean visibleToInstantApps
18734 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18737 boolean instantApp;
18738 synchronized(this) {
18739 if (caller != null) {
18740 callerApp = getRecordForAppLocked(caller);
18741 if (callerApp == null) {
18742 throw new SecurityException(
18743 "Unable to find app for caller " + caller
18744 + " (pid=" + Binder.getCallingPid()
18745 + ") when registering receiver " + receiver);
18747 if (callerApp.info.uid != SYSTEM_UID &&
18748 !callerApp.pkgList.containsKey(callerPackage) &&
18749 !"android".equals(callerPackage)) {
18750 throw new SecurityException("Given caller package " + callerPackage
18751 + " is not running in process " + callerApp);
18753 callingUid = callerApp.info.uid;
18754 callingPid = callerApp.pid;
18756 callerPackage = null;
18757 callingUid = Binder.getCallingUid();
18758 callingPid = Binder.getCallingPid();
18761 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18762 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18763 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18765 Iterator<String> actions = filter.actionsIterator();
18766 if (actions == null) {
18767 ArrayList<String> noAction = new ArrayList<String>(1);
18768 noAction.add(null);
18769 actions = noAction.iterator();
18772 // Collect stickies of users
18773 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18774 while (actions.hasNext()) {
18775 String action = actions.next();
18776 for (int id : userIds) {
18777 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18778 if (stickies != null) {
18779 ArrayList<Intent> intents = stickies.get(action);
18780 if (intents != null) {
18781 if (stickyIntents == null) {
18782 stickyIntents = new ArrayList<Intent>();
18784 stickyIntents.addAll(intents);
18791 ArrayList<Intent> allSticky = null;
18792 if (stickyIntents != null) {
18793 final ContentResolver resolver = mContext.getContentResolver();
18794 // Look for any matching sticky broadcasts...
18795 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18796 Intent intent = stickyIntents.get(i);
18797 // Don't provided intents that aren't available to instant apps.
18799 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18802 // If intent has scheme "content", it will need to acccess
18803 // provider that needs to lock mProviderMap in ActivityThread
18804 // and also it may need to wait application response, so we
18805 // cannot lock ActivityManagerService here.
18806 if (filter.match(resolver, intent, true, TAG) >= 0) {
18807 if (allSticky == null) {
18808 allSticky = new ArrayList<Intent>();
18810 allSticky.add(intent);
18815 // The first sticky in the list is returned directly back to the client.
18816 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18817 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18818 if (receiver == null) {
18822 synchronized (this) {
18823 if (callerApp != null && (callerApp.thread == null
18824 || callerApp.thread.asBinder() != caller.asBinder())) {
18825 // Original caller already died
18828 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18830 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18832 if (rl.app != null) {
18833 rl.app.receivers.add(rl);
18836 receiver.asBinder().linkToDeath(rl, 0);
18837 } catch (RemoteException e) {
18840 rl.linkedToDeath = true;
18842 mRegisteredReceivers.put(receiver.asBinder(), rl);
18843 } else if (rl.uid != callingUid) {
18844 throw new IllegalArgumentException(
18845 "Receiver requested to register for uid " + callingUid
18846 + " was previously registered for uid " + rl.uid
18847 + " callerPackage is " + callerPackage);
18848 } else if (rl.pid != callingPid) {
18849 throw new IllegalArgumentException(
18850 "Receiver requested to register for pid " + callingPid
18851 + " was previously registered for pid " + rl.pid
18852 + " callerPackage is " + callerPackage);
18853 } else if (rl.userId != userId) {
18854 throw new IllegalArgumentException(
18855 "Receiver requested to register for user " + userId
18856 + " was previously registered for user " + rl.userId
18857 + " callerPackage is " + callerPackage);
18859 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18860 permission, callingUid, userId, instantApp, visibleToInstantApps);
18862 if (!bf.debugCheck()) {
18863 Slog.w(TAG, "==> For Dynamic broadcast");
18865 mReceiverResolver.addFilter(bf);
18867 // Enqueue broadcasts for all existing stickies that match
18869 if (allSticky != null) {
18870 ArrayList receivers = new ArrayList();
18873 final int stickyCount = allSticky.size();
18874 for (int i = 0; i < stickyCount; i++) {
18875 Intent intent = allSticky.get(i);
18876 BroadcastQueue queue = broadcastQueueForIntent(intent);
18877 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18878 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18879 null, 0, null, null, false, true, true, -1);
18880 queue.enqueueParallelBroadcastLocked(r);
18881 queue.scheduleBroadcastsLocked();
18889 public void unregisterReceiver(IIntentReceiver receiver) {
18890 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18892 final long origId = Binder.clearCallingIdentity();
18894 boolean doTrim = false;
18896 synchronized(this) {
18897 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18899 final BroadcastRecord r = rl.curBroadcast;
18900 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18901 final boolean doNext = r.queue.finishReceiverLocked(
18902 r, r.resultCode, r.resultData, r.resultExtras,
18903 r.resultAbort, false);
18906 r.queue.processNextBroadcast(false);
18910 if (rl.app != null) {
18911 rl.app.receivers.remove(rl);
18913 removeReceiverLocked(rl);
18914 if (rl.linkedToDeath) {
18915 rl.linkedToDeath = false;
18916 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18921 // If we actually concluded any broadcasts, we might now be able
18922 // to trim the recipients' apps from our working set
18924 trimApplications();
18929 Binder.restoreCallingIdentity(origId);
18933 void removeReceiverLocked(ReceiverList rl) {
18934 mRegisteredReceivers.remove(rl.receiver.asBinder());
18935 for (int i = rl.size() - 1; i >= 0; i--) {
18936 mReceiverResolver.removeFilter(rl.get(i));
18940 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18941 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18942 ProcessRecord r = mLruProcesses.get(i);
18943 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18945 r.thread.dispatchPackageBroadcast(cmd, packages);
18946 } catch (RemoteException ex) {
18952 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18953 int callingUid, int[] users) {
18954 // TODO: come back and remove this assumption to triage all broadcasts
18955 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18957 List<ResolveInfo> receivers = null;
18959 HashSet<ComponentName> singleUserReceivers = null;
18960 boolean scannedFirstReceivers = false;
18961 for (int user : users) {
18962 // Skip users that have Shell restrictions, with exception of always permitted
18963 // Shell broadcasts
18964 if (callingUid == SHELL_UID
18965 && mUserController.hasUserRestriction(
18966 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18967 && !isPermittedShellBroadcast(intent)) {
18970 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18971 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18972 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18973 // If this is not the system user, we need to check for
18974 // any receivers that should be filtered out.
18975 for (int i=0; i<newReceivers.size(); i++) {
18976 ResolveInfo ri = newReceivers.get(i);
18977 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18978 newReceivers.remove(i);
18983 if (newReceivers != null && newReceivers.size() == 0) {
18984 newReceivers = null;
18986 if (receivers == null) {
18987 receivers = newReceivers;
18988 } else if (newReceivers != null) {
18989 // We need to concatenate the additional receivers
18990 // found with what we have do far. This would be easy,
18991 // but we also need to de-dup any receivers that are
18993 if (!scannedFirstReceivers) {
18994 // Collect any single user receivers we had already retrieved.
18995 scannedFirstReceivers = true;
18996 for (int i=0; i<receivers.size(); i++) {
18997 ResolveInfo ri = receivers.get(i);
18998 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18999 ComponentName cn = new ComponentName(
19000 ri.activityInfo.packageName, ri.activityInfo.name);
19001 if (singleUserReceivers == null) {
19002 singleUserReceivers = new HashSet<ComponentName>();
19004 singleUserReceivers.add(cn);
19008 // Add the new results to the existing results, tracking
19009 // and de-dupping single user receivers.
19010 for (int i=0; i<newReceivers.size(); i++) {
19011 ResolveInfo ri = newReceivers.get(i);
19012 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19013 ComponentName cn = new ComponentName(
19014 ri.activityInfo.packageName, ri.activityInfo.name);
19015 if (singleUserReceivers == null) {
19016 singleUserReceivers = new HashSet<ComponentName>();
19018 if (!singleUserReceivers.contains(cn)) {
19019 singleUserReceivers.add(cn);
19028 } catch (RemoteException ex) {
19029 // pm is in same process, this will never happen.
19034 private boolean isPermittedShellBroadcast(Intent intent) {
19035 // remote bugreport should always be allowed to be taken
19036 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19039 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19040 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19041 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19042 // Don't yell about broadcasts sent via shell
19046 final String action = intent.getAction();
19047 if (isProtectedBroadcast
19048 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19049 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19050 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19051 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19052 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19053 || Intent.ACTION_MASTER_CLEAR.equals(action)
19054 || Intent.ACTION_FACTORY_RESET.equals(action)
19055 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19056 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19057 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19058 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19059 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19060 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19061 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19062 // Broadcast is either protected, or it's a public action that
19063 // we've relaxed, so it's fine for system internals to send.
19067 // This broadcast may be a problem... but there are often system components that
19068 // want to send an internal broadcast to themselves, which is annoying to have to
19069 // explicitly list each action as a protected broadcast, so we will check for that
19070 // one safe case and allow it: an explicit broadcast, only being received by something
19071 // that has protected itself.
19072 if (receivers != null && receivers.size() > 0
19073 && (intent.getPackage() != null || intent.getComponent() != null)) {
19074 boolean allProtected = true;
19075 for (int i = receivers.size()-1; i >= 0; i--) {
19076 Object target = receivers.get(i);
19077 if (target instanceof ResolveInfo) {
19078 ResolveInfo ri = (ResolveInfo)target;
19079 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19080 allProtected = false;
19084 BroadcastFilter bf = (BroadcastFilter)target;
19085 if (bf.requiredPermission == null) {
19086 allProtected = false;
19091 if (allProtected) {
19097 // The vast majority of broadcasts sent from system internals
19098 // should be protected to avoid security holes, so yell loudly
19099 // to ensure we examine these cases.
19100 if (callerApp != null) {
19101 Log.wtf(TAG, "Sending non-protected broadcast " + action
19102 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19105 Log.wtf(TAG, "Sending non-protected broadcast " + action
19106 + " from system uid " + UserHandle.formatUid(callingUid)
19107 + " pkg " + callerPackage,
19112 final int broadcastIntentLocked(ProcessRecord callerApp,
19113 String callerPackage, Intent intent, String resolvedType,
19114 IIntentReceiver resultTo, int resultCode, String resultData,
19115 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19116 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19117 intent = new Intent(intent);
19119 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19120 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19121 if (callerInstantApp) {
19122 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19125 // By default broadcasts do not go to stopped apps.
19126 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19128 // If we have not finished booting, don't allow this to launch new processes.
19129 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19130 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19133 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19134 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19135 + " ordered=" + ordered + " userid=" + userId);
19136 if ((resultTo != null) && !ordered) {
19137 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19140 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19141 ALLOW_NON_FULL, "broadcast", callerPackage);
19143 // Make sure that the user who is receiving this broadcast is running.
19144 // If not, we will just skip it. Make an exception for shutdown broadcasts
19145 // and upgrade steps.
19147 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19148 if ((callingUid != SYSTEM_UID
19149 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19150 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19151 Slog.w(TAG, "Skipping broadcast of " + intent
19152 + ": user " + userId + " is stopped");
19153 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19157 BroadcastOptions brOptions = null;
19158 if (bOptions != null) {
19159 brOptions = new BroadcastOptions(bOptions);
19160 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19161 // See if the caller is allowed to do this. Note we are checking against
19162 // the actual real caller (not whoever provided the operation as say a
19163 // PendingIntent), because that who is actually supplied the arguments.
19164 if (checkComponentPermission(
19165 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19166 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19167 != PackageManager.PERMISSION_GRANTED) {
19168 String msg = "Permission Denial: " + intent.getAction()
19169 + " broadcast from " + callerPackage + " (pid=" + callingPid
19170 + ", uid=" + callingUid + ")"
19172 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19174 throw new SecurityException(msg);
19179 // Verify that protected broadcasts are only being sent by system code,
19180 // and that system code is only sending protected broadcasts.
19181 final String action = intent.getAction();
19182 final boolean isProtectedBroadcast;
19184 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19185 } catch (RemoteException e) {
19186 Slog.w(TAG, "Remote exception", e);
19187 return ActivityManager.BROADCAST_SUCCESS;
19190 final boolean isCallerSystem;
19191 switch (UserHandle.getAppId(callingUid)) {
19195 case BLUETOOTH_UID:
19197 isCallerSystem = true;
19200 isCallerSystem = (callerApp != null) && callerApp.persistent;
19204 // First line security check before anything else: stop non-system apps from
19205 // sending protected broadcasts.
19206 if (!isCallerSystem) {
19207 if (isProtectedBroadcast) {
19208 String msg = "Permission Denial: not allowed to send broadcast "
19209 + action + " from pid="
19210 + callingPid + ", uid=" + callingUid;
19212 throw new SecurityException(msg);
19214 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19215 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19216 // Special case for compatibility: we don't want apps to send this,
19217 // but historically it has not been protected and apps may be using it
19218 // to poke their own app widget. So, instead of making it protected,
19219 // just limit it to the caller.
19220 if (callerPackage == null) {
19221 String msg = "Permission Denial: not allowed to send broadcast "
19222 + action + " from unknown caller.";
19224 throw new SecurityException(msg);
19225 } else if (intent.getComponent() != null) {
19226 // They are good enough to send to an explicit component... verify
19227 // it is being sent to the calling app.
19228 if (!intent.getComponent().getPackageName().equals(
19230 String msg = "Permission Denial: not allowed to send broadcast "
19232 + intent.getComponent().getPackageName() + " from "
19235 throw new SecurityException(msg);
19238 // Limit broadcast to their own package.
19239 intent.setPackage(callerPackage);
19244 if (action != null) {
19245 if (getBackgroundLaunchBroadcasts().contains(action)) {
19246 if (DEBUG_BACKGROUND_CHECK) {
19247 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19249 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19253 case Intent.ACTION_UID_REMOVED:
19254 case Intent.ACTION_PACKAGE_REMOVED:
19255 case Intent.ACTION_PACKAGE_CHANGED:
19256 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19257 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19258 case Intent.ACTION_PACKAGES_SUSPENDED:
19259 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19260 // Handle special intents: if this broadcast is from the package
19261 // manager about a package being removed, we need to remove all of
19262 // its activities from the history stack.
19263 if (checkComponentPermission(
19264 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19265 callingPid, callingUid, -1, true)
19266 != PackageManager.PERMISSION_GRANTED) {
19267 String msg = "Permission Denial: " + intent.getAction()
19268 + " broadcast from " + callerPackage + " (pid=" + callingPid
19269 + ", uid=" + callingUid + ")"
19271 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19273 throw new SecurityException(msg);
19276 case Intent.ACTION_UID_REMOVED:
19277 final int uid = getUidFromIntent(intent);
19279 mBatteryStatsService.removeUid(uid);
19280 mAppOpsService.uidRemoved(uid);
19283 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19284 // If resources are unavailable just force stop all those packages
19285 // and flush the attribute cache as well.
19287 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19288 if (list != null && list.length > 0) {
19289 for (int i = 0; i < list.length; i++) {
19290 forceStopPackageLocked(list[i], -1, false, true, true,
19291 false, false, userId, "storage unmount");
19293 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19294 sendPackageBroadcastLocked(
19295 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19299 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19300 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19302 case Intent.ACTION_PACKAGE_REMOVED:
19303 case Intent.ACTION_PACKAGE_CHANGED:
19304 Uri data = intent.getData();
19306 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19307 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19308 final boolean replacing =
19309 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19310 final boolean killProcess =
19311 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19312 final boolean fullUninstall = removed && !replacing;
19315 forceStopPackageLocked(ssp, UserHandle.getAppId(
19316 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19317 false, true, true, false, fullUninstall, userId,
19318 removed ? "pkg removed" : "pkg changed");
19320 final int cmd = killProcess
19321 ? ApplicationThreadConstants.PACKAGE_REMOVED
19322 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19323 sendPackageBroadcastLocked(cmd,
19324 new String[] {ssp}, userId);
19325 if (fullUninstall) {
19326 mAppOpsService.packageRemoved(
19327 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19329 // Remove all permissions granted from/to this package
19330 removeUriPermissionsForPackageLocked(ssp, userId, true);
19332 removeTasksByPackageNameLocked(ssp, userId);
19334 mServices.forceStopPackageLocked(ssp, userId);
19336 // Hide the "unsupported display" dialog if necessary.
19337 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19338 mUnsupportedDisplaySizeDialog.getPackageName())) {
19339 mUnsupportedDisplaySizeDialog.dismiss();
19340 mUnsupportedDisplaySizeDialog = null;
19342 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19343 mBatteryStatsService.notePackageUninstalled(ssp);
19347 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19348 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19349 userId, ProcessList.INVALID_ADJ,
19350 false, true, true, false, "change " + ssp);
19352 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19353 intent.getStringArrayExtra(
19354 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19358 case Intent.ACTION_PACKAGES_SUSPENDED:
19359 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19360 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19361 intent.getAction());
19362 final String[] packageNames = intent.getStringArrayExtra(
19363 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19364 final int userHandle = intent.getIntExtra(
19365 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19367 synchronized(ActivityManagerService.this) {
19368 mRecentTasks.onPackagesSuspendedChanged(
19369 packageNames, suspended, userHandle);
19374 case Intent.ACTION_PACKAGE_REPLACED:
19376 final Uri data = intent.getData();
19378 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19379 ApplicationInfo aInfo = null;
19381 aInfo = AppGlobals.getPackageManager()
19382 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19383 } catch (RemoteException ignore) {}
19384 if (aInfo == null) {
19385 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19386 + " ssp=" + ssp + " data=" + data);
19387 return ActivityManager.BROADCAST_SUCCESS;
19389 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19390 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19391 new String[] {ssp}, userId);
19395 case Intent.ACTION_PACKAGE_ADDED:
19397 // Special case for adding a package: by default turn on compatibility mode.
19398 Uri data = intent.getData();
19400 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19401 final boolean replacing =
19402 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19403 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19406 ApplicationInfo ai = AppGlobals.getPackageManager().
19407 getApplicationInfo(ssp, 0, 0);
19408 mBatteryStatsService.notePackageInstalled(ssp,
19409 ai != null ? ai.versionCode : 0);
19410 } catch (RemoteException e) {
19415 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19417 Uri data = intent.getData();
19419 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19420 // Hide the "unsupported display" dialog if necessary.
19421 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19422 mUnsupportedDisplaySizeDialog.getPackageName())) {
19423 mUnsupportedDisplaySizeDialog.dismiss();
19424 mUnsupportedDisplaySizeDialog = null;
19426 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19430 case Intent.ACTION_TIMEZONE_CHANGED:
19431 // If this is the time zone changed action, queue up a message that will reset
19432 // the timezone of all currently running processes. This message will get
19433 // queued up before the broadcast happens.
19434 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19436 case Intent.ACTION_TIME_CHANGED:
19437 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19438 // the tri-state value it may contain and "unknown".
19439 // For convenience we re-use the Intent extra values.
19440 final int NO_EXTRA_VALUE_FOUND = -1;
19441 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19442 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19443 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19444 // Only send a message if the time preference is available.
19445 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19446 Message updateTimePreferenceMsg =
19447 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19448 timeFormatPreferenceMsgValue, 0);
19449 mHandler.sendMessage(updateTimePreferenceMsg);
19451 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19452 synchronized (stats) {
19453 stats.noteCurrentTimeChangedLocked();
19456 case Intent.ACTION_CLEAR_DNS_CACHE:
19457 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19459 case Proxy.PROXY_CHANGE_ACTION:
19460 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19461 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19463 case android.hardware.Camera.ACTION_NEW_PICTURE:
19464 case android.hardware.Camera.ACTION_NEW_VIDEO:
19465 // In N we just turned these off; in O we are turing them back on partly,
19466 // only for registered receivers. This will still address the main problem
19467 // (a spam of apps waking up when a picture is taken putting significant
19468 // memory pressure on the system at a bad point), while still allowing apps
19469 // that are already actively running to know about this happening.
19470 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19472 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19473 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19475 case "com.android.launcher.action.INSTALL_SHORTCUT":
19476 // As of O, we no longer support this broadcasts, even for pre-O apps.
19477 // Apps should now be using ShortcutManager.pinRequestShortcut().
19478 Log.w(TAG, "Broadcast " + action
19479 + " no longer supported. It will not be delivered.");
19480 return ActivityManager.BROADCAST_SUCCESS;
19483 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19484 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19485 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19486 final int uid = getUidFromIntent(intent);
19488 final UidRecord uidRec = mActiveUids.get(uid);
19489 if (uidRec != null) {
19490 uidRec.updateHasInternetPermission();
19496 // Add to the sticky list if requested.
19498 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19499 callingPid, callingUid)
19500 != PackageManager.PERMISSION_GRANTED) {
19501 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19502 + callingPid + ", uid=" + callingUid
19503 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19505 throw new SecurityException(msg);
19507 if (requiredPermissions != null && requiredPermissions.length > 0) {
19508 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19509 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19510 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19512 if (intent.getComponent() != null) {
19513 throw new SecurityException(
19514 "Sticky broadcasts can't target a specific component");
19516 // We use userId directly here, since the "all" target is maintained
19517 // as a separate set of sticky broadcasts.
19518 if (userId != UserHandle.USER_ALL) {
19519 // But first, if this is not a broadcast to all users, then
19520 // make sure it doesn't conflict with an existing broadcast to
19522 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19523 UserHandle.USER_ALL);
19524 if (stickies != null) {
19525 ArrayList<Intent> list = stickies.get(intent.getAction());
19526 if (list != null) {
19527 int N = list.size();
19529 for (i=0; i<N; i++) {
19530 if (intent.filterEquals(list.get(i))) {
19531 throw new IllegalArgumentException(
19532 "Sticky broadcast " + intent + " for user "
19533 + userId + " conflicts with existing global broadcast");
19539 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19540 if (stickies == null) {
19541 stickies = new ArrayMap<>();
19542 mStickyBroadcasts.put(userId, stickies);
19544 ArrayList<Intent> list = stickies.get(intent.getAction());
19545 if (list == null) {
19546 list = new ArrayList<>();
19547 stickies.put(intent.getAction(), list);
19549 final int stickiesCount = list.size();
19551 for (i = 0; i < stickiesCount; i++) {
19552 if (intent.filterEquals(list.get(i))) {
19553 // This sticky already exists, replace it.
19554 list.set(i, new Intent(intent));
19558 if (i >= stickiesCount) {
19559 list.add(new Intent(intent));
19564 if (userId == UserHandle.USER_ALL) {
19565 // Caller wants broadcast to go to all started users.
19566 users = mUserController.getStartedUserArrayLocked();
19568 // Caller wants broadcast to go to one specific user.
19569 users = new int[] {userId};
19572 // Figure out who all will receive this broadcast.
19573 List receivers = null;
19574 List<BroadcastFilter> registeredReceivers = null;
19575 // Need to resolve the intent to interested receivers...
19576 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19578 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19580 if (intent.getComponent() == null) {
19581 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19582 // Query one target user at a time, excluding shell-restricted users
19583 for (int i = 0; i < users.length; i++) {
19584 if (mUserController.hasUserRestriction(
19585 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19588 List<BroadcastFilter> registeredReceiversForUser =
19589 mReceiverResolver.queryIntent(intent,
19590 resolvedType, false /*defaultOnly*/, users[i]);
19591 if (registeredReceivers == null) {
19592 registeredReceivers = registeredReceiversForUser;
19593 } else if (registeredReceiversForUser != null) {
19594 registeredReceivers.addAll(registeredReceiversForUser);
19598 registeredReceivers = mReceiverResolver.queryIntent(intent,
19599 resolvedType, false /*defaultOnly*/, userId);
19603 final boolean replacePending =
19604 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19606 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19607 + " replacePending=" + replacePending);
19609 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19610 if (!ordered && NR > 0) {
19611 // If we are not serializing this broadcast, then send the
19612 // registered receivers separately so they don't wait for the
19613 // components to be launched.
19614 if (isCallerSystem) {
19615 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19616 isProtectedBroadcast, registeredReceivers);
19618 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19619 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19620 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19621 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19622 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19623 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19624 final boolean replaced = replacePending
19625 && (queue.replaceParallelBroadcastLocked(r) != null);
19626 // Note: We assume resultTo is null for non-ordered broadcasts.
19628 queue.enqueueParallelBroadcastLocked(r);
19629 queue.scheduleBroadcastsLocked();
19631 registeredReceivers = null;
19635 // Merge into one list.
19637 if (receivers != null) {
19638 // A special case for PACKAGE_ADDED: do not allow the package
19639 // being added to see this broadcast. This prevents them from
19640 // using this as a back door to get run as soon as they are
19641 // installed. Maybe in the future we want to have a special install
19642 // broadcast or such for apps, but we'd like to deliberately make
19644 String skipPackages[] = null;
19645 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19646 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19647 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19648 Uri data = intent.getData();
19649 if (data != null) {
19650 String pkgName = data.getSchemeSpecificPart();
19651 if (pkgName != null) {
19652 skipPackages = new String[] { pkgName };
19655 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19656 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19658 if (skipPackages != null && (skipPackages.length > 0)) {
19659 for (String skipPackage : skipPackages) {
19660 if (skipPackage != null) {
19661 int NT = receivers.size();
19662 for (int it=0; it<NT; it++) {
19663 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19664 if (curt.activityInfo.packageName.equals(skipPackage)) {
19665 receivers.remove(it);
19674 int NT = receivers != null ? receivers.size() : 0;
19676 ResolveInfo curt = null;
19677 BroadcastFilter curr = null;
19678 while (it < NT && ir < NR) {
19679 if (curt == null) {
19680 curt = (ResolveInfo)receivers.get(it);
19682 if (curr == null) {
19683 curr = registeredReceivers.get(ir);
19685 if (curr.getPriority() >= curt.priority) {
19686 // Insert this broadcast record into the final list.
19687 receivers.add(it, curr);
19693 // Skip to the next ResolveInfo in the final list.
19700 if (receivers == null) {
19701 receivers = new ArrayList();
19703 receivers.add(registeredReceivers.get(ir));
19707 if (isCallerSystem) {
19708 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19709 isProtectedBroadcast, receivers);
19712 if ((receivers != null && receivers.size() > 0)
19713 || resultTo != null) {
19714 BroadcastQueue queue = broadcastQueueForIntent(intent);
19715 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19716 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19717 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19718 resultData, resultExtras, ordered, sticky, false, userId);
19720 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19721 + ": prev had " + queue.mOrderedBroadcasts.size());
19722 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19723 "Enqueueing broadcast " + r.intent.getAction());
19725 final BroadcastRecord oldRecord =
19726 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19727 if (oldRecord != null) {
19728 // Replaced, fire the result-to receiver.
19729 if (oldRecord.resultTo != null) {
19730 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19732 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19734 Activity.RESULT_CANCELED, null, null,
19735 false, false, oldRecord.userId);
19736 } catch (RemoteException e) {
19737 Slog.w(TAG, "Failure ["
19738 + queue.mQueueName + "] sending broadcast result of "
19744 queue.enqueueOrderedBroadcastLocked(r);
19745 queue.scheduleBroadcastsLocked();
19748 // There was nobody interested in the broadcast, but we still want to record
19749 // that it happened.
19750 if (intent.getComponent() == null && intent.getPackage() == null
19751 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19752 // This was an implicit broadcast... let's record it for posterity.
19753 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19757 return ActivityManager.BROADCAST_SUCCESS;
19761 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19763 private int getUidFromIntent(Intent intent) {
19764 if (intent == null) {
19767 final Bundle intentExtras = intent.getExtras();
19768 return intent.hasExtra(Intent.EXTRA_UID)
19769 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19772 final void rotateBroadcastStatsIfNeededLocked() {
19773 final long now = SystemClock.elapsedRealtime();
19774 if (mCurBroadcastStats == null ||
19775 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19776 mLastBroadcastStats = mCurBroadcastStats;
19777 if (mLastBroadcastStats != null) {
19778 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19779 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19781 mCurBroadcastStats = new BroadcastStats();
19785 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19786 int skipCount, long dispatchTime) {
19787 rotateBroadcastStatsIfNeededLocked();
19788 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19791 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19792 rotateBroadcastStatsIfNeededLocked();
19793 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19796 final Intent verifyBroadcastLocked(Intent intent) {
19797 // Refuse possible leaked file descriptors
19798 if (intent != null && intent.hasFileDescriptors() == true) {
19799 throw new IllegalArgumentException("File descriptors passed in Intent");
19802 int flags = intent.getFlags();
19804 if (!mProcessesReady) {
19805 // if the caller really truly claims to know what they're doing, go
19806 // ahead and allow the broadcast without launching any receivers
19807 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19808 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19809 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19810 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19811 + " before boot completion");
19812 throw new IllegalStateException("Cannot broadcast before boot completed");
19816 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19817 throw new IllegalArgumentException(
19818 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19821 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19822 switch (Binder.getCallingUid()) {
19827 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19828 + Binder.getCallingUid());
19829 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19837 public final int broadcastIntent(IApplicationThread caller,
19838 Intent intent, String resolvedType, IIntentReceiver resultTo,
19839 int resultCode, String resultData, Bundle resultExtras,
19840 String[] requiredPermissions, int appOp, Bundle bOptions,
19841 boolean serialized, boolean sticky, int userId) {
19842 enforceNotIsolatedCaller("broadcastIntent");
19843 synchronized(this) {
19844 intent = verifyBroadcastLocked(intent);
19846 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19847 final int callingPid = Binder.getCallingPid();
19848 final int callingUid = Binder.getCallingUid();
19849 final long origId = Binder.clearCallingIdentity();
19850 int res = broadcastIntentLocked(callerApp,
19851 callerApp != null ? callerApp.info.packageName : null,
19852 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19853 requiredPermissions, appOp, bOptions, serialized, sticky,
19854 callingPid, callingUid, userId);
19855 Binder.restoreCallingIdentity(origId);
19861 int broadcastIntentInPackage(String packageName, int uid,
19862 Intent intent, String resolvedType, IIntentReceiver resultTo,
19863 int resultCode, String resultData, Bundle resultExtras,
19864 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19866 synchronized(this) {
19867 intent = verifyBroadcastLocked(intent);
19869 final long origId = Binder.clearCallingIdentity();
19870 String[] requiredPermissions = requiredPermission == null ? null
19871 : new String[] {requiredPermission};
19872 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19873 resultTo, resultCode, resultData, resultExtras,
19874 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19875 sticky, -1, uid, userId);
19876 Binder.restoreCallingIdentity(origId);
19881 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19882 // Refuse possible leaked file descriptors
19883 if (intent != null && intent.hasFileDescriptors() == true) {
19884 throw new IllegalArgumentException("File descriptors passed in Intent");
19887 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19888 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19890 synchronized(this) {
19891 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19892 != PackageManager.PERMISSION_GRANTED) {
19893 String msg = "Permission Denial: unbroadcastIntent() from pid="
19894 + Binder.getCallingPid()
19895 + ", uid=" + Binder.getCallingUid()
19896 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19898 throw new SecurityException(msg);
19900 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19901 if (stickies != null) {
19902 ArrayList<Intent> list = stickies.get(intent.getAction());
19903 if (list != null) {
19904 int N = list.size();
19906 for (i=0; i<N; i++) {
19907 if (intent.filterEquals(list.get(i))) {
19912 if (list.size() <= 0) {
19913 stickies.remove(intent.getAction());
19916 if (stickies.size() <= 0) {
19917 mStickyBroadcasts.remove(userId);
19923 void backgroundServicesFinishedLocked(int userId) {
19924 for (BroadcastQueue queue : mBroadcastQueues) {
19925 queue.backgroundServicesFinishedLocked(userId);
19929 public void finishReceiver(IBinder who, int resultCode, String resultData,
19930 Bundle resultExtras, boolean resultAbort, int flags) {
19931 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19933 // Refuse possible leaked file descriptors
19934 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19935 throw new IllegalArgumentException("File descriptors passed in Bundle");
19938 final long origId = Binder.clearCallingIdentity();
19940 boolean doNext = false;
19943 synchronized(this) {
19944 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19945 ? mFgBroadcastQueue : mBgBroadcastQueue;
19946 r = queue.getMatchingOrderedReceiver(who);
19948 doNext = r.queue.finishReceiverLocked(r, resultCode,
19949 resultData, resultExtras, resultAbort, true);
19954 r.queue.processNextBroadcast(false);
19956 trimApplications();
19958 Binder.restoreCallingIdentity(origId);
19962 // =========================================================
19964 // =========================================================
19966 public boolean startInstrumentation(ComponentName className,
19967 String profileFile, int flags, Bundle arguments,
19968 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19969 int userId, String abiOverride) {
19970 enforceNotIsolatedCaller("startInstrumentation");
19971 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19972 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19973 // Refuse possible leaked file descriptors
19974 if (arguments != null && arguments.hasFileDescriptors()) {
19975 throw new IllegalArgumentException("File descriptors passed in Bundle");
19978 synchronized(this) {
19979 InstrumentationInfo ii = null;
19980 ApplicationInfo ai = null;
19982 ii = mContext.getPackageManager().getInstrumentationInfo(
19983 className, STOCK_PM_FLAGS);
19984 ai = AppGlobals.getPackageManager().getApplicationInfo(
19985 ii.targetPackage, STOCK_PM_FLAGS, userId);
19986 } catch (PackageManager.NameNotFoundException e) {
19987 } catch (RemoteException e) {
19990 reportStartInstrumentationFailureLocked(watcher, className,
19991 "Unable to find instrumentation info for: " + className);
19995 reportStartInstrumentationFailureLocked(watcher, className,
19996 "Unable to find instrumentation target package: " + ii.targetPackage);
19999 if (!ai.hasCode()) {
20000 reportStartInstrumentationFailureLocked(watcher, className,
20001 "Instrumentation target has no code: " + ii.targetPackage);
20005 int match = mContext.getPackageManager().checkSignatures(
20006 ii.targetPackage, ii.packageName);
20007 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20008 String msg = "Permission Denial: starting instrumentation "
20009 + className + " from pid="
20010 + Binder.getCallingPid()
20011 + ", uid=" + Binder.getCallingPid()
20012 + " not allowed because package " + ii.packageName
20013 + " does not have a signature matching the target "
20014 + ii.targetPackage;
20015 reportStartInstrumentationFailureLocked(watcher, className, msg);
20016 throw new SecurityException(msg);
20019 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20020 activeInstr.mClass = className;
20021 String defProcess = ai.processName;;
20022 if (ii.targetProcesses == null) {
20023 activeInstr.mTargetProcesses = new String[]{ai.processName};
20024 } else if (ii.targetProcesses.equals("*")) {
20025 activeInstr.mTargetProcesses = new String[0];
20027 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20028 defProcess = activeInstr.mTargetProcesses[0];
20030 activeInstr.mTargetInfo = ai;
20031 activeInstr.mProfileFile = profileFile;
20032 activeInstr.mArguments = arguments;
20033 activeInstr.mWatcher = watcher;
20034 activeInstr.mUiAutomationConnection = uiAutomationConnection;
20035 activeInstr.mResultClass = className;
20037 final long origId = Binder.clearCallingIdentity();
20038 // Instrumentation can kill and relaunch even persistent processes
20039 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20041 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20042 app.instr = activeInstr;
20043 activeInstr.mFinished = false;
20044 activeInstr.mRunningProcesses.add(app);
20045 if (!mActiveInstrumentation.contains(activeInstr)) {
20046 mActiveInstrumentation.add(activeInstr);
20048 Binder.restoreCallingIdentity(origId);
20055 * Report errors that occur while attempting to start Instrumentation. Always writes the
20056 * error to the logs, but if somebody is watching, send the report there too. This enables
20057 * the "am" command to report errors with more information.
20059 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
20060 * @param cn The component name of the instrumentation.
20061 * @param report The error report.
20063 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20064 ComponentName cn, String report) {
20065 Slog.w(TAG, report);
20066 if (watcher != null) {
20067 Bundle results = new Bundle();
20068 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20069 results.putString("Error", report);
20070 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20074 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20075 if (app.instr == null) {
20076 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20080 if (!app.instr.mFinished && results != null) {
20081 if (app.instr.mCurResults == null) {
20082 app.instr.mCurResults = new Bundle(results);
20084 app.instr.mCurResults.putAll(results);
20089 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20090 int userId = UserHandle.getCallingUserId();
20091 // Refuse possible leaked file descriptors
20092 if (results != null && results.hasFileDescriptors()) {
20093 throw new IllegalArgumentException("File descriptors passed in Intent");
20096 synchronized(this) {
20097 ProcessRecord app = getRecordForAppLocked(target);
20099 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20102 final long origId = Binder.clearCallingIdentity();
20103 addInstrumentationResultsLocked(app, results);
20104 Binder.restoreCallingIdentity(origId);
20108 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20109 if (app.instr == null) {
20110 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20114 if (!app.instr.mFinished) {
20115 if (app.instr.mWatcher != null) {
20116 Bundle finalResults = app.instr.mCurResults;
20117 if (finalResults != null) {
20118 if (app.instr.mCurResults != null && results != null) {
20119 finalResults.putAll(results);
20122 finalResults = results;
20124 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20125 app.instr.mClass, resultCode, finalResults);
20128 // Can't call out of the system process with a lock held, so post a message.
20129 if (app.instr.mUiAutomationConnection != null) {
20130 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20131 app.instr.mUiAutomationConnection).sendToTarget();
20133 app.instr.mFinished = true;
20136 app.instr.removeProcess(app);
20139 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20143 public void finishInstrumentation(IApplicationThread target,
20144 int resultCode, Bundle results) {
20145 int userId = UserHandle.getCallingUserId();
20146 // Refuse possible leaked file descriptors
20147 if (results != null && results.hasFileDescriptors()) {
20148 throw new IllegalArgumentException("File descriptors passed in Intent");
20151 synchronized(this) {
20152 ProcessRecord app = getRecordForAppLocked(target);
20154 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20157 final long origId = Binder.clearCallingIdentity();
20158 finishInstrumentationLocked(app, resultCode, results);
20159 Binder.restoreCallingIdentity(origId);
20163 // =========================================================
20165 // =========================================================
20167 public ConfigurationInfo getDeviceConfigurationInfo() {
20168 ConfigurationInfo config = new ConfigurationInfo();
20169 synchronized (this) {
20170 final Configuration globalConfig = getGlobalConfiguration();
20171 config.reqTouchScreen = globalConfig.touchscreen;
20172 config.reqKeyboardType = globalConfig.keyboard;
20173 config.reqNavigation = globalConfig.navigation;
20174 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20175 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20176 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20178 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20179 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20180 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20182 config.reqGlEsVersion = GL_ES_VERSION;
20187 ActivityStack getFocusedStack() {
20188 return mStackSupervisor.getFocusedStack();
20192 public int getFocusedStackId() throws RemoteException {
20193 ActivityStack focusedStack = getFocusedStack();
20194 if (focusedStack != null) {
20195 return focusedStack.getStackId();
20200 public Configuration getConfiguration() {
20202 synchronized(this) {
20203 ci = new Configuration(getGlobalConfiguration());
20204 ci.userSetLocale = false;
20210 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20211 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20212 synchronized (this) {
20213 mSuppressResizeConfigChanges = suppress;
20218 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20219 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20220 * activity and clearing the task at the same time.
20223 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20224 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20225 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20226 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20228 synchronized (this) {
20229 final long origId = Binder.clearCallingIdentity();
20231 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20233 Binder.restoreCallingIdentity(origId);
20239 public void updatePersistentConfiguration(Configuration values) {
20240 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20241 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20242 if (values == null) {
20243 throw new NullPointerException("Configuration must not be null");
20246 int userId = UserHandle.getCallingUserId();
20248 synchronized(this) {
20249 updatePersistentConfigurationLocked(values, userId);
20253 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20254 final long origId = Binder.clearCallingIdentity();
20256 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20258 Binder.restoreCallingIdentity(origId);
20262 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20263 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20264 FONT_SCALE, 1.0f, userId);
20266 synchronized (this) {
20267 if (getGlobalConfiguration().fontScale == scaleFactor) {
20271 final Configuration configuration
20272 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20273 configuration.fontScale = scaleFactor;
20274 updatePersistentConfigurationLocked(configuration, userId);
20278 private void enforceWriteSettingsPermission(String func) {
20279 int uid = Binder.getCallingUid();
20280 if (uid == ROOT_UID) {
20284 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20285 Settings.getPackageNameForUid(mContext, uid), false)) {
20289 String msg = "Permission Denial: " + func + " from pid="
20290 + Binder.getCallingPid()
20292 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20294 throw new SecurityException(msg);
20298 public boolean updateConfiguration(Configuration values) {
20299 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20301 synchronized(this) {
20302 if (values == null && mWindowManager != null) {
20303 // sentinel: fetch the current configuration from the window manager
20304 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20307 if (mWindowManager != null) {
20308 // Update OOM levels based on display size.
20309 mProcessList.applyDisplaySize(mWindowManager);
20312 final long origId = Binder.clearCallingIdentity();
20314 if (values != null) {
20315 Settings.System.clearConfiguration(values);
20317 updateConfigurationLocked(values, null, false, false /* persistent */,
20318 UserHandle.USER_NULL, false /* deferResume */,
20319 mTmpUpdateConfigurationResult);
20320 return mTmpUpdateConfigurationResult.changes != 0;
20322 Binder.restoreCallingIdentity(origId);
20327 void updateUserConfigurationLocked() {
20328 final Configuration configuration = new Configuration(getGlobalConfiguration());
20329 final int currentUserId = mUserController.getCurrentUserIdLocked();
20330 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20331 currentUserId, Settings.System.canWrite(mContext));
20332 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20333 false /* persistent */, currentUserId, false /* deferResume */);
20336 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20337 boolean initLocale) {
20338 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20341 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20342 boolean initLocale, boolean deferResume) {
20343 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20344 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20345 UserHandle.USER_NULL, deferResume);
20348 // To cache the list of supported system locales
20349 private String[] mSupportedSystemLocales = null;
20351 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20352 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20353 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20354 deferResume, null /* result */);
20358 * Do either or both things: (1) change the current configuration, and (2)
20359 * make sure the given activity is running with the (now) current
20360 * configuration. Returns true if the activity has been left running, or
20361 * false if <var>starting</var> is being destroyed to match the new
20364 * @param userId is only used when persistent parameter is set to true to persist configuration
20365 * for that particular user
20367 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20368 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20369 UpdateConfigurationResult result) {
20371 boolean kept = true;
20373 if (mWindowManager != null) {
20374 mWindowManager.deferSurfaceLayout();
20377 if (values != null) {
20378 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20382 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20384 if (mWindowManager != null) {
20385 mWindowManager.continueSurfaceLayout();
20389 if (result != null) {
20390 result.changes = changes;
20391 result.activityRelaunched = !kept;
20396 /** Update default (global) configuration and notify listeners about changes. */
20397 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20398 boolean persistent, int userId, boolean deferResume) {
20399 mTempConfig.setTo(getGlobalConfiguration());
20400 final int changes = mTempConfig.updateFrom(values);
20401 if (changes == 0) {
20402 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20403 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20404 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20405 // (even if there are no actual changes) to unfreeze the window.
20406 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20410 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20411 "Updating global configuration to: " + values);
20413 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20415 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20416 final LocaleList locales = values.getLocales();
20417 int bestLocaleIndex = 0;
20418 if (locales.size() > 1) {
20419 if (mSupportedSystemLocales == null) {
20420 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20422 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20424 SystemProperties.set("persist.sys.locale",
20425 locales.get(bestLocaleIndex).toLanguageTag());
20426 LocaleList.setDefault(locales, bestLocaleIndex);
20427 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20428 locales.get(bestLocaleIndex)));
20431 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20432 mTempConfig.seq = mConfigurationSeq;
20434 // Update stored global config and notify everyone about the change.
20435 mStackSupervisor.onConfigurationChanged(mTempConfig);
20437 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20438 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20439 mUsageStatsService.reportConfigurationChange(mTempConfig,
20440 mUserController.getCurrentUserIdLocked());
20442 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20443 mShowDialogs = shouldShowDialogs(mTempConfig);
20445 AttributeCache ac = AttributeCache.instance();
20447 ac.updateConfiguration(mTempConfig);
20450 // Make sure all resources in our process are updated right now, so that anyone who is going
20451 // to retrieve resource values after we return will be sure to get the new ones. This is
20452 // especially important during boot, where the first config change needs to guarantee all
20453 // resources have that config before following boot code is executed.
20454 mSystemThread.applyConfigurationToResources(mTempConfig);
20456 // We need another copy of global config because we're scheduling some calls instead of
20457 // running them in place. We need to be sure that object we send will be handled unchanged.
20458 final Configuration configCopy = new Configuration(mTempConfig);
20459 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20460 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20461 msg.obj = configCopy;
20463 mHandler.sendMessage(msg);
20466 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20467 ProcessRecord app = mLruProcesses.get(i);
20469 if (app.thread != null) {
20470 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20471 + app.processName + " new config " + configCopy);
20472 app.thread.scheduleConfigurationChanged(configCopy);
20474 } catch (Exception e) {
20478 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20479 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20480 | Intent.FLAG_RECEIVER_FOREGROUND
20481 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20482 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20483 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20484 UserHandle.USER_ALL);
20485 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20486 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20487 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20488 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20489 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20490 if (initLocale || !mProcessesReady) {
20491 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20493 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20494 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20495 UserHandle.USER_ALL);
20498 // Override configuration of the default display duplicates global config, so we need to
20499 // update it also. This will also notify WindowManager about changes.
20500 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20507 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20508 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20510 synchronized (this) {
20511 // Check if display is initialized in AM.
20512 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20513 // Call might come when display is not yet added or has already been removed.
20514 if (DEBUG_CONFIGURATION) {
20515 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20521 if (values == null && mWindowManager != null) {
20522 // sentinel: fetch the current configuration from the window manager
20523 values = mWindowManager.computeNewConfiguration(displayId);
20526 if (mWindowManager != null) {
20527 // Update OOM levels based on display size.
20528 mProcessList.applyDisplaySize(mWindowManager);
20531 final long origId = Binder.clearCallingIdentity();
20533 if (values != null) {
20534 Settings.System.clearConfiguration(values);
20536 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20537 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20538 return mTmpUpdateConfigurationResult.changes != 0;
20540 Binder.restoreCallingIdentity(origId);
20545 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20546 boolean deferResume, int displayId) {
20547 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20548 displayId, null /* result */);
20552 * Updates override configuration specific for the selected display. If no config is provided,
20553 * new one will be computed in WM based on current display info.
20555 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20556 ActivityRecord starting, boolean deferResume, int displayId,
20557 UpdateConfigurationResult result) {
20559 boolean kept = true;
20561 if (mWindowManager != null) {
20562 mWindowManager.deferSurfaceLayout();
20565 if (values != null) {
20566 if (displayId == DEFAULT_DISPLAY) {
20567 // Override configuration of the default display duplicates global config, so
20568 // we're calling global config update instead for default display. It will also
20569 // apply the correct override config.
20570 changes = updateGlobalConfiguration(values, false /* initLocale */,
20571 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20573 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20577 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20579 if (mWindowManager != null) {
20580 mWindowManager.continueSurfaceLayout();
20584 if (result != null) {
20585 result.changes = changes;
20586 result.activityRelaunched = !kept;
20591 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20593 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20594 final int changes = mTempConfig.updateFrom(values);
20595 if (changes != 0) {
20596 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20597 + mTempConfig + " for displayId=" + displayId);
20598 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20600 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20601 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20602 // Reset the unsupported display size dialog.
20603 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20605 killAllBackgroundProcessesExcept(N,
20606 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20610 // Update the configuration with WM first and check if any of the stacks need to be resized
20611 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20612 // necessary. This way we don't need to relaunch again afterwards in
20613 // ensureActivityConfigurationLocked().
20614 if (mWindowManager != null) {
20615 final int[] resizedStacks =
20616 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20617 if (resizedStacks != null) {
20618 for (int stackId : resizedStacks) {
20619 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20627 /** Applies latest configuration and/or visibility updates if needed. */
20628 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20629 boolean kept = true;
20630 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20631 // mainStack is null during startup.
20632 if (mainStack != null) {
20633 if (changes != 0 && starting == null) {
20634 // If the configuration changed, and the caller is not already
20635 // in the process of starting an activity, then find the top
20636 // activity to check if its configuration needs to change.
20637 starting = mainStack.topRunningActivityLocked();
20640 if (starting != null) {
20641 kept = starting.ensureActivityConfigurationLocked(changes,
20642 false /* preserveWindow */);
20643 // And we need to make sure at this point that all other activities
20644 // are made visible with the correct configuration.
20645 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20646 !PRESERVE_WINDOWS);
20653 /** Helper method that requests bounds from WM and applies them to stack. */
20654 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20655 final Rect newStackBounds = new Rect();
20656 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20657 mStackSupervisor.resizeStackLocked(
20658 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20659 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20660 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20664 * Decide based on the configuration whether we should show the ANR,
20665 * crash, etc dialogs. The idea is that if there is no affordance to
20666 * press the on-screen buttons, or the user experience would be more
20667 * greatly impacted than the crash itself, we shouldn't show the dialog.
20669 * A thought: SystemUI might also want to get told about this, the Power
20670 * dialog / global actions also might want different behaviors.
20672 private static boolean shouldShowDialogs(Configuration config) {
20673 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20674 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20675 && config.navigation == Configuration.NAVIGATION_NONAV);
20676 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20677 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20678 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20679 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20680 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20681 return inputMethodExists && uiModeSupportsDialogs;
20685 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20686 synchronized (this) {
20687 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20688 if (srec != null) {
20689 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20695 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20696 Intent resultData) {
20698 synchronized (this) {
20699 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20701 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20707 public int getLaunchedFromUid(IBinder activityToken) {
20708 ActivityRecord srec;
20709 synchronized (this) {
20710 srec = ActivityRecord.forTokenLocked(activityToken);
20712 if (srec == null) {
20715 return srec.launchedFromUid;
20718 public String getLaunchedFromPackage(IBinder activityToken) {
20719 ActivityRecord srec;
20720 synchronized (this) {
20721 srec = ActivityRecord.forTokenLocked(activityToken);
20723 if (srec == null) {
20726 return srec.launchedFromPackage;
20729 // =========================================================
20730 // LIFETIME MANAGEMENT
20731 // =========================================================
20733 // Returns whether the app is receiving broadcast.
20734 // If receiving, fetch all broadcast queues which the app is
20735 // the current [or imminent] receiver on.
20736 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20737 ArraySet<BroadcastQueue> receivingQueues) {
20738 if (!app.curReceivers.isEmpty()) {
20739 for (BroadcastRecord r : app.curReceivers) {
20740 receivingQueues.add(r.queue);
20745 // It's not the current receiver, but it might be starting up to become one
20746 for (BroadcastQueue queue : mBroadcastQueues) {
20747 final BroadcastRecord r = queue.mPendingBroadcast;
20748 if (r != null && r.curApp == app) {
20749 // found it; report which queue it's in
20750 receivingQueues.add(queue);
20754 return !receivingQueues.isEmpty();
20757 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20758 int targetUid, ComponentName targetComponent, String targetProcess) {
20759 if (!mTrackingAssociations) {
20762 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20763 = mAssociations.get(targetUid);
20764 if (components == null) {
20765 components = new ArrayMap<>();
20766 mAssociations.put(targetUid, components);
20768 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20769 if (sourceUids == null) {
20770 sourceUids = new SparseArray<>();
20771 components.put(targetComponent, sourceUids);
20773 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20774 if (sourceProcesses == null) {
20775 sourceProcesses = new ArrayMap<>();
20776 sourceUids.put(sourceUid, sourceProcesses);
20778 Association ass = sourceProcesses.get(sourceProcess);
20780 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20782 sourceProcesses.put(sourceProcess, ass);
20786 if (ass.mNesting == 1) {
20787 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20788 ass.mLastState = sourceState;
20793 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20794 ComponentName targetComponent) {
20795 if (!mTrackingAssociations) {
20798 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20799 = mAssociations.get(targetUid);
20800 if (components == null) {
20803 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20804 if (sourceUids == null) {
20807 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20808 if (sourceProcesses == null) {
20811 Association ass = sourceProcesses.get(sourceProcess);
20812 if (ass == null || ass.mNesting <= 0) {
20816 if (ass.mNesting == 0) {
20817 long uptime = SystemClock.uptimeMillis();
20818 ass.mTime += uptime - ass.mStartTime;
20819 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20820 += uptime - ass.mLastStateUptime;
20821 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20825 private void noteUidProcessState(final int uid, final int state) {
20826 mBatteryStatsService.noteUidProcessState(uid, state);
20827 if (mTrackingAssociations) {
20828 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20829 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20830 = mAssociations.valueAt(i1);
20831 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20832 SparseArray<ArrayMap<String, Association>> sourceUids
20833 = targetComponents.valueAt(i2);
20834 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20835 if (sourceProcesses != null) {
20836 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20837 Association ass = sourceProcesses.valueAt(i4);
20838 if (ass.mNesting >= 1) {
20839 // currently associated
20840 long uptime = SystemClock.uptimeMillis();
20841 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20842 += uptime - ass.mLastStateUptime;
20843 ass.mLastState = state;
20844 ass.mLastStateUptime = uptime;
20853 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20854 boolean doingAll, long now) {
20855 if (mAdjSeq == app.adjSeq) {
20856 // This adjustment has already been computed.
20857 return app.curRawAdj;
20860 if (app.thread == null) {
20861 app.adjSeq = mAdjSeq;
20862 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20863 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20864 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20867 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20868 app.adjSource = null;
20869 app.adjTarget = null;
20871 app.cached = false;
20873 final int activitiesSize = app.activities.size();
20875 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20876 // The max adjustment doesn't allow this app to be anything
20877 // below foreground, so it is not worth doing work for it.
20878 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20879 app.adjType = "fixed";
20880 app.adjSeq = mAdjSeq;
20881 app.curRawAdj = app.maxAdj;
20882 app.foregroundActivities = false;
20883 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20884 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20885 // System processes can do UI, and when they do we want to have
20886 // them trim their memory after the user leaves the UI. To
20887 // facilitate this, here we need to determine whether or not it
20888 // is currently showing UI.
20889 app.systemNoUi = true;
20890 if (app == TOP_APP) {
20891 app.systemNoUi = false;
20892 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20893 app.adjType = "pers-top-activity";
20894 } else if (app.hasTopUi) {
20895 app.systemNoUi = false;
20896 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20897 app.adjType = "pers-top-ui";
20898 } else if (activitiesSize > 0) {
20899 for (int j = 0; j < activitiesSize; j++) {
20900 final ActivityRecord r = app.activities.get(j);
20902 app.systemNoUi = false;
20906 if (!app.systemNoUi) {
20907 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20909 return (app.curAdj=app.maxAdj);
20912 app.systemNoUi = false;
20914 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20916 // Determine the importance of the process, starting with most
20917 // important to least, and assign an appropriate OOM adjustment.
20921 boolean foregroundActivities = false;
20922 mTmpBroadcastQueue.clear();
20923 if (app == TOP_APP) {
20924 // The last app on the list is the foreground app.
20925 adj = ProcessList.FOREGROUND_APP_ADJ;
20926 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20927 app.adjType = "top-activity";
20928 foregroundActivities = true;
20929 procState = PROCESS_STATE_CUR_TOP;
20930 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20931 } else if (app.instr != null) {
20932 // Don't want to kill running instrumentation.
20933 adj = ProcessList.FOREGROUND_APP_ADJ;
20934 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20935 app.adjType = "instrumentation";
20936 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20937 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20938 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20939 // An app that is currently receiving a broadcast also
20940 // counts as being in the foreground for OOM killer purposes.
20941 // It's placed in a sched group based on the nature of the
20942 // broadcast as reflected by which queue it's active in.
20943 adj = ProcessList.FOREGROUND_APP_ADJ;
20944 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20945 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20946 app.adjType = "broadcast";
20947 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20948 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20949 } else if (app.executingServices.size() > 0) {
20950 // An app that is currently executing a service callback also
20951 // counts as being in the foreground.
20952 adj = ProcessList.FOREGROUND_APP_ADJ;
20953 schedGroup = app.execServicesFg ?
20954 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20955 app.adjType = "exec-service";
20956 procState = ActivityManager.PROCESS_STATE_SERVICE;
20957 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20958 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20960 // As far as we know the process is empty. We may change our mind later.
20961 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20962 // At this point we don't actually know the adjustment. Use the cached adj
20963 // value that the caller wants us to.
20965 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20968 app.adjType = "cch-empty";
20969 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20972 // Examine all activities if not already foreground.
20973 if (!foregroundActivities && activitiesSize > 0) {
20974 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20975 for (int j = 0; j < activitiesSize; j++) {
20976 final ActivityRecord r = app.activities.get(j);
20977 if (r.app != app) {
20978 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20979 + " instead of expected " + app);
20980 if (r.app == null || (r.app.uid == app.uid)) {
20981 // Only fix things up when they look sane
20988 // App has a visible activity; only upgrade adjustment.
20989 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20990 adj = ProcessList.VISIBLE_APP_ADJ;
20991 app.adjType = "vis-activity";
20992 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20994 if (procState > PROCESS_STATE_CUR_TOP) {
20995 procState = PROCESS_STATE_CUR_TOP;
20996 app.adjType = "vis-activity";
20997 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20999 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21000 app.cached = false;
21002 foregroundActivities = true;
21003 final TaskRecord task = r.getTask();
21004 if (task != null && minLayer > 0) {
21005 final int layer = task.mLayerRank;
21006 if (layer >= 0 && minLayer > layer) {
21011 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21012 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21013 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21014 app.adjType = "pause-activity";
21015 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21017 if (procState > PROCESS_STATE_CUR_TOP) {
21018 procState = PROCESS_STATE_CUR_TOP;
21019 app.adjType = "pause-activity";
21020 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21022 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21023 app.cached = false;
21025 foregroundActivities = true;
21026 } else if (r.state == ActivityState.STOPPING) {
21027 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21028 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21029 app.adjType = "stop-activity";
21030 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21032 // For the process state, we will at this point consider the
21033 // process to be cached. It will be cached either as an activity
21034 // or empty depending on whether the activity is finishing. We do
21035 // this so that we can treat the process as cached for purposes of
21036 // memory trimming (determing current memory level, trim command to
21037 // send to process) since there can be an arbitrary number of stopping
21038 // processes and they should soon all go into the cached state.
21039 if (!r.finishing) {
21040 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21041 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21042 app.adjType = "stop-activity";
21043 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21046 app.cached = false;
21048 foregroundActivities = true;
21050 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21051 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21052 app.adjType = "cch-act";
21053 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21057 if (adj == ProcessList.VISIBLE_APP_ADJ) {
21062 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21063 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21064 if (app.foregroundServices) {
21065 // The user is aware of this app, so make it visible.
21066 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21067 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21068 app.cached = false;
21069 app.adjType = "fg-service";
21070 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21071 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21072 } else if (app.hasOverlayUi) {
21073 // The process is display an overlay UI.
21074 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21075 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21076 app.cached = false;
21077 app.adjType = "has-overlay-ui";
21078 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21079 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21083 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21084 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21085 if (app.forcingToImportant != null) {
21086 // This is currently used for toasts... they are not interactive, and
21087 // we don't want them to cause the app to become fully foreground (and
21088 // thus out of background check), so we yes the best background level we can.
21089 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21090 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21091 app.cached = false;
21092 app.adjType = "force-imp";
21093 app.adjSource = app.forcingToImportant;
21094 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21095 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21099 if (app == mHeavyWeightProcess) {
21100 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21101 // We don't want to kill the current heavy-weight process.
21102 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21103 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21104 app.cached = false;
21105 app.adjType = "heavy";
21106 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21108 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21109 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21110 app.adjType = "heavy";
21111 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21115 if (app == mHomeProcess) {
21116 if (adj > ProcessList.HOME_APP_ADJ) {
21117 // This process is hosting what we currently consider to be the
21118 // home app, so we don't want to let it go into the background.
21119 adj = ProcessList.HOME_APP_ADJ;
21120 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21121 app.cached = false;
21122 app.adjType = "home";
21123 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21125 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21126 procState = ActivityManager.PROCESS_STATE_HOME;
21127 app.adjType = "home";
21128 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21132 if (app == mPreviousProcess && app.activities.size() > 0) {
21133 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21134 // This was the previous process that showed UI to the user.
21135 // We want to try to keep it around more aggressively, to give
21136 // a good experience around switching between two apps.
21137 adj = ProcessList.PREVIOUS_APP_ADJ;
21138 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21139 app.cached = false;
21140 app.adjType = "previous";
21141 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21143 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21144 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21145 app.adjType = "previous";
21146 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21150 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21151 + " reason=" + app.adjType);
21153 // By default, we use the computed adjustment. It may be changed if
21154 // there are applications dependent on our services or providers, but
21155 // this gives us a baseline and makes sure we don't get into an
21156 // infinite recursion.
21157 app.adjSeq = mAdjSeq;
21158 app.curRawAdj = adj;
21159 app.hasStartedServices = false;
21161 if (mBackupTarget != null && app == mBackupTarget.app) {
21162 // If possible we want to avoid killing apps while they're being backed up
21163 if (adj > ProcessList.BACKUP_APP_ADJ) {
21164 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21165 adj = ProcessList.BACKUP_APP_ADJ;
21166 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21167 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21169 app.adjType = "backup";
21170 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21171 app.cached = false;
21173 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21174 procState = ActivityManager.PROCESS_STATE_BACKUP;
21175 app.adjType = "backup";
21176 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21180 boolean mayBeTop = false;
21181 String mayBeTopType = null;
21182 Object mayBeTopSource = null;
21183 Object mayBeTopTarget = null;
21185 for (int is = app.services.size()-1;
21186 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21187 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21188 || procState > ActivityManager.PROCESS_STATE_TOP);
21190 ServiceRecord s = app.services.valueAt(is);
21191 if (s.startRequested) {
21192 app.hasStartedServices = true;
21193 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21194 procState = ActivityManager.PROCESS_STATE_SERVICE;
21195 app.adjType = "started-services";
21196 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21198 if (app.hasShownUi && app != mHomeProcess) {
21199 // If this process has shown some UI, let it immediately
21200 // go to the LRU list because it may be pretty heavy with
21201 // UI stuff. We'll tag it with a label just to help
21202 // debug and understand what is going on.
21203 if (adj > ProcessList.SERVICE_ADJ) {
21204 app.adjType = "cch-started-ui-services";
21207 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21208 // This service has seen some activity within
21209 // recent memory, so we will keep its process ahead
21210 // of the background processes.
21211 if (adj > ProcessList.SERVICE_ADJ) {
21212 adj = ProcessList.SERVICE_ADJ;
21213 app.adjType = "started-services";
21214 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21215 app.cached = false;
21218 // If we have let the service slide into the background
21219 // state, still have some text describing what it is doing
21220 // even though the service no longer has an impact.
21221 if (adj > ProcessList.SERVICE_ADJ) {
21222 app.adjType = "cch-started-services";
21227 for (int conni = s.connections.size()-1;
21228 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21229 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21230 || procState > ActivityManager.PROCESS_STATE_TOP);
21232 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21234 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21235 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21236 || procState > ActivityManager.PROCESS_STATE_TOP);
21238 // XXX should compute this based on the max of
21239 // all connected clients.
21240 ConnectionRecord cr = clist.get(i);
21241 if (cr.binding.client == app) {
21242 // Binding to ourself is not interesting.
21246 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21247 ProcessRecord client = cr.binding.client;
21248 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21249 TOP_APP, doingAll, now);
21250 int clientProcState = client.curProcState;
21251 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21252 // If the other app is cached for any reason, for purposes here
21253 // we are going to consider it empty. The specific cached state
21254 // doesn't propagate except under certain conditions.
21255 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21257 String adjType = null;
21258 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21259 // Not doing bind OOM management, so treat
21260 // this guy more like a started service.
21261 if (app.hasShownUi && app != mHomeProcess) {
21262 // If this process has shown some UI, let it immediately
21263 // go to the LRU list because it may be pretty heavy with
21264 // UI stuff. We'll tag it with a label just to help
21265 // debug and understand what is going on.
21266 if (adj > clientAdj) {
21267 adjType = "cch-bound-ui-services";
21269 app.cached = false;
21271 clientProcState = procState;
21273 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21274 // This service has not seen activity within
21275 // recent memory, so allow it to drop to the
21276 // LRU list if there is no other reason to keep
21277 // it around. We'll also tag it with a label just
21278 // to help debug and undertand what is going on.
21279 if (adj > clientAdj) {
21280 adjType = "cch-bound-services";
21286 if (adj > clientAdj) {
21287 // If this process has recently shown UI, and
21288 // the process that is binding to it is less
21289 // important than being visible, then we don't
21290 // care about the binding as much as we care
21291 // about letting this process get into the LRU
21292 // list to be killed and restarted if needed for
21294 if (app.hasShownUi && app != mHomeProcess
21295 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21296 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21297 adjType = "cch-bound-ui-services";
21301 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21302 |Context.BIND_IMPORTANT)) != 0) {
21303 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21304 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21305 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21306 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21307 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21308 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21309 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21310 newAdj = clientAdj;
21312 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21313 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21318 if (!client.cached) {
21319 app.cached = false;
21321 if (adj > newAdj) {
21323 adjType = "service";
21327 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21328 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21329 // This will treat important bound services identically to
21330 // the top app, which may behave differently than generic
21331 // foreground work.
21332 if (client.curSchedGroup > schedGroup) {
21333 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21334 schedGroup = client.curSchedGroup;
21336 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21339 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21340 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21341 // Special handling of clients who are in the top state.
21342 // We *may* want to consider this process to be in the
21343 // top state as well, but only if there is not another
21344 // reason for it to be running. Being on the top is a
21345 // special state, meaning you are specifically running
21346 // for the current top app. If the process is already
21347 // running in the background for some other reason, it
21348 // is more important to continue considering it to be
21349 // in the background state.
21351 mayBeTopType = "service";
21352 mayBeTopSource = cr.binding.client;
21353 mayBeTopTarget = s.name;
21354 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21356 // Special handling for above-top states (persistent
21357 // processes). These should not bring the current process
21358 // into the top state, since they are not on top. Instead
21359 // give them the best state after that.
21360 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21362 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21363 } else if (mWakefulness
21364 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21365 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21368 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21371 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21375 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21376 if (clientProcState <
21377 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21379 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21382 if (clientProcState <
21383 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21385 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21388 if (procState > clientProcState) {
21389 procState = clientProcState;
21390 if (adjType == null) {
21391 adjType = "service";
21394 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21395 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21396 app.pendingUiClean = true;
21398 if (adjType != null) {
21399 app.adjType = adjType;
21400 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21401 .REASON_SERVICE_IN_USE;
21402 app.adjSource = cr.binding.client;
21403 app.adjSourceProcState = clientProcState;
21404 app.adjTarget = s.name;
21405 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21406 + ": " + app + ", due to " + cr.binding.client
21407 + " adj=" + adj + " procState=" + procState);
21410 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21411 app.treatLikeActivity = true;
21413 final ActivityRecord a = cr.activity;
21414 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21415 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21416 (a.visible || a.state == ActivityState.RESUMED ||
21417 a.state == ActivityState.PAUSING)) {
21418 adj = ProcessList.FOREGROUND_APP_ADJ;
21419 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21420 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21421 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21423 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21426 app.cached = false;
21427 app.adjType = "service";
21428 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21429 .REASON_SERVICE_IN_USE;
21431 app.adjSourceProcState = procState;
21432 app.adjTarget = s.name;
21433 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21441 for (int provi = app.pubProviders.size()-1;
21442 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21443 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21444 || procState > ActivityManager.PROCESS_STATE_TOP);
21446 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21447 for (int i = cpr.connections.size()-1;
21448 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21449 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21450 || procState > ActivityManager.PROCESS_STATE_TOP);
21452 ContentProviderConnection conn = cpr.connections.get(i);
21453 ProcessRecord client = conn.client;
21454 if (client == app) {
21455 // Being our own client is not interesting.
21458 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21459 int clientProcState = client.curProcState;
21460 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21461 // If the other app is cached for any reason, for purposes here
21462 // we are going to consider it empty.
21463 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21465 String adjType = null;
21466 if (adj > clientAdj) {
21467 if (app.hasShownUi && app != mHomeProcess
21468 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21469 adjType = "cch-ui-provider";
21471 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21472 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21473 adjType = "provider";
21475 app.cached &= client.cached;
21477 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21478 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21479 // Special handling of clients who are in the top state.
21480 // We *may* want to consider this process to be in the
21481 // top state as well, but only if there is not another
21482 // reason for it to be running. Being on the top is a
21483 // special state, meaning you are specifically running
21484 // for the current top app. If the process is already
21485 // running in the background for some other reason, it
21486 // is more important to continue considering it to be
21487 // in the background state.
21489 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21490 mayBeTopType = adjType = "provider-top";
21491 mayBeTopSource = client;
21492 mayBeTopTarget = cpr.name;
21494 // Special handling for above-top states (persistent
21495 // processes). These should not bring the current process
21496 // into the top state, since they are not on top. Instead
21497 // give them the best state after that.
21499 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21500 if (adjType == null) {
21501 adjType = "provider";
21505 if (procState > clientProcState) {
21506 procState = clientProcState;
21508 if (client.curSchedGroup > schedGroup) {
21509 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21511 if (adjType != null) {
21512 app.adjType = adjType;
21513 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21514 .REASON_PROVIDER_IN_USE;
21515 app.adjSource = client;
21516 app.adjSourceProcState = clientProcState;
21517 app.adjTarget = cpr.name;
21518 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21519 + ": " + app + ", due to " + client
21520 + " adj=" + adj + " procState=" + procState);
21523 // If the provider has external (non-framework) process
21524 // dependencies, ensure that its adjustment is at least
21525 // FOREGROUND_APP_ADJ.
21526 if (cpr.hasExternalProcessHandles()) {
21527 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21528 adj = ProcessList.FOREGROUND_APP_ADJ;
21529 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21530 app.cached = false;
21531 app.adjType = "ext-provider";
21532 app.adjTarget = cpr.name;
21533 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21535 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21536 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21541 if (app.lastProviderTime > 0 &&
21542 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21543 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21544 adj = ProcessList.PREVIOUS_APP_ADJ;
21545 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21546 app.cached = false;
21547 app.adjType = "recent-provider";
21548 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21550 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21551 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21552 app.adjType = "recent-provider";
21553 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21557 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21558 // A client of one of our services or providers is in the top state. We
21559 // *may* want to be in the top state, but not if we are already running in
21560 // the background for some other reason. For the decision here, we are going
21561 // to pick out a few specific states that we want to remain in when a client
21562 // is top (states that tend to be longer-term) and otherwise allow it to go
21563 // to the top state.
21564 switch (procState) {
21565 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21566 // Something else is keeping it at this level, just leave it.
21568 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21569 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21570 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21571 case ActivityManager.PROCESS_STATE_SERVICE:
21572 // These all are longer-term states, so pull them up to the top
21573 // of the background states, but not all the way to the top state.
21574 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21575 app.adjType = mayBeTopType;
21576 app.adjSource = mayBeTopSource;
21577 app.adjTarget = mayBeTopTarget;
21578 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21579 + ": " + app + ", due to " + mayBeTopSource
21580 + " adj=" + adj + " procState=" + procState);
21583 // Otherwise, top is a better choice, so take it.
21584 procState = ActivityManager.PROCESS_STATE_TOP;
21585 app.adjType = mayBeTopType;
21586 app.adjSource = mayBeTopSource;
21587 app.adjTarget = mayBeTopTarget;
21588 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21589 + ": " + app + ", due to " + mayBeTopSource
21590 + " adj=" + adj + " procState=" + procState);
21595 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21596 if (app.hasClientActivities) {
21597 // This is a cached process, but with client activities. Mark it so.
21598 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21599 app.adjType = "cch-client-act";
21600 } else if (app.treatLikeActivity) {
21601 // This is a cached process, but somebody wants us to treat it like it has
21602 // an activity, okay!
21603 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21604 app.adjType = "cch-as-act";
21608 if (adj == ProcessList.SERVICE_ADJ) {
21610 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21611 mNewNumServiceProcs++;
21612 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21613 if (!app.serviceb) {
21614 // This service isn't far enough down on the LRU list to
21615 // normally be a B service, but if we are low on RAM and it
21616 // is large we want to force it down since we would prefer to
21617 // keep launcher over it.
21618 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21619 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21620 app.serviceHighRam = true;
21621 app.serviceb = true;
21622 //Slog.i(TAG, "ADJ " + app + " high ram!");
21624 mNewNumAServiceProcs++;
21625 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21628 app.serviceHighRam = false;
21631 if (app.serviceb) {
21632 adj = ProcessList.SERVICE_B_ADJ;
21636 app.curRawAdj = adj;
21638 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21639 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21640 if (adj > app.maxAdj) {
21642 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21643 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21647 // Do final modification to adj. Everything we do between here and applying
21648 // the final setAdj must be done in this function, because we will also use
21649 // it when computing the final cached adj later. Note that we don't need to
21650 // worry about this for max adj above, since max adj will always be used to
21651 // keep it out of the cached vaues.
21652 app.curAdj = app.modifyRawOomAdj(adj);
21653 app.curSchedGroup = schedGroup;
21654 app.curProcState = procState;
21655 app.foregroundActivities = foregroundActivities;
21657 return app.curRawAdj;
21661 * Record new PSS sample for a process.
21663 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21665 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21667 proc.lastPssTime = now;
21668 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21669 if (DEBUG_PSS) Slog.d(TAG_PSS,
21670 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21671 + " state=" + ProcessList.makeProcStateString(procState));
21672 if (proc.initialIdlePss == 0) {
21673 proc.initialIdlePss = pss;
21675 proc.lastPss = pss;
21676 proc.lastSwapPss = swapPss;
21677 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21678 proc.lastCachedPss = pss;
21679 proc.lastCachedSwapPss = swapPss;
21682 final SparseArray<Pair<Long, String>> watchUids
21683 = mMemWatchProcesses.getMap().get(proc.processName);
21685 if (watchUids != null) {
21686 Pair<Long, String> val = watchUids.get(proc.uid);
21688 val = watchUids.get(0);
21694 if (check != null) {
21695 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21696 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21697 if (!isDebuggable) {
21698 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21699 isDebuggable = true;
21702 if (isDebuggable) {
21703 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21704 final ProcessRecord myProc = proc;
21705 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21706 mMemWatchDumpProcName = proc.processName;
21707 mMemWatchDumpFile = heapdumpFile.toString();
21708 mMemWatchDumpPid = proc.pid;
21709 mMemWatchDumpUid = proc.uid;
21710 BackgroundThread.getHandler().post(new Runnable() {
21712 public void run() {
21713 revokeUriPermission(ActivityThread.currentActivityThread()
21714 .getApplicationThread(),
21715 null, DumpHeapActivity.JAVA_URI,
21716 Intent.FLAG_GRANT_READ_URI_PERMISSION
21717 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21718 UserHandle.myUserId());
21719 ParcelFileDescriptor fd = null;
21721 heapdumpFile.delete();
21722 fd = ParcelFileDescriptor.open(heapdumpFile,
21723 ParcelFileDescriptor.MODE_CREATE |
21724 ParcelFileDescriptor.MODE_TRUNCATE |
21725 ParcelFileDescriptor.MODE_WRITE_ONLY |
21726 ParcelFileDescriptor.MODE_APPEND);
21727 IApplicationThread thread = myProc.thread;
21728 if (thread != null) {
21730 if (DEBUG_PSS) Slog.d(TAG_PSS,
21731 "Requesting dump heap from "
21732 + myProc + " to " + heapdumpFile);
21733 thread.dumpHeap(/* managed= */ true,
21734 /* mallocInfo= */ false, /* runGc= */ false,
21735 heapdumpFile.toString(), fd);
21736 } catch (RemoteException e) {
21739 } catch (FileNotFoundException e) {
21740 e.printStackTrace();
21745 } catch (IOException e) {
21752 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21753 + ", but debugging not enabled");
21760 * Schedule PSS collection of a process.
21762 void requestPssLocked(ProcessRecord proc, int procState) {
21763 if (mPendingPssProcesses.contains(proc)) {
21766 if (mPendingPssProcesses.size() == 0) {
21767 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21769 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21770 proc.pssProcState = procState;
21771 mPendingPssProcesses.add(proc);
21775 * Schedule PSS collection of all processes.
21777 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21779 if (now < (mLastFullPssTime +
21780 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21781 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21785 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21786 mLastFullPssTime = now;
21787 mFullPssPending = true;
21788 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21789 mPendingPssProcesses.clear();
21790 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21791 ProcessRecord app = mLruProcesses.get(i);
21792 if (app.thread == null
21793 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21796 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21797 app.pssProcState = app.setProcState;
21798 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21799 mTestPssMode, isSleepingLocked(), now);
21800 mPendingPssProcesses.add(app);
21803 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21806 public void setTestPssMode(boolean enabled) {
21807 synchronized (this) {
21808 mTestPssMode = enabled;
21810 // Whenever we enable the mode, we want to take a snapshot all of current
21811 // process mem use.
21812 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21818 * Ask a given process to GC right now.
21820 final void performAppGcLocked(ProcessRecord app) {
21822 app.lastRequestedGc = SystemClock.uptimeMillis();
21823 if (app.thread != null) {
21824 if (app.reportLowMemory) {
21825 app.reportLowMemory = false;
21826 app.thread.scheduleLowMemory();
21828 app.thread.processInBackground();
21831 } catch (Exception e) {
21837 * Returns true if things are idle enough to perform GCs.
21839 private final boolean canGcNowLocked() {
21840 boolean processingBroadcasts = false;
21841 for (BroadcastQueue q : mBroadcastQueues) {
21842 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21843 processingBroadcasts = true;
21846 return !processingBroadcasts
21847 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21851 * Perform GCs on all processes that are waiting for it, but only
21852 * if things are idle.
21854 final void performAppGcsLocked() {
21855 final int N = mProcessesToGc.size();
21859 if (canGcNowLocked()) {
21860 while (mProcessesToGc.size() > 0) {
21861 ProcessRecord proc = mProcessesToGc.remove(0);
21862 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21863 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21864 <= SystemClock.uptimeMillis()) {
21865 // To avoid spamming the system, we will GC processes one
21866 // at a time, waiting a few seconds between each.
21867 performAppGcLocked(proc);
21868 scheduleAppGcsLocked();
21871 // It hasn't been long enough since we last GCed this
21872 // process... put it in the list to wait for its time.
21873 addProcessToGcListLocked(proc);
21879 scheduleAppGcsLocked();
21884 * If all looks good, perform GCs on all processes waiting for them.
21886 final void performAppGcsIfAppropriateLocked() {
21887 if (canGcNowLocked()) {
21888 performAppGcsLocked();
21891 // Still not idle, wait some more.
21892 scheduleAppGcsLocked();
21896 * Schedule the execution of all pending app GCs.
21898 final void scheduleAppGcsLocked() {
21899 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21901 if (mProcessesToGc.size() > 0) {
21902 // Schedule a GC for the time to the next process.
21903 ProcessRecord proc = mProcessesToGc.get(0);
21904 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21906 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21907 long now = SystemClock.uptimeMillis();
21908 if (when < (now+mConstants.GC_TIMEOUT)) {
21909 when = now + mConstants.GC_TIMEOUT;
21911 mHandler.sendMessageAtTime(msg, when);
21916 * Add a process to the array of processes waiting to be GCed. Keeps the
21917 * list in sorted order by the last GC time. The process can't already be
21920 final void addProcessToGcListLocked(ProcessRecord proc) {
21921 boolean added = false;
21922 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21923 if (mProcessesToGc.get(i).lastRequestedGc <
21924 proc.lastRequestedGc) {
21926 mProcessesToGc.add(i+1, proc);
21931 mProcessesToGc.add(0, proc);
21936 * Set up to ask a process to GC itself. This will either do it
21937 * immediately, or put it on the list of processes to gc the next
21938 * time things are idle.
21940 final void scheduleAppGcLocked(ProcessRecord app) {
21941 long now = SystemClock.uptimeMillis();
21942 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21945 if (!mProcessesToGc.contains(app)) {
21946 addProcessToGcListLocked(app);
21947 scheduleAppGcsLocked();
21951 final void checkExcessivePowerUsageLocked() {
21952 updateCpuStatsNow();
21954 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21955 boolean doCpuKills = true;
21956 if (mLastPowerCheckUptime == 0) {
21957 doCpuKills = false;
21959 final long curUptime = SystemClock.uptimeMillis();
21960 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21961 mLastPowerCheckUptime = curUptime;
21962 int i = mLruProcesses.size();
21965 ProcessRecord app = mLruProcesses.get(i);
21966 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21967 if (app.lastCpuTime <= 0) {
21970 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21972 StringBuilder sb = new StringBuilder(128);
21973 sb.append("CPU for ");
21974 app.toShortString(sb);
21975 sb.append(": over ");
21976 TimeUtils.formatDuration(uptimeSince, sb);
21977 sb.append(" used ");
21978 TimeUtils.formatDuration(cputimeUsed, sb);
21980 sb.append((cputimeUsed*100)/uptimeSince);
21982 Slog.i(TAG_POWER, sb.toString());
21984 // If the process has used too much CPU over the last duration, the
21985 // user probably doesn't want this, so kill!
21986 if (doCpuKills && uptimeSince > 0) {
21987 // What is the limit for this process?
21989 long checkDur = curUptime - app.whenUnimportant;
21990 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21991 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21992 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21993 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21994 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21995 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21996 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21998 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
22000 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
22001 synchronized (stats) {
22002 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
22003 uptimeSince, cputimeUsed);
22005 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
22006 + " dur=" + checkDur + " limit=" + cpuLimit, true);
22007 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22010 app.lastCpuTime = app.curCpuTime;
22015 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22017 boolean success = true;
22019 if (app.curRawAdj != app.setRawAdj) {
22020 app.setRawAdj = app.curRawAdj;
22025 if (app.curAdj != app.setAdj) {
22026 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22027 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22028 String msg = "Set " + app.pid + " " + app.processName + " adj "
22029 + app.curAdj + ": " + app.adjType;
22030 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22032 app.setAdj = app.curAdj;
22033 app.verifiedAdj = ProcessList.INVALID_ADJ;
22036 if (app.setSchedGroup != app.curSchedGroup) {
22037 int oldSchedGroup = app.setSchedGroup;
22038 app.setSchedGroup = app.curSchedGroup;
22039 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22040 String msg = "Setting sched group of " + app.processName
22041 + " to " + app.curSchedGroup;
22042 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22044 if (app.waitingToKill != null && app.curReceivers.isEmpty()
22045 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22046 app.kill(app.waitingToKill, true);
22050 switch (app.curSchedGroup) {
22051 case ProcessList.SCHED_GROUP_BACKGROUND:
22052 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22054 case ProcessList.SCHED_GROUP_TOP_APP:
22055 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22056 processGroup = THREAD_GROUP_TOP_APP;
22059 processGroup = THREAD_GROUP_DEFAULT;
22062 long oldId = Binder.clearCallingIdentity();
22064 setProcessGroup(app.pid, processGroup);
22065 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22066 // do nothing if we already switched to RT
22067 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22068 mVrController.onTopProcChangedLocked(app);
22069 if (mUseFifoUiScheduling) {
22070 // Switch UI pipeline for app to SCHED_FIFO
22071 app.savedPriority = Process.getThreadPriority(app.pid);
22072 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22073 if (app.renderThreadTid != 0) {
22074 scheduleAsFifoPriority(app.renderThreadTid,
22075 /* suppressLogs */true);
22076 if (DEBUG_OOM_ADJ) {
22077 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22078 app.renderThreadTid + ") to FIFO");
22081 if (DEBUG_OOM_ADJ) {
22082 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22086 // Boost priority for top app UI and render threads
22087 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22088 if (app.renderThreadTid != 0) {
22090 setThreadPriority(app.renderThreadTid,
22091 TOP_APP_PRIORITY_BOOST);
22092 } catch (IllegalArgumentException e) {
22093 // thread died, ignore
22098 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22099 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22100 mVrController.onTopProcChangedLocked(app);
22101 if (mUseFifoUiScheduling) {
22103 // Reset UI pipeline to SCHED_OTHER
22104 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22105 setThreadPriority(app.pid, app.savedPriority);
22106 if (app.renderThreadTid != 0) {
22107 setThreadScheduler(app.renderThreadTid,
22109 setThreadPriority(app.renderThreadTid, -4);
22111 } catch (IllegalArgumentException e) {
22113 "Failed to set scheduling policy, thread does not exist:\n"
22115 } catch (SecurityException e) {
22116 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22119 // Reset priority for top app UI and render threads
22120 setThreadPriority(app.pid, 0);
22121 if (app.renderThreadTid != 0) {
22122 setThreadPriority(app.renderThreadTid, 0);
22126 } catch (Exception e) {
22128 Slog.w(TAG, "Failed setting process group of " + app.pid
22129 + " to " + app.curSchedGroup);
22130 Slog.w(TAG, "at location", e);
22133 Binder.restoreCallingIdentity(oldId);
22137 if (app.repForegroundActivities != app.foregroundActivities) {
22138 app.repForegroundActivities = app.foregroundActivities;
22139 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22141 if (app.repProcState != app.curProcState) {
22142 app.repProcState = app.curProcState;
22143 if (app.thread != null) {
22146 //RuntimeException h = new RuntimeException("here");
22147 Slog.i(TAG, "Sending new process state " + app.repProcState
22148 + " to " + app /*, h*/);
22150 app.thread.setProcessState(app.repProcState);
22151 } catch (RemoteException e) {
22155 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22156 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22157 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22158 // Experimental code to more aggressively collect pss while
22159 // running test... the problem is that this tends to collect
22160 // the data right when a process is transitioning between process
22161 // states, which well tend to give noisy data.
22162 long start = SystemClock.uptimeMillis();
22163 long pss = Debug.getPss(app.pid, mTmpLong, null);
22164 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22165 mPendingPssProcesses.remove(app);
22166 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22167 + " to " + app.curProcState + ": "
22168 + (SystemClock.uptimeMillis()-start) + "ms");
22170 app.lastStateTime = now;
22171 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22172 mTestPssMode, isSleepingLocked(), now);
22173 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22174 + ProcessList.makeProcStateString(app.setProcState) + " to "
22175 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22176 + (app.nextPssTime-now) + ": " + app);
22178 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22179 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22181 requestPssLocked(app, app.setProcState);
22182 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22183 mTestPssMode, isSleepingLocked(), now);
22184 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22185 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22187 if (app.setProcState != app.curProcState) {
22188 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22189 String msg = "Proc state change of " + app.processName
22190 + " to " + app.curProcState;
22191 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22193 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22194 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22195 if (setImportant && !curImportant) {
22196 // This app is no longer something we consider important enough to allow to
22197 // use arbitrary amounts of battery power. Note
22198 // its current CPU time to later know to kill it if
22199 // it is not behaving well.
22200 app.whenUnimportant = now;
22201 app.lastCpuTime = 0;
22203 // Inform UsageStats of important process state change
22204 // Must be called before updating setProcState
22205 maybeUpdateUsageStatsLocked(app, nowElapsed);
22207 app.setProcState = app.curProcState;
22208 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22209 app.notCachedSinceIdle = false;
22212 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22214 app.procStateChanged = true;
22216 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22217 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22218 // For apps that sit around for a long time in the interactive state, we need
22219 // to report this at least once a day so they don't go idle.
22220 maybeUpdateUsageStatsLocked(app, nowElapsed);
22223 if (changes != 0) {
22224 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22225 "Changes in " + app + ": " + changes);
22226 int i = mPendingProcessChanges.size()-1;
22227 ProcessChangeItem item = null;
22229 item = mPendingProcessChanges.get(i);
22230 if (item.pid == app.pid) {
22231 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22232 "Re-using existing item: " + item);
22238 // No existing item in pending changes; need a new one.
22239 final int NA = mAvailProcessChanges.size();
22241 item = mAvailProcessChanges.remove(NA-1);
22242 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22243 "Retrieving available item: " + item);
22245 item = new ProcessChangeItem();
22246 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22247 "Allocating new item: " + item);
22250 item.pid = app.pid;
22251 item.uid = app.info.uid;
22252 if (mPendingProcessChanges.size() == 0) {
22253 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22254 "*** Enqueueing dispatch processes changed!");
22255 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22257 mPendingProcessChanges.add(item);
22259 item.changes |= changes;
22260 item.foregroundActivities = app.repForegroundActivities;
22261 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22262 "Item " + Integer.toHexString(System.identityHashCode(item))
22263 + " " + app.toShortString() + ": changes=" + item.changes
22264 + " foreground=" + item.foregroundActivities
22265 + " type=" + app.adjType + " source=" + app.adjSource
22266 + " target=" + app.adjTarget);
22272 private boolean isEphemeralLocked(int uid) {
22273 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22274 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22277 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22282 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22283 final UidRecord.ChangeItem pendingChange;
22284 if (uidRec == null || uidRec.pendingChange == null) {
22285 if (mPendingUidChanges.size() == 0) {
22286 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22287 "*** Enqueueing dispatch uid changed!");
22288 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22290 final int NA = mAvailUidChanges.size();
22292 pendingChange = mAvailUidChanges.remove(NA-1);
22293 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22294 "Retrieving available item: " + pendingChange);
22296 pendingChange = new UidRecord.ChangeItem();
22297 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22298 "Allocating new item: " + pendingChange);
22300 if (uidRec != null) {
22301 uidRec.pendingChange = pendingChange;
22302 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22303 // If this uid is going away, and we haven't yet reported it is gone,
22305 change |= UidRecord.CHANGE_IDLE;
22307 } else if (uid < 0) {
22308 throw new IllegalArgumentException("No UidRecord or uid");
22310 pendingChange.uidRecord = uidRec;
22311 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22312 mPendingUidChanges.add(pendingChange);
22314 pendingChange = uidRec.pendingChange;
22315 // If there is no change in idle or active state, then keep whatever was pending.
22316 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22317 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22318 | UidRecord.CHANGE_ACTIVE));
22320 // If there is no change in cached or uncached state, then keep whatever was pending.
22321 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22322 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22323 | UidRecord.CHANGE_UNCACHED));
22325 // If this is a report of the UID being gone, then we shouldn't keep any previous
22326 // report of it being active or cached. (That is, a gone uid is never active,
22327 // and never cached.)
22328 if ((change & UidRecord.CHANGE_GONE) != 0) {
22329 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22330 if (!uidRec.idle) {
22331 // If this uid is going away, and we haven't yet reported it is gone,
22333 change |= UidRecord.CHANGE_IDLE;
22337 pendingChange.change = change;
22338 pendingChange.processState = uidRec != null
22339 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22340 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22341 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22342 if (uidRec != null) {
22343 uidRec.lastReportedChange = change;
22344 uidRec.updateLastDispatchedProcStateSeq(change);
22347 // Directly update the power manager, since we sit on top of it and it is critical
22348 // it be kept in sync (so wake locks will be held as soon as appropriate).
22349 if (mLocalPowerManager != null) {
22350 // TO DO: dispatch cached/uncached changes here, so we don't need to report
22351 // all proc state changes.
22352 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22353 mLocalPowerManager.uidActive(pendingChange.uid);
22355 if ((change & UidRecord.CHANGE_IDLE) != 0) {
22356 mLocalPowerManager.uidIdle(pendingChange.uid);
22358 if ((change & UidRecord.CHANGE_GONE) != 0) {
22359 mLocalPowerManager.uidGone(pendingChange.uid);
22361 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22362 pendingChange.processState);
22367 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22368 String authority) {
22369 if (app == null) return;
22370 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22371 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22372 if (userState == null) return;
22373 final long now = SystemClock.elapsedRealtime();
22374 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22375 if (lastReported == null || lastReported < now - 60 * 1000L) {
22376 if (mSystemReady) {
22377 // Cannot touch the user stats if not system ready
22378 mUsageStatsService.reportContentProviderUsage(
22379 authority, providerPkgName, app.userId);
22381 userState.mProviderLastReportedFg.put(authority, now);
22386 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22387 if (DEBUG_USAGE_STATS) {
22388 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22389 + "] state changes: old = " + app.setProcState + ", new = "
22390 + app.curProcState);
22392 if (mUsageStatsService == null) {
22395 boolean isInteraction;
22396 // To avoid some abuse patterns, we are going to be careful about what we consider
22397 // to be an app interaction. Being the top activity doesn't count while the display
22398 // is sleeping, nor do short foreground services.
22399 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22400 isInteraction = true;
22401 app.fgInteractionTime = 0;
22402 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22403 if (app.fgInteractionTime == 0) {
22404 app.fgInteractionTime = nowElapsed;
22405 isInteraction = false;
22407 isInteraction = nowElapsed > app.fgInteractionTime
22408 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22411 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22412 app.fgInteractionTime = 0;
22414 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22415 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22416 app.interactionEventTime = nowElapsed;
22417 String[] packages = app.getPackageList();
22418 if (packages != null) {
22419 for (int i = 0; i < packages.length; i++) {
22420 mUsageStatsService.reportEvent(packages[i], app.userId,
22421 UsageEvents.Event.SYSTEM_INTERACTION);
22425 app.reportedInteraction = isInteraction;
22426 if (!isInteraction) {
22427 app.interactionEventTime = 0;
22431 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22432 if (proc.thread != null) {
22433 if (proc.baseProcessTracker != null) {
22434 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22439 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22440 ProcessRecord TOP_APP, boolean doingAll, long now) {
22441 if (app.thread == null) {
22445 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22447 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22450 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22452 if (isForeground != proc.foregroundServices) {
22453 proc.foregroundServices = isForeground;
22454 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22456 if (isForeground) {
22457 if (curProcs == null) {
22458 curProcs = new ArrayList<ProcessRecord>();
22459 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22461 if (!curProcs.contains(proc)) {
22462 curProcs.add(proc);
22463 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22464 proc.info.packageName, proc.info.uid);
22467 if (curProcs != null) {
22468 if (curProcs.remove(proc)) {
22469 mBatteryStatsService.noteEvent(
22470 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22471 proc.info.packageName, proc.info.uid);
22472 if (curProcs.size() <= 0) {
22473 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22479 updateOomAdjLocked();
22484 private final ActivityRecord resumedAppLocked() {
22485 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22489 pkg = act.packageName;
22490 uid = act.info.applicationInfo.uid;
22495 // Has the UID or resumed package name changed?
22496 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22497 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22498 if (mCurResumedPackage != null) {
22499 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22500 mCurResumedPackage, mCurResumedUid);
22502 mCurResumedPackage = pkg;
22503 mCurResumedUid = uid;
22504 if (mCurResumedPackage != null) {
22505 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22506 mCurResumedPackage, mCurResumedUid);
22513 * Update OomAdj for a specific process.
22514 * @param app The process to update
22515 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22516 * if necessary, or skip.
22517 * @return whether updateOomAdjLocked(app) was successful.
22519 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22520 final ActivityRecord TOP_ACT = resumedAppLocked();
22521 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22522 final boolean wasCached = app.cached;
22526 // This is the desired cached adjusment we want to tell it to use.
22527 // If our app is currently cached, we know it, and that is it. Otherwise,
22528 // we don't know it yet, and it needs to now be cached we will then
22529 // need to do a complete oom adj.
22530 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22531 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22532 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22533 SystemClock.uptimeMillis());
22535 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22536 // Changed to/from cached state, so apps after it in the LRU
22537 // list may also be changed.
22538 updateOomAdjLocked();
22543 final void updateOomAdjLocked() {
22544 final ActivityRecord TOP_ACT = resumedAppLocked();
22545 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22546 final long now = SystemClock.uptimeMillis();
22547 final long nowElapsed = SystemClock.elapsedRealtime();
22548 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22549 final int N = mLruProcesses.size();
22552 RuntimeException e = new RuntimeException();
22553 e.fillInStackTrace();
22554 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22557 // Reset state in all uid records.
22558 for (int i=mActiveUids.size()-1; i>=0; i--) {
22559 final UidRecord uidRec = mActiveUids.valueAt(i);
22560 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22561 "Starting update of " + uidRec);
22565 mStackSupervisor.rankTaskLayersIfNeeded();
22568 mNewNumServiceProcs = 0;
22569 mNewNumAServiceProcs = 0;
22571 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22572 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22574 // Let's determine how many processes we have running vs.
22575 // how many slots we have for background processes; we may want
22576 // to put multiple processes in a slot of there are enough of
22578 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22579 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22580 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22581 if (numEmptyProcs > cachedProcessLimit) {
22582 // If there are more empty processes than our limit on cached
22583 // processes, then use the cached process limit for the factor.
22584 // This ensures that the really old empty processes get pushed
22585 // down to the bottom, so if we are running low on memory we will
22586 // have a better chance at keeping around more cached processes
22587 // instead of a gazillion empty processes.
22588 numEmptyProcs = cachedProcessLimit;
22590 int emptyFactor = numEmptyProcs/numSlots;
22591 if (emptyFactor < 1) emptyFactor = 1;
22592 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22593 if (cachedFactor < 1) cachedFactor = 1;
22594 int stepCached = 0;
22598 int numTrimming = 0;
22600 mNumNonCachedProcs = 0;
22601 mNumCachedHiddenProcs = 0;
22603 // First update the OOM adjustment for each of the
22604 // application processes based on their current state.
22605 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22606 int nextCachedAdj = curCachedAdj+1;
22607 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22608 int nextEmptyAdj = curEmptyAdj+2;
22609 for (int i=N-1; i>=0; i--) {
22610 ProcessRecord app = mLruProcesses.get(i);
22611 if (!app.killedByAm && app.thread != null) {
22612 app.procStateChanged = false;
22613 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22615 // If we haven't yet assigned the final cached adj
22616 // to the process, do that now.
22617 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22618 switch (app.curProcState) {
22619 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22620 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22621 // This process is a cached process holding activities...
22622 // assign it the next cached value for that type, and then
22623 // step that cached level.
22624 app.curRawAdj = curCachedAdj;
22625 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22626 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22627 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22629 if (curCachedAdj != nextCachedAdj) {
22631 if (stepCached >= cachedFactor) {
22633 curCachedAdj = nextCachedAdj;
22634 nextCachedAdj += 2;
22635 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22636 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22642 // For everything else, assign next empty cached process
22643 // level and bump that up. Note that this means that
22644 // long-running services that have dropped down to the
22645 // cached level will be treated as empty (since their process
22646 // state is still as a service), which is what we want.
22647 app.curRawAdj = curEmptyAdj;
22648 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22649 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22650 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22652 if (curEmptyAdj != nextEmptyAdj) {
22654 if (stepEmpty >= emptyFactor) {
22656 curEmptyAdj = nextEmptyAdj;
22658 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22659 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22667 applyOomAdjLocked(app, true, now, nowElapsed);
22669 // Count the number of process types.
22670 switch (app.curProcState) {
22671 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22672 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22673 mNumCachedHiddenProcs++;
22675 if (numCached > cachedProcessLimit) {
22676 app.kill("cached #" + numCached, true);
22679 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22680 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22681 && app.lastActivityTime < oldTime) {
22682 app.kill("empty for "
22683 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22684 / 1000) + "s", true);
22687 if (numEmpty > emptyProcessLimit) {
22688 app.kill("empty #" + numEmpty, true);
22693 mNumNonCachedProcs++;
22697 if (app.isolated && app.services.size() <= 0) {
22698 // If this is an isolated process, and there are no
22699 // services running in it, then the process is no longer
22700 // needed. We agressively kill these because we can by
22701 // definition not re-use the same process again, and it is
22702 // good to avoid having whatever code was running in them
22703 // left sitting around after no longer needed.
22704 app.kill("isolated not needed", true);
22706 // Keeping this process, update its uid.
22707 final UidRecord uidRec = app.uidRecord;
22708 if (uidRec != null) {
22709 uidRec.ephemeral = app.info.isInstantApp();
22710 if (uidRec.curProcState > app.curProcState) {
22711 uidRec.curProcState = app.curProcState;
22713 if (app.foregroundServices) {
22714 uidRec.foregroundServices = true;
22719 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22720 && !app.killedByAm) {
22726 incrementProcStateSeqAndNotifyAppsLocked();
22728 mNumServiceProcs = mNewNumServiceProcs;
22730 // Now determine the memory trimming level of background processes.
22731 // Unfortunately we need to start at the back of the list to do this
22732 // properly. We only do this if the number of background apps we
22733 // are managing to keep around is less than half the maximum we desire;
22734 // if we are keeping a good number around, we'll let them use whatever
22735 // memory they want.
22736 final int numCachedAndEmpty = numCached + numEmpty;
22738 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22739 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22740 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22741 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22742 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22743 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22745 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22748 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22750 // We always allow the memory level to go up (better). We only allow it to go
22751 // down if we are in a state where that is allowed, *and* the total number of processes
22752 // has gone down since last time.
22753 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22754 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22755 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22756 if (memFactor > mLastMemoryLevel) {
22757 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22758 memFactor = mLastMemoryLevel;
22759 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22762 if (memFactor != mLastMemoryLevel) {
22763 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22765 mLastMemoryLevel = memFactor;
22766 mLastNumProcesses = mLruProcesses.size();
22767 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22768 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22769 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22770 if (mLowRamStartTime == 0) {
22771 mLowRamStartTime = now;
22775 switch (memFactor) {
22776 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22777 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22779 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22780 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22783 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22786 int factor = numTrimming/3;
22788 if (mHomeProcess != null) minFactor++;
22789 if (mPreviousProcess != null) minFactor++;
22790 if (factor < minFactor) factor = minFactor;
22791 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22792 for (int i=N-1; i>=0; i--) {
22793 ProcessRecord app = mLruProcesses.get(i);
22794 if (allChanged || app.procStateChanged) {
22795 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22796 app.procStateChanged = false;
22798 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22799 && !app.killedByAm) {
22800 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22802 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22803 "Trimming memory of " + app.processName + " to " + curLevel);
22804 app.thread.scheduleTrimMemory(curLevel);
22805 } catch (RemoteException e) {
22808 // For now we won't do this; our memory trimming seems
22809 // to be good enough at this point that destroying
22810 // activities causes more harm than good.
22811 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22812 && app != mHomeProcess && app != mPreviousProcess) {
22813 // Need to do this on its own message because the stack may not
22814 // be in a consistent state at this point.
22815 // For these apps we will also finish their activities
22816 // to help them free memory.
22817 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22821 app.trimMemoryLevel = curLevel;
22823 if (step >= factor) {
22825 switch (curLevel) {
22826 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22827 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22829 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22830 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22834 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22835 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22836 && app.thread != null) {
22838 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22839 "Trimming memory of heavy-weight " + app.processName
22840 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22841 app.thread.scheduleTrimMemory(
22842 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22843 } catch (RemoteException e) {
22846 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22848 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22849 || app.systemNoUi) && app.pendingUiClean) {
22850 // If this application is now in the background and it
22851 // had done UI, then give it the special trim level to
22852 // have it free UI resources.
22853 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22854 if (app.trimMemoryLevel < level && app.thread != null) {
22856 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22857 "Trimming memory of bg-ui " + app.processName
22859 app.thread.scheduleTrimMemory(level);
22860 } catch (RemoteException e) {
22863 app.pendingUiClean = false;
22865 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22867 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22868 "Trimming memory of fg " + app.processName
22869 + " to " + fgTrimLevel);
22870 app.thread.scheduleTrimMemory(fgTrimLevel);
22871 } catch (RemoteException e) {
22874 app.trimMemoryLevel = fgTrimLevel;
22878 if (mLowRamStartTime != 0) {
22879 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22880 mLowRamStartTime = 0;
22882 for (int i=N-1; i>=0; i--) {
22883 ProcessRecord app = mLruProcesses.get(i);
22884 if (allChanged || app.procStateChanged) {
22885 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22886 app.procStateChanged = false;
22888 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22889 || app.systemNoUi) && app.pendingUiClean) {
22890 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22891 && app.thread != null) {
22893 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22894 "Trimming memory of ui hidden " + app.processName
22895 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22896 app.thread.scheduleTrimMemory(
22897 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22898 } catch (RemoteException e) {
22901 app.pendingUiClean = false;
22903 app.trimMemoryLevel = 0;
22907 if (mAlwaysFinishActivities) {
22908 // Need to do this on its own message because the stack may not
22909 // be in a consistent state at this point.
22910 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22914 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22917 ArrayList<UidRecord> becameIdle = null;
22919 // Update from any uid changes.
22920 if (mLocalPowerManager != null) {
22921 mLocalPowerManager.startUidChanges();
22923 for (int i=mActiveUids.size()-1; i>=0; i--) {
22924 final UidRecord uidRec = mActiveUids.valueAt(i);
22925 int uidChange = UidRecord.CHANGE_PROCSTATE;
22926 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22927 && (uidRec.setProcState != uidRec.curProcState
22928 || uidRec.setWhitelist != uidRec.curWhitelist)) {
22929 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22930 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22931 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22932 + " to " + uidRec.curWhitelist);
22933 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22934 && !uidRec.curWhitelist) {
22935 // UID is now in the background (and not on the temp whitelist). Was it
22936 // previously in the foreground (or on the temp whitelist)?
22937 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22938 || uidRec.setWhitelist) {
22939 uidRec.lastBackgroundTime = nowElapsed;
22940 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22941 // Note: the background settle time is in elapsed realtime, while
22942 // the handler time base is uptime. All this means is that we may
22943 // stop background uids later than we had intended, but that only
22944 // happens because the device was sleeping so we are okay anyway.
22945 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22946 mConstants.BACKGROUND_SETTLE_TIME);
22949 if (uidRec.idle && !uidRec.setIdle) {
22950 uidChange = UidRecord.CHANGE_IDLE;
22951 if (becameIdle == null) {
22952 becameIdle = new ArrayList<>();
22954 becameIdle.add(uidRec);
22958 uidChange = UidRecord.CHANGE_ACTIVE;
22959 EventLogTags.writeAmUidActive(uidRec.uid);
22960 uidRec.idle = false;
22962 uidRec.lastBackgroundTime = 0;
22964 final boolean wasCached = uidRec.setProcState
22965 > ActivityManager.PROCESS_STATE_RECEIVER;
22966 final boolean isCached = uidRec.curProcState
22967 > ActivityManager.PROCESS_STATE_RECEIVER;
22968 if (wasCached != isCached ||
22969 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22970 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22972 uidRec.setProcState = uidRec.curProcState;
22973 uidRec.setWhitelist = uidRec.curWhitelist;
22974 uidRec.setIdle = uidRec.idle;
22975 enqueueUidChangeLocked(uidRec, -1, uidChange);
22976 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22977 if (uidRec.foregroundServices) {
22978 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22982 if (mLocalPowerManager != null) {
22983 mLocalPowerManager.finishUidChanges();
22986 if (becameIdle != null) {
22987 // If we have any new uids that became idle this time, we need to make sure
22988 // they aren't left with running services.
22989 for (int i = becameIdle.size() - 1; i >= 0; i--) {
22990 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22994 if (mProcessStats.shouldWriteNowLocked(now)) {
22995 mHandler.post(new Runnable() {
22996 @Override public void run() {
22997 synchronized (ActivityManagerService.this) {
22998 mProcessStats.writeStateAsyncLocked();
23004 if (DEBUG_OOM_ADJ) {
23005 final long duration = SystemClock.uptimeMillis() - now;
23007 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23008 new RuntimeException("here").fillInStackTrace());
23010 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23016 public void makePackageIdle(String packageName, int userId) {
23017 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23018 != PackageManager.PERMISSION_GRANTED) {
23019 String msg = "Permission Denial: makePackageIdle() from pid="
23020 + Binder.getCallingPid()
23021 + ", uid=" + Binder.getCallingUid()
23022 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23024 throw new SecurityException(msg);
23026 final int callingPid = Binder.getCallingPid();
23027 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23028 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23029 long callingId = Binder.clearCallingIdentity();
23030 synchronized(this) {
23032 IPackageManager pm = AppGlobals.getPackageManager();
23035 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23036 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23037 } catch (RemoteException e) {
23039 if (pkgUid == -1) {
23040 throw new IllegalArgumentException("Unknown package name " + packageName);
23043 if (mLocalPowerManager != null) {
23044 mLocalPowerManager.startUidChanges();
23046 final int appId = UserHandle.getAppId(pkgUid);
23047 final int N = mActiveUids.size();
23048 for (int i=N-1; i>=0; i--) {
23049 final UidRecord uidRec = mActiveUids.valueAt(i);
23050 final long bgTime = uidRec.lastBackgroundTime;
23051 if (bgTime > 0 && !uidRec.idle) {
23052 if (UserHandle.getAppId(uidRec.uid) == appId) {
23053 if (userId == UserHandle.USER_ALL ||
23054 userId == UserHandle.getUserId(uidRec.uid)) {
23055 EventLogTags.writeAmUidIdle(uidRec.uid);
23056 uidRec.idle = true;
23057 uidRec.setIdle = true;
23058 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23059 + " from package " + packageName + " user " + userId);
23060 doStopUidLocked(uidRec.uid, uidRec);
23066 if (mLocalPowerManager != null) {
23067 mLocalPowerManager.finishUidChanges();
23069 Binder.restoreCallingIdentity(callingId);
23074 final void idleUids() {
23075 synchronized (this) {
23076 final int N = mActiveUids.size();
23080 final long nowElapsed = SystemClock.elapsedRealtime();
23081 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23083 if (mLocalPowerManager != null) {
23084 mLocalPowerManager.startUidChanges();
23086 for (int i=N-1; i>=0; i--) {
23087 final UidRecord uidRec = mActiveUids.valueAt(i);
23088 final long bgTime = uidRec.lastBackgroundTime;
23089 if (bgTime > 0 && !uidRec.idle) {
23090 if (bgTime <= maxBgTime) {
23091 EventLogTags.writeAmUidIdle(uidRec.uid);
23092 uidRec.idle = true;
23093 uidRec.setIdle = true;
23094 doStopUidLocked(uidRec.uid, uidRec);
23096 if (nextTime == 0 || nextTime > bgTime) {
23102 if (mLocalPowerManager != null) {
23103 mLocalPowerManager.finishUidChanges();
23105 if (nextTime > 0) {
23106 mHandler.removeMessages(IDLE_UIDS_MSG);
23107 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23108 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23114 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23115 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23116 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23120 void incrementProcStateSeqAndNotifyAppsLocked() {
23121 if (mWaitForNetworkTimeoutMs <= 0) {
23124 // Used for identifying which uids need to block for network.
23125 ArrayList<Integer> blockingUids = null;
23126 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23127 final UidRecord uidRec = mActiveUids.valueAt(i);
23128 // If the network is not restricted for uid, then nothing to do here.
23129 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23132 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23135 // If process state is not changed, then there's nothing to do.
23136 if (uidRec.setProcState == uidRec.curProcState) {
23139 final int blockState = getBlockStateForUid(uidRec);
23140 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23141 // there's nothing the app needs to do in this scenario.
23142 if (blockState == NETWORK_STATE_NO_CHANGE) {
23145 synchronized (uidRec.networkStateLock) {
23146 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23147 if (blockState == NETWORK_STATE_BLOCK) {
23148 if (blockingUids == null) {
23149 blockingUids = new ArrayList<>();
23151 blockingUids.add(uidRec.uid);
23153 if (DEBUG_NETWORK) {
23154 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23155 + " threads for uid: " + uidRec);
23157 if (uidRec.waitingForNetwork) {
23158 uidRec.networkStateLock.notifyAll();
23164 // There are no uids that need to block, so nothing more to do.
23165 if (blockingUids == null) {
23169 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23170 final ProcessRecord app = mLruProcesses.get(i);
23171 if (!blockingUids.contains(app.uid)) {
23174 if (!app.killedByAm && app.thread != null) {
23175 final UidRecord uidRec = mActiveUids.get(app.uid);
23177 if (DEBUG_NETWORK) {
23178 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23181 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23182 } catch (RemoteException ignored) {
23189 * Checks if the uid is coming from background to foreground or vice versa and returns
23190 * appropriate block state based on this.
23192 * @return blockState based on whether the uid is coming from background to foreground or
23193 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23194 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23195 * {@link #NETWORK_STATE_NO_CHANGE}.
23198 int getBlockStateForUid(UidRecord uidRec) {
23199 // Denotes whether uid's process state is currently allowed network access.
23200 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23201 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23202 // Denotes whether uid's process state was previously allowed network access.
23203 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23204 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23206 // When the uid is coming to foreground, AMS should inform the app thread that it should
23207 // block for the network rules to get updated before launching an activity.
23208 if (!wasAllowed && isAllowed) {
23209 return NETWORK_STATE_BLOCK;
23211 // When the uid is going to background, AMS should inform the app thread that if an
23212 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23213 if (wasAllowed && !isAllowed) {
23214 return NETWORK_STATE_UNBLOCK;
23216 return NETWORK_STATE_NO_CHANGE;
23219 final void runInBackgroundDisabled(int uid) {
23220 synchronized (this) {
23221 UidRecord uidRec = mActiveUids.get(uid);
23222 if (uidRec != null) {
23223 // This uid is actually running... should it be considered background now?
23225 doStopUidLocked(uidRec.uid, uidRec);
23228 // This uid isn't actually running... still send a report about it being "stopped".
23229 doStopUidLocked(uid, null);
23234 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23235 mServices.stopInBackgroundLocked(uid);
23236 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23240 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23242 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23243 long duration, String tag) {
23244 if (DEBUG_WHITELISTS) {
23245 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23246 + targetUid + ", " + duration + ")");
23249 synchronized (mPidsSelfLocked) {
23250 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23252 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23256 if (!pr.whitelistManager) {
23257 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23258 != PackageManager.PERMISSION_GRANTED) {
23259 if (DEBUG_WHITELISTS) {
23260 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23261 + ": pid " + callerPid + " is not allowed");
23268 tempWhitelistUidLocked(targetUid, duration, tag);
23272 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23274 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23275 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23276 setUidTempWhitelistStateLocked(targetUid, true);
23277 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23280 void pushTempWhitelist() {
23282 final PendingTempWhitelist[] list;
23284 // First copy out the pending changes... we need to leave them in the map for now,
23285 // in case someone needs to check what is coming up while we don't have the lock held.
23286 synchronized(this) {
23287 N = mPendingTempWhitelist.size();
23288 list = new PendingTempWhitelist[N];
23289 for (int i = 0; i < N; i++) {
23290 list[i] = mPendingTempWhitelist.valueAt(i);
23294 // Now safely dispatch changes to device idle controller.
23295 for (int i = 0; i < N; i++) {
23296 PendingTempWhitelist ptw = list[i];
23297 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23298 ptw.duration, true, ptw.tag);
23301 // And now we can safely remove them from the map.
23302 synchronized(this) {
23303 for (int i = 0; i < N; i++) {
23304 PendingTempWhitelist ptw = list[i];
23305 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23306 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23307 mPendingTempWhitelist.removeAt(index);
23313 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23314 boolean changed = false;
23315 for (int i=mActiveUids.size()-1; i>=0; i--) {
23316 final UidRecord uidRec = mActiveUids.valueAt(i);
23317 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23318 uidRec.curWhitelist = onWhitelist;
23323 updateOomAdjLocked();
23327 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23328 boolean changed = false;
23329 final UidRecord uidRec = mActiveUids.get(uid);
23330 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23331 uidRec.curWhitelist = onWhitelist;
23332 updateOomAdjLocked();
23336 final void trimApplications() {
23337 synchronized (this) {
23340 // First remove any unused application processes whose package
23341 // has been removed.
23342 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23343 final ProcessRecord app = mRemovedProcesses.get(i);
23344 if (app.activities.size() == 0
23345 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23347 TAG, "Exiting empty application process "
23348 + app.toShortString() + " ("
23349 + (app.thread != null ? app.thread.asBinder() : null)
23351 if (app.pid > 0 && app.pid != MY_PID) {
23352 app.kill("empty", false);
23355 app.thread.scheduleExit();
23356 } catch (Exception e) {
23357 // Ignore exceptions.
23360 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23361 mRemovedProcesses.remove(i);
23363 if (app.persistent) {
23364 addAppLocked(app.info, null, false, null /* ABI override */);
23369 // Now update the oom adj for all processes.
23370 updateOomAdjLocked();
23374 /** This method sends the specified signal to each of the persistent apps */
23375 public void signalPersistentProcesses(int sig) throws RemoteException {
23376 if (sig != SIGNAL_USR1) {
23377 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23380 synchronized (this) {
23381 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23382 != PackageManager.PERMISSION_GRANTED) {
23383 throw new SecurityException("Requires permission "
23384 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23387 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23388 ProcessRecord r = mLruProcesses.get(i);
23389 if (r.thread != null && r.persistent) {
23390 sendSignal(r.pid, sig);
23396 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23397 if (proc == null || proc == mProfileProc) {
23398 proc = mProfileProc;
23399 profileType = mProfileType;
23400 clearProfilerLocked();
23402 if (proc == null) {
23406 proc.thread.profilerControl(false, null, profileType);
23407 } catch (RemoteException e) {
23408 throw new IllegalStateException("Process disappeared");
23412 private void clearProfilerLocked() {
23413 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23415 mProfilerInfo.profileFd.close();
23416 } catch (IOException e) {
23419 mProfileApp = null;
23420 mProfileProc = null;
23421 mProfilerInfo = null;
23424 public boolean profileControl(String process, int userId, boolean start,
23425 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23428 synchronized (this) {
23429 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23430 // its own permission.
23431 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23432 != PackageManager.PERMISSION_GRANTED) {
23433 throw new SecurityException("Requires permission "
23434 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23437 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23438 throw new IllegalArgumentException("null profile info or fd");
23441 ProcessRecord proc = null;
23442 if (process != null) {
23443 proc = findProcessLocked(process, userId, "profileControl");
23446 if (start && (proc == null || proc.thread == null)) {
23447 throw new IllegalArgumentException("Unknown process: " + process);
23451 stopProfilerLocked(null, 0);
23452 setProfileApp(proc.info, proc.processName, profilerInfo);
23453 mProfileProc = proc;
23454 mProfileType = profileType;
23455 ParcelFileDescriptor fd = profilerInfo.profileFd;
23458 } catch (IOException e) {
23461 profilerInfo.profileFd = fd;
23462 proc.thread.profilerControl(start, profilerInfo, profileType);
23465 mProfilerInfo.profileFd.close();
23466 } catch (IOException e) {
23468 mProfilerInfo.profileFd = null;
23470 stopProfilerLocked(proc, profileType);
23471 if (profilerInfo != null && profilerInfo.profileFd != null) {
23473 profilerInfo.profileFd.close();
23474 } catch (IOException e) {
23481 } catch (RemoteException e) {
23482 throw new IllegalStateException("Process disappeared");
23484 if (profilerInfo != null && profilerInfo.profileFd != null) {
23486 profilerInfo.profileFd.close();
23487 } catch (IOException e) {
23493 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23494 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23495 userId, true, ALLOW_FULL_ONLY, callName, null);
23496 ProcessRecord proc = null;
23498 int pid = Integer.parseInt(process);
23499 synchronized (mPidsSelfLocked) {
23500 proc = mPidsSelfLocked.get(pid);
23502 } catch (NumberFormatException e) {
23505 if (proc == null) {
23506 ArrayMap<String, SparseArray<ProcessRecord>> all
23507 = mProcessNames.getMap();
23508 SparseArray<ProcessRecord> procs = all.get(process);
23509 if (procs != null && procs.size() > 0) {
23510 proc = procs.valueAt(0);
23511 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23512 for (int i=1; i<procs.size(); i++) {
23513 ProcessRecord thisProc = procs.valueAt(i);
23514 if (thisProc.userId == userId) {
23526 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23527 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23530 synchronized (this) {
23531 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23532 // its own permission (same as profileControl).
23533 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23534 != PackageManager.PERMISSION_GRANTED) {
23535 throw new SecurityException("Requires permission "
23536 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23540 throw new IllegalArgumentException("null fd");
23543 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23544 if (proc == null || proc.thread == null) {
23545 throw new IllegalArgumentException("Unknown process: " + process);
23548 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23549 if (!isDebuggable) {
23550 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23551 throw new SecurityException("Process not debuggable: " + proc);
23555 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23559 } catch (RemoteException e) {
23560 throw new IllegalStateException("Process disappeared");
23565 } catch (IOException e) {
23572 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23573 String reportPackage) {
23574 if (processName != null) {
23575 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23576 "setDumpHeapDebugLimit()");
23578 synchronized (mPidsSelfLocked) {
23579 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23580 if (proc == null) {
23581 throw new SecurityException("No process found for calling pid "
23582 + Binder.getCallingPid());
23584 if (!Build.IS_DEBUGGABLE
23585 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23586 throw new SecurityException("Not running a debuggable build");
23588 processName = proc.processName;
23590 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23591 throw new SecurityException("Package " + reportPackage + " is not running in "
23596 synchronized (this) {
23597 if (maxMemSize > 0) {
23598 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23601 mMemWatchProcesses.remove(processName, uid);
23603 mMemWatchProcesses.getMap().remove(processName);
23610 public void dumpHeapFinished(String path) {
23611 synchronized (this) {
23612 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23613 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23614 + " does not match last pid " + mMemWatchDumpPid);
23617 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23618 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23619 + " does not match last path " + mMemWatchDumpFile);
23622 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23623 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23625 // Forced gc to clean up the remnant hprof fd.
23626 Runtime.getRuntime().gc();
23630 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23631 public void monitor() {
23632 synchronized (this) { }
23635 void onCoreSettingsChange(Bundle settings) {
23636 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23637 ProcessRecord processRecord = mLruProcesses.get(i);
23639 if (processRecord.thread != null) {
23640 processRecord.thread.setCoreSettings(settings);
23642 } catch (RemoteException re) {
23648 // Multi-user methods
23651 * Start user, if its not already running, but don't bring it to foreground.
23654 public boolean startUserInBackground(final int userId) {
23655 return mUserController.startUser(userId, /* foreground */ false);
23659 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23660 return mUserController.unlockUser(userId, token, secret, listener);
23664 public boolean switchUser(final int targetUserId) {
23665 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23667 UserInfo targetUserInfo;
23668 synchronized (this) {
23669 currentUserId = mUserController.getCurrentUserIdLocked();
23670 targetUserInfo = mUserController.getUserInfo(targetUserId);
23671 if (targetUserId == currentUserId) {
23672 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23675 if (targetUserInfo == null) {
23676 Slog.w(TAG, "No user info for user #" + targetUserId);
23679 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23680 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23681 + " when device is in demo mode");
23684 if (!targetUserInfo.supportsSwitchTo()) {
23685 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23688 if (targetUserInfo.isManagedProfile()) {
23689 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23692 mUserController.setTargetUserIdLocked(targetUserId);
23694 if (mUserController.mUserSwitchUiEnabled) {
23695 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23696 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23697 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23698 mUiHandler.sendMessage(mHandler.obtainMessage(
23699 START_USER_SWITCH_UI_MSG, userNames));
23701 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23702 mHandler.sendMessage(mHandler.obtainMessage(
23703 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23708 void scheduleStartProfilesLocked() {
23709 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23710 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23711 DateUtils.SECOND_IN_MILLIS);
23716 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23717 return mUserController.stopUser(userId, force, callback);
23721 public UserInfo getCurrentUser() {
23722 return mUserController.getCurrentUser();
23725 String getStartedUserState(int userId) {
23726 synchronized (this) {
23727 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23728 return UserState.stateToString(userState.state);
23733 public boolean isUserRunning(int userId, int flags) {
23734 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23735 && checkCallingPermission(INTERACT_ACROSS_USERS)
23736 != PackageManager.PERMISSION_GRANTED) {
23737 String msg = "Permission Denial: isUserRunning() from pid="
23738 + Binder.getCallingPid()
23739 + ", uid=" + Binder.getCallingUid()
23740 + " requires " + INTERACT_ACROSS_USERS;
23742 throw new SecurityException(msg);
23744 synchronized (this) {
23745 return mUserController.isUserRunningLocked(userId, flags);
23750 public int[] getRunningUserIds() {
23751 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23752 != PackageManager.PERMISSION_GRANTED) {
23753 String msg = "Permission Denial: isUserRunning() from pid="
23754 + Binder.getCallingPid()
23755 + ", uid=" + Binder.getCallingUid()
23756 + " requires " + INTERACT_ACROSS_USERS;
23758 throw new SecurityException(msg);
23760 synchronized (this) {
23761 return mUserController.getStartedUserArrayLocked();
23766 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23767 mUserController.registerUserSwitchObserver(observer, name);
23771 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23772 mUserController.unregisterUserSwitchObserver(observer);
23775 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23776 if (info == null) return null;
23777 ApplicationInfo newInfo = new ApplicationInfo(info);
23778 newInfo.initForUser(userId);
23782 public boolean isUserStopped(int userId) {
23783 synchronized (this) {
23784 return mUserController.getStartedUserStateLocked(userId) == null;
23788 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23790 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23794 ActivityInfo info = new ActivityInfo(aInfo);
23795 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23799 private boolean processSanityChecksLocked(ProcessRecord process) {
23800 if (process == null || process.thread == null) {
23804 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23805 if (!isDebuggable) {
23806 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23814 public boolean startBinderTracking() throws RemoteException {
23815 synchronized (this) {
23816 mBinderTransactionTrackingEnabled = true;
23817 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23818 // permission (same as profileControl).
23819 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23820 != PackageManager.PERMISSION_GRANTED) {
23821 throw new SecurityException("Requires permission "
23822 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23825 for (int i = 0; i < mLruProcesses.size(); i++) {
23826 ProcessRecord process = mLruProcesses.get(i);
23827 if (!processSanityChecksLocked(process)) {
23831 process.thread.startBinderTracking();
23832 } catch (RemoteException e) {
23833 Log.v(TAG, "Process disappared");
23840 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23842 synchronized (this) {
23843 mBinderTransactionTrackingEnabled = false;
23844 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23845 // permission (same as profileControl).
23846 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23847 != PackageManager.PERMISSION_GRANTED) {
23848 throw new SecurityException("Requires permission "
23849 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23853 throw new IllegalArgumentException("null fd");
23856 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23857 pw.println("Binder transaction traces for all processes.\n");
23858 for (ProcessRecord process : mLruProcesses) {
23859 if (!processSanityChecksLocked(process)) {
23863 pw.println("Traces for process: " + process.processName);
23866 TransferPipe tp = new TransferPipe();
23868 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23869 tp.go(fd.getFileDescriptor());
23873 } catch (IOException e) {
23874 pw.println("Failure while dumping IPC traces from " + process +
23875 ". Exception: " + e);
23877 } catch (RemoteException e) {
23878 pw.println("Got a RemoteException while dumping IPC traces from " +
23879 process + ". Exception: " + e);
23890 } catch (IOException e) {
23897 final class LocalService extends ActivityManagerInternal {
23899 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23900 int targetUserId) {
23901 synchronized (ActivityManagerService.this) {
23902 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23903 targetPkg, intent, null, targetUserId);
23908 public String checkContentProviderAccess(String authority, int userId) {
23909 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23913 public void onWakefulnessChanged(int wakefulness) {
23914 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23918 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23919 String processName, String abiOverride, int uid, Runnable crashHandler) {
23920 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23921 processName, abiOverride, uid, crashHandler);
23925 public SleepToken acquireSleepToken(String tag, int displayId) {
23926 Preconditions.checkNotNull(tag);
23927 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23931 public ComponentName getHomeActivityForUser(int userId) {
23932 synchronized (ActivityManagerService.this) {
23933 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23934 return homeActivity == null ? null : homeActivity.realActivity;
23939 public void onUserRemoved(int userId) {
23940 synchronized (ActivityManagerService.this) {
23941 ActivityManagerService.this.onUserStoppedLocked(userId);
23943 mBatteryStatsService.onUserRemoved(userId);
23947 public void onLocalVoiceInteractionStarted(IBinder activity,
23948 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23949 synchronized (ActivityManagerService.this) {
23950 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23951 voiceSession, voiceInteractor);
23956 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23957 synchronized (ActivityManagerService.this) {
23958 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23959 reasons, timestamp);
23964 public void notifyAppTransitionFinished() {
23965 synchronized (ActivityManagerService.this) {
23966 mStackSupervisor.notifyAppTransitionDone();
23971 public void notifyAppTransitionCancelled() {
23972 synchronized (ActivityManagerService.this) {
23973 mStackSupervisor.notifyAppTransitionDone();
23978 public List<IBinder> getTopVisibleActivities() {
23979 synchronized (ActivityManagerService.this) {
23980 return mStackSupervisor.getTopVisibleActivities();
23985 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23986 synchronized (ActivityManagerService.this) {
23987 mStackSupervisor.setDockedStackMinimized(minimized);
23992 public void killForegroundAppsForUser(int userHandle) {
23993 synchronized (ActivityManagerService.this) {
23994 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23995 final int NP = mProcessNames.getMap().size();
23996 for (int ip = 0; ip < NP; ip++) {
23997 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23998 final int NA = apps.size();
23999 for (int ia = 0; ia < NA; ia++) {
24000 final ProcessRecord app = apps.valueAt(ia);
24001 if (app.persistent) {
24002 // We don't kill persistent processes.
24007 } else if (app.userId == userHandle && app.foregroundActivities) {
24008 app.removed = true;
24014 final int N = procs.size();
24015 for (int i = 0; i < N; i++) {
24016 removeProcessLocked(procs.get(i), false, true, "kill all fg");
24022 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24024 if (!(target instanceof PendingIntentRecord)) {
24025 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24028 synchronized (ActivityManagerService.this) {
24029 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24034 public void setDeviceIdleWhitelist(int[] appids) {
24035 synchronized (ActivityManagerService.this) {
24036 mDeviceIdleWhitelist = appids;
24041 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24042 synchronized (ActivityManagerService.this) {
24043 mDeviceIdleTempWhitelist = appids;
24044 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24049 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24051 Preconditions.checkNotNull(values, "Configuration must not be null");
24052 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24053 synchronized (ActivityManagerService.this) {
24054 updateConfigurationLocked(values, null, false, true, userId,
24055 false /* deferResume */);
24060 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24062 Preconditions.checkNotNull(intents, "intents");
24063 final String[] resolvedTypes = new String[intents.length];
24064 for (int i = 0; i < intents.length; i++) {
24065 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24068 // UID of the package on user userId.
24069 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24070 // packageUid may not be initialized.
24071 int packageUid = 0;
24073 packageUid = AppGlobals.getPackageManager().getPackageUid(
24074 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24075 } catch (RemoteException e) {
24076 // Shouldn't happen.
24079 synchronized (ActivityManagerService.this) {
24080 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24081 /*resultTo*/ null, bOptions, userId);
24086 public int getUidProcessState(int uid) {
24087 return getUidState(uid);
24091 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24092 synchronized (ActivityManagerService.this) {
24094 // We might change the visibilities here, so prepare an empty app transition which
24095 // might be overridden later if we actually change visibilities.
24096 final boolean wasTransitionSet =
24097 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24098 if (!wasTransitionSet) {
24099 mWindowManager.prepareAppTransition(TRANSIT_NONE,
24100 false /* alwaysKeepCurrent */);
24102 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24104 // If there was a transition set already we don't want to interfere with it as we
24105 // might be starting it too early.
24106 if (!wasTransitionSet) {
24107 mWindowManager.executeAppTransition();
24110 if (callback != null) {
24116 public boolean isSystemReady() {
24117 // no need to synchronize(this) just to read & return the value
24118 return mSystemReady;
24122 public void notifyKeyguardTrustedChanged() {
24123 synchronized (ActivityManagerService.this) {
24124 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24125 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24131 * Sets if the given pid has an overlay UI or not.
24133 * @param pid The pid we are setting overlay UI for.
24134 * @param hasOverlayUi True if the process has overlay UI.
24135 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24138 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24139 synchronized (ActivityManagerService.this) {
24140 final ProcessRecord pr;
24141 synchronized (mPidsSelfLocked) {
24142 pr = mPidsSelfLocked.get(pid);
24144 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24148 if (pr.hasOverlayUi == hasOverlayUi) {
24151 pr.hasOverlayUi = hasOverlayUi;
24152 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24153 updateOomAdjLocked(pr, true);
24158 * Called after the network policy rules are updated by
24159 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24160 * and {@param procStateSeq}.
24163 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24164 if (DEBUG_NETWORK) {
24165 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24166 + uid + " seq: " + procStateSeq);
24169 synchronized (ActivityManagerService.this) {
24170 record = mActiveUids.get(uid);
24171 if (record == null) {
24172 if (DEBUG_NETWORK) {
24173 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24174 + " procStateSeq: " + procStateSeq);
24179 synchronized (record.networkStateLock) {
24180 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24181 if (DEBUG_NETWORK) {
24182 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24183 + " been handled for uid: " + uid);
24187 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24188 if (record.curProcStateSeq > procStateSeq) {
24189 if (DEBUG_NETWORK) {
24190 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24191 + ", curProcstateSeq: " + record.curProcStateSeq
24192 + ", procStateSeq: " + procStateSeq);
24196 if (record.waitingForNetwork) {
24197 if (DEBUG_NETWORK) {
24198 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24199 + ", procStateSeq: " + procStateSeq);
24201 record.networkStateLock.notifyAll();
24207 * Called after virtual display Id is updated by
24208 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24209 * {@param vrVr2dDisplayId}.
24212 public void setVr2dDisplayId(int vr2dDisplayId) {
24214 Slog.d(TAG, "setVr2dDisplayId called for: " +
24217 synchronized (ActivityManagerService.this) {
24218 mVr2dDisplayId = vr2dDisplayId;
24223 public void saveANRState(String reason) {
24224 synchronized (ActivityManagerService.this) {
24225 final StringWriter sw = new StringWriter();
24226 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24227 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24228 if (reason != null) {
24229 pw.println(" Reason: " + reason);
24232 mActivityStarter.dump(pw, " ", null);
24234 pw.println("-------------------------------------------------------------------------------");
24235 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24236 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24241 mLastANRState = sw.toString();
24246 public void clearSavedANRState() {
24247 synchronized (ActivityManagerService.this) {
24248 mLastANRState = null;
24253 public void setFocusedActivity(IBinder token) {
24254 synchronized (ActivityManagerService.this) {
24255 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24257 throw new IllegalArgumentException(
24258 "setFocusedActivity: No activity record matching token=" + token);
24260 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24261 r, "setFocusedActivity")) {
24262 mStackSupervisor.resumeFocusedStackTopActivityLocked();
24268 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24269 if (packageName == null) return false;
24271 synchronized (ActivityManagerService.this) {
24272 for (int i = 0; i < mLruProcesses.size(); i++) {
24273 final ProcessRecord processRecord = mLruProcesses.get(i);
24274 if (processRecord.uid == uid) {
24275 for (int j = 0; j < processRecord.activities.size(); j++) {
24276 final ActivityRecord activityRecord = processRecord.activities.get(j);
24277 if (packageName.equals(activityRecord.packageName)) {
24289 * Called by app main thread to wait for the network policy rules to get updated.
24291 * @param procStateSeq The sequence number indicating the process state change that the main
24292 * thread is interested in.
24295 public void waitForNetworkStateUpdate(long procStateSeq) {
24296 final int callingUid = Binder.getCallingUid();
24297 if (DEBUG_NETWORK) {
24298 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24301 synchronized (this) {
24302 record = mActiveUids.get(callingUid);
24303 if (record == null) {
24307 synchronized (record.networkStateLock) {
24308 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24309 if (DEBUG_NETWORK) {
24310 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24311 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24312 + " lastProcStateSeqDispatchedToObservers: "
24313 + record.lastDispatchedProcStateSeq);
24317 if (record.curProcStateSeq > procStateSeq) {
24318 if (DEBUG_NETWORK) {
24319 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24320 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24321 + ", procStateSeq: " + procStateSeq);
24325 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24326 if (DEBUG_NETWORK) {
24327 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24328 + procStateSeq + ", so no need to wait. Uid: "
24329 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24330 + record.lastNetworkUpdatedProcStateSeq);
24335 if (DEBUG_NETWORK) {
24336 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24337 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24339 final long startTime = SystemClock.uptimeMillis();
24340 record.waitingForNetwork = true;
24341 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24342 record.waitingForNetwork = false;
24343 final long totalTime = SystemClock.uptimeMillis() - startTime;
24344 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24345 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24346 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24347 + procStateSeq + " UidRec: " + record
24348 + " validateUidRec: " + mValidateUids.get(callingUid));
24350 } catch (InterruptedException e) {
24351 Thread.currentThread().interrupt();
24356 public void waitForBroadcastIdle(PrintWriter pw) {
24357 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24359 boolean idle = true;
24360 synchronized (this) {
24361 for (BroadcastQueue queue : mBroadcastQueues) {
24362 if (!queue.isIdle()) {
24363 final String msg = "Waiting for queue " + queue + " to become idle...";
24373 final String msg = "All broadcast queues are idle!";
24379 SystemClock.sleep(1000);
24385 * Return the user id of the last resumed activity.
24388 public @UserIdInt int getLastResumedActivityUserId() {
24389 enforceCallingPermission(
24390 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24391 synchronized (this) {
24392 if (mLastResumedActivity == null) {
24393 return mUserController.getCurrentUserIdLocked();
24395 return mLastResumedActivity.userId;
24400 * An implementation of IAppTask, that allows an app to manage its own tasks via
24401 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24402 * only the process that calls getAppTasks() can call the AppTask methods.
24404 class AppTaskImpl extends IAppTask.Stub {
24405 private int mTaskId;
24406 private int mCallingUid;
24408 public AppTaskImpl(int taskId, int callingUid) {
24410 mCallingUid = callingUid;
24413 private void checkCaller() {
24414 if (mCallingUid != Binder.getCallingUid()) {
24415 throw new SecurityException("Caller " + mCallingUid
24416 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24421 public void finishAndRemoveTask() {
24424 synchronized (ActivityManagerService.this) {
24425 long origId = Binder.clearCallingIdentity();
24427 // We remove the task from recents to preserve backwards
24428 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24429 REMOVE_FROM_RECENTS)) {
24430 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24433 Binder.restoreCallingIdentity(origId);
24439 public ActivityManager.RecentTaskInfo getTaskInfo() {
24442 synchronized (ActivityManagerService.this) {
24443 long origId = Binder.clearCallingIdentity();
24445 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24447 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24449 return createRecentTaskInfoFromTaskRecord(tr);
24451 Binder.restoreCallingIdentity(origId);
24457 public void moveToFront() {
24459 // Will bring task to front if it already has a root activity.
24460 final long origId = Binder.clearCallingIdentity();
24462 synchronized (this) {
24463 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24466 Binder.restoreCallingIdentity(origId);
24471 public int startActivity(IBinder whoThread, String callingPackage,
24472 Intent intent, String resolvedType, Bundle bOptions) {
24475 int callingUser = UserHandle.getCallingUserId();
24477 IApplicationThread appThread;
24478 synchronized (ActivityManagerService.this) {
24479 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24481 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24483 appThread = IApplicationThread.Stub.asInterface(whoThread);
24484 if (appThread == null) {
24485 throw new IllegalArgumentException("Bad app thread " + appThread);
24488 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24489 resolvedType, null, null, null, null, 0, 0, null, null,
24490 null, bOptions, false, callingUser, tr, "AppTaskImpl");
24494 public void setExcludeFromRecents(boolean exclude) {
24497 synchronized (ActivityManagerService.this) {
24498 long origId = Binder.clearCallingIdentity();
24500 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24502 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24504 Intent intent = tr.getBaseIntent();
24506 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24508 intent.setFlags(intent.getFlags()
24509 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24512 Binder.restoreCallingIdentity(origId);
24519 * Kill processes for the user with id userId and that depend on the package named packageName
24522 public void killPackageDependents(String packageName, int userId) {
24523 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24524 if (packageName == null) {
24525 throw new NullPointerException(
24526 "Cannot kill the dependents of a package without its name.");
24529 long callingId = Binder.clearCallingIdentity();
24530 IPackageManager pm = AppGlobals.getPackageManager();
24533 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24534 } catch (RemoteException e) {
24536 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24537 throw new IllegalArgumentException(
24538 "Cannot kill dependents of non-existing package " + packageName);
24541 synchronized(this) {
24542 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24543 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24544 "dep: " + packageName);
24547 Binder.restoreCallingIdentity(callingId);
24552 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24553 throws RemoteException {
24554 final long callingId = Binder.clearCallingIdentity();
24556 mKeyguardController.dismissKeyguard(token, callback);
24558 Binder.restoreCallingIdentity(callingId);
24563 public int restartUserInBackground(final int userId) {
24564 return mUserController.restartUser(userId, /* foreground */ false);
24568 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24569 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24570 "scheduleApplicationInfoChanged()");
24572 synchronized (this) {
24573 final long origId = Binder.clearCallingIdentity();
24575 updateApplicationInfoLocked(packageNames, userId);
24577 Binder.restoreCallingIdentity(origId);
24582 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24583 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24584 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24585 final ProcessRecord app = mLruProcesses.get(i);
24586 if (app.thread == null) {
24590 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24594 final int packageCount = app.pkgList.size();
24595 for (int j = 0; j < packageCount; j++) {
24596 final String packageName = app.pkgList.keyAt(j);
24597 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24599 final ApplicationInfo ai = AppGlobals.getPackageManager()
24600 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24602 app.thread.scheduleApplicationInfoChanged(ai);
24604 } catch (RemoteException e) {
24605 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24606 packageName, app));
24614 * Attach an agent to the specified process (proces name or PID)
24616 public void attachAgent(String process, String path) {
24618 synchronized (this) {
24619 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24620 if (proc == null || proc.thread == null) {
24621 throw new IllegalArgumentException("Unknown process: " + process);
24624 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24625 if (!isDebuggable) {
24626 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24627 throw new SecurityException("Process not debuggable: " + proc);
24631 proc.thread.attachAgent(path);
24633 } catch (RemoteException e) {
24634 throw new IllegalStateException("Process disappeared");
24639 public static class Injector {
24640 private NetworkManagementInternal mNmi;
24642 public Context getContext() {
24646 public AppOpsService getAppOpsService(File file, Handler handler) {
24647 return new AppOpsService(file, handler);
24650 public Handler getUiHandler(ActivityManagerService service) {
24651 return service.new UiHandler();
24654 public boolean isNetworkRestrictedForUid(int uid) {
24655 if (ensureHasNetworkManagementInternal()) {
24656 return mNmi.isNetworkRestrictedForUid(uid);
24661 private boolean ensureHasNetworkManagementInternal() {
24662 if (mNmi == null) {
24663 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24665 return mNmi != null;
24670 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24671 throws RemoteException {
24672 synchronized (this) {
24673 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24677 final long origId = Binder.clearCallingIdentity();
24679 r.setShowWhenLocked(showWhenLocked);
24681 Binder.restoreCallingIdentity(origId);
24687 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24688 synchronized (this) {
24689 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24693 final long origId = Binder.clearCallingIdentity();
24695 r.setTurnScreenOn(turnScreenOn);
24697 Binder.restoreCallingIdentity(origId);