2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import static android.Manifest.permission.CHANGE_CONFIGURATION;
20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25 import static android.Manifest.permission.READ_FRAME_BUFFER;
26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
32 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
33 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
34 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
35 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
36 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
37 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
38 import static android.content.pm.PackageManager.GET_PROVIDERS;
39 import static android.content.pm.PackageManager.MATCH_ANY_USER;
40 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
41 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
43 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
44 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
45 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
46 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
47 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
49 import static android.os.Build.VERSION_CODES.N;
50 import static android.os.Process.BLUETOOTH_UID;
51 import static android.os.Process.FIRST_APPLICATION_UID;
52 import static android.os.Process.FIRST_ISOLATED_UID;
53 import static android.os.Process.LAST_ISOLATED_UID;
54 import static android.os.Process.NFC_UID;
55 import static android.os.Process.PHONE_UID;
56 import static android.os.Process.PROC_CHAR;
57 import static android.os.Process.PROC_OUT_LONG;
58 import static android.os.Process.PROC_PARENS;
59 import static android.os.Process.PROC_SPACE_TERM;
60 import static android.os.Process.ProcessStartResult;
61 import static android.os.Process.ROOT_UID;
62 import static android.os.Process.SCHED_FIFO;
63 import static android.os.Process.SCHED_OTHER;
64 import static android.os.Process.SCHED_RESET_ON_FORK;
65 import static android.os.Process.SHELL_UID;
66 import static android.os.Process.SIGNAL_QUIT;
67 import static android.os.Process.SIGNAL_USR1;
68 import static android.os.Process.SYSTEM_UID;
69 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
70 import static android.os.Process.THREAD_GROUP_DEFAULT;
71 import static android.os.Process.THREAD_GROUP_TOP_APP;
72 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
73 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
74 import static android.os.Process.getFreeMemory;
75 import static android.os.Process.getTotalMemory;
76 import static android.os.Process.isThreadInProcess;
77 import static android.os.Process.killProcess;
78 import static android.os.Process.killProcessQuiet;
79 import static android.os.Process.myPid;
80 import static android.os.Process.myUid;
81 import static android.os.Process.readProcFile;
82 import static android.os.Process.removeAllProcessGroups;
83 import static android.os.Process.sendSignal;
84 import static android.os.Process.setProcessGroup;
85 import static android.os.Process.setThreadPriority;
86 import static android.os.Process.setThreadScheduler;
87 import static android.os.Process.startWebView;
88 import static android.os.Process.zygoteProcess;
89 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
90 import static android.provider.Settings.Global.DEBUG_APP;
91 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
92 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
94 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
95 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
96 import static android.provider.Settings.System.FONT_SCALE;
97 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
98 import static android.view.Display.DEFAULT_DISPLAY;
99 import static android.view.Display.INVALID_DISPLAY;
100 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
101 import static com.android.internal.util.XmlUtils.readIntAttribute;
102 import static com.android.internal.util.XmlUtils.readLongAttribute;
103 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
104 import static com.android.internal.util.XmlUtils.writeIntAttribute;
105 import static com.android.internal.util.XmlUtils.writeLongAttribute;
106 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
107 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
140 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
165 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
167 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188 import static org.xmlpull.v1.XmlPullParser.START_TAG;
190 import android.Manifest;
191 import android.Manifest.permission;
192 import android.annotation.NonNull;
193 import android.annotation.Nullable;
194 import android.annotation.UserIdInt;
195 import android.app.Activity;
196 import android.app.ActivityManager;
197 import android.app.ActivityManager.RunningTaskInfo;
198 import android.app.ActivityManager.StackId;
199 import android.app.ActivityManager.StackInfo;
200 import android.app.ActivityManager.TaskSnapshot;
201 import android.app.ActivityManager.TaskThumbnailInfo;
202 import android.app.ActivityManagerInternal;
203 import android.app.ActivityManagerInternal.SleepToken;
204 import android.app.ActivityOptions;
205 import android.app.ActivityThread;
206 import android.app.AlertDialog;
207 import android.app.AppGlobals;
208 import android.app.AppOpsManager;
209 import android.app.ApplicationErrorReport;
210 import android.app.ApplicationThreadConstants;
211 import android.app.BroadcastOptions;
212 import android.app.ContentProviderHolder;
213 import android.app.Dialog;
214 import android.app.IActivityContainer;
215 import android.app.IActivityContainerCallback;
216 import android.app.IActivityController;
217 import android.app.IActivityManager;
218 import android.app.IAppTask;
219 import android.app.IApplicationThread;
220 import android.app.IInstrumentationWatcher;
221 import android.app.INotificationManager;
222 import android.app.IProcessObserver;
223 import android.app.IServiceConnection;
224 import android.app.IStopUserCallback;
225 import android.app.ITaskStackListener;
226 import android.app.IUiAutomationConnection;
227 import android.app.IUidObserver;
228 import android.app.IUserSwitchObserver;
229 import android.app.Instrumentation;
230 import android.app.Notification;
231 import android.app.NotificationManager;
232 import android.app.PendingIntent;
233 import android.app.PictureInPictureParams;
234 import android.app.ProfilerInfo;
235 import android.app.RemoteAction;
236 import android.app.WaitResult;
237 import android.app.admin.DevicePolicyManager;
238 import android.app.assist.AssistContent;
239 import android.app.assist.AssistStructure;
240 import android.app.backup.IBackupManager;
241 import android.app.usage.UsageEvents;
242 import android.app.usage.UsageStatsManagerInternal;
243 import android.appwidget.AppWidgetManager;
244 import android.content.ActivityNotFoundException;
245 import android.content.BroadcastReceiver;
246 import android.content.ClipData;
247 import android.content.ComponentCallbacks2;
248 import android.content.ComponentName;
249 import android.content.ContentProvider;
250 import android.content.ContentResolver;
251 import android.content.Context;
252 import android.content.DialogInterface;
253 import android.content.IContentProvider;
254 import android.content.IIntentReceiver;
255 import android.content.IIntentSender;
256 import android.content.Intent;
257 import android.content.IntentFilter;
258 import android.content.IntentSender;
259 import android.content.pm.ActivityInfo;
260 import android.content.pm.ApplicationInfo;
261 import android.content.pm.ConfigurationInfo;
262 import android.content.pm.IPackageDataObserver;
263 import android.content.pm.IPackageManager;
264 import android.content.pm.InstrumentationInfo;
265 import android.content.pm.PackageInfo;
266 import android.content.pm.PackageManager;
267 import android.content.pm.PackageManager.NameNotFoundException;
268 import android.content.pm.PackageManagerInternal;
269 import android.content.pm.ParceledListSlice;
270 import android.content.pm.PathPermission;
271 import android.content.pm.PermissionInfo;
272 import android.content.pm.ProviderInfo;
273 import android.content.pm.ResolveInfo;
274 import android.content.pm.SELinuxUtil;
275 import android.content.pm.ServiceInfo;
276 import android.content.pm.UserInfo;
277 import android.content.res.CompatibilityInfo;
278 import android.content.res.Configuration;
279 import android.content.res.Resources;
280 import android.database.ContentObserver;
281 import android.graphics.Bitmap;
282 import android.graphics.Point;
283 import android.graphics.Rect;
284 import android.location.LocationManager;
285 import android.media.audiofx.AudioEffect;
286 import android.metrics.LogMaker;
287 import android.net.Proxy;
288 import android.net.ProxyInfo;
289 import android.net.Uri;
290 import android.os.BatteryStats;
291 import android.os.Binder;
292 import android.os.Build;
293 import android.os.Bundle;
294 import android.os.Debug;
295 import android.os.DropBoxManager;
296 import android.os.Environment;
297 import android.os.FactoryTest;
298 import android.os.FileObserver;
299 import android.os.FileUtils;
300 import android.os.Handler;
301 import android.os.IBinder;
302 import android.os.IDeviceIdentifiersPolicyService;
303 import android.os.IPermissionController;
304 import android.os.IProcessInfoService;
305 import android.os.IProgressListener;
306 import android.os.LocaleList;
307 import android.os.Looper;
308 import android.os.Message;
309 import android.os.Parcel;
310 import android.os.ParcelFileDescriptor;
311 import android.os.PersistableBundle;
312 import android.os.PowerManager;
313 import android.os.PowerManagerInternal;
314 import android.os.Process;
315 import android.os.RemoteCallbackList;
316 import android.os.RemoteException;
317 import android.os.ResultReceiver;
318 import android.os.ServiceManager;
319 import android.os.ShellCallback;
320 import android.os.StrictMode;
321 import android.os.SystemClock;
322 import android.os.SystemProperties;
323 import android.os.Trace;
324 import android.os.TransactionTooLargeException;
325 import android.os.UpdateLock;
326 import android.os.UserHandle;
327 import android.os.UserManager;
328 import android.os.WorkSource;
329 import android.os.storage.IStorageManager;
330 import android.os.storage.StorageManager;
331 import android.os.storage.StorageManagerInternal;
332 import android.provider.Downloads;
333 import android.provider.Settings;
334 import android.service.voice.IVoiceInteractionSession;
335 import android.service.voice.VoiceInteractionManagerInternal;
336 import android.service.voice.VoiceInteractionSession;
337 import android.telecom.TelecomManager;
338 import android.text.TextUtils;
339 import android.text.format.DateUtils;
340 import android.text.format.Time;
341 import android.text.style.SuggestionSpan;
342 import android.util.ArrayMap;
343 import android.util.ArraySet;
344 import android.util.AtomicFile;
345 import android.util.BootTimingsTraceLog;
346 import android.util.DebugUtils;
347 import android.util.DisplayMetrics;
348 import android.util.EventLog;
349 import android.util.Log;
350 import android.util.Pair;
351 import android.util.PrintWriterPrinter;
352 import android.util.Slog;
353 import android.util.SparseArray;
354 import android.util.SparseIntArray;
355 import android.util.TimeUtils;
356 import android.util.Xml;
357 import android.view.Gravity;
358 import android.view.LayoutInflater;
359 import android.view.View;
360 import android.view.WindowManager;
362 import com.android.server.job.JobSchedulerInternal;
363 import com.google.android.collect.Lists;
364 import com.google.android.collect.Maps;
366 import com.android.internal.R;
367 import com.android.internal.annotations.GuardedBy;
368 import com.android.internal.annotations.VisibleForTesting;
369 import com.android.internal.app.AssistUtils;
370 import com.android.internal.app.DumpHeapActivity;
371 import com.android.internal.app.IAppOpsCallback;
372 import com.android.internal.app.IAppOpsService;
373 import com.android.internal.app.IVoiceInteractor;
374 import com.android.internal.app.ProcessMap;
375 import com.android.internal.app.SystemUserHomeActivity;
376 import com.android.internal.app.procstats.ProcessStats;
377 import com.android.internal.logging.MetricsLogger;
378 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
379 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
380 import com.android.internal.notification.SystemNotificationChannels;
381 import com.android.internal.os.BackgroundThread;
382 import com.android.internal.os.BatteryStatsImpl;
383 import com.android.internal.os.IResultReceiver;
384 import com.android.internal.os.ProcessCpuTracker;
385 import com.android.internal.os.TransferPipe;
386 import com.android.internal.os.Zygote;
387 import com.android.internal.policy.IKeyguardDismissCallback;
388 import com.android.internal.telephony.TelephonyIntents;
389 import com.android.internal.util.ArrayUtils;
390 import com.android.internal.util.DumpUtils;
391 import com.android.internal.util.FastPrintWriter;
392 import com.android.internal.util.FastXmlSerializer;
393 import com.android.internal.util.MemInfoReader;
394 import com.android.internal.util.Preconditions;
395 import com.android.server.AppOpsService;
396 import com.android.server.AttributeCache;
397 import com.android.server.DeviceIdleController;
398 import com.android.server.IntentResolver;
399 import com.android.server.LocalServices;
400 import com.android.server.LockGuard;
401 import com.android.server.NetworkManagementInternal;
402 import com.android.server.RescueParty;
403 import com.android.server.ServiceThread;
404 import com.android.server.SystemConfig;
405 import com.android.server.SystemService;
406 import com.android.server.SystemServiceManager;
407 import com.android.server.ThreadPriorityBooster;
408 import com.android.server.Watchdog;
409 import com.android.server.am.ActivityStack.ActivityState;
410 import com.android.server.firewall.IntentFirewall;
411 import com.android.server.pm.Installer;
412 import com.android.server.pm.Installer.InstallerException;
413 import com.android.server.statusbar.StatusBarManagerInternal;
414 import com.android.server.vr.VrManagerInternal;
415 import com.android.server.wm.PinnedStackWindowController;
416 import com.android.server.wm.WindowManagerService;
418 import org.xmlpull.v1.XmlPullParser;
419 import org.xmlpull.v1.XmlPullParserException;
420 import org.xmlpull.v1.XmlSerializer;
423 import java.io.FileDescriptor;
424 import java.io.FileInputStream;
425 import java.io.FileNotFoundException;
426 import java.io.FileOutputStream;
427 import java.io.IOException;
428 import java.io.InputStreamReader;
429 import java.io.PrintWriter;
430 import java.io.StringWriter;
431 import java.io.UnsupportedEncodingException;
432 import java.lang.ref.WeakReference;
433 import java.nio.charset.StandardCharsets;
434 import java.text.DateFormat;
435 import java.util.ArrayList;
436 import java.util.Arrays;
437 import java.util.Collections;
438 import java.util.Comparator;
439 import java.util.Date;
440 import java.util.HashMap;
441 import java.util.HashSet;
442 import java.util.Iterator;
443 import java.util.List;
444 import java.util.Locale;
445 import java.util.Map;
446 import java.util.Objects;
447 import java.util.Set;
448 import java.util.concurrent.CountDownLatch;
449 import java.util.concurrent.atomic.AtomicBoolean;
450 import java.util.concurrent.atomic.AtomicLong;
452 import dalvik.system.VMRuntime;
453 import libcore.io.IoUtils;
454 import libcore.util.EmptyArray;
456 public class ActivityManagerService extends IActivityManager.Stub
457 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
460 * Priority we boost main thread and RT of top app to.
462 public static final int TOP_APP_PRIORITY_BOOST = -10;
464 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
465 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
466 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
467 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
468 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
469 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
470 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
471 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
472 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
473 private static final String TAG_LRU = TAG + POSTFIX_LRU;
474 private static final String TAG_MU = TAG + POSTFIX_MU;
475 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
476 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
477 private static final String TAG_POWER = TAG + POSTFIX_POWER;
478 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
479 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
480 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
481 private static final String TAG_PSS = TAG + POSTFIX_PSS;
482 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
483 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
484 private static final String TAG_STACK = TAG + POSTFIX_STACK;
485 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
486 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
487 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
488 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
489 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
491 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
492 // here so that while the job scheduler can depend on AMS, the other way around
493 // need not be the case.
494 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
496 /** Control over CPU and battery monitoring */
497 // write battery stats every 30 minutes.
498 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
499 static final boolean MONITOR_CPU_USAGE = true;
500 // don't sample cpu less than every 5 seconds.
501 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
502 // wait possibly forever for next cpu sample.
503 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
504 static final boolean MONITOR_THREAD_CPU_USAGE = false;
506 // The flags that are set for all calls we make to the package manager.
507 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
509 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
511 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
513 // Amount of time after a call to stopAppSwitches() during which we will
514 // prevent further untrusted switches from happening.
515 static final long APP_SWITCH_DELAY_TIME = 5*1000;
517 // How long we wait for a launched process to attach to the activity manager
518 // before we decide it's never going to come up for real.
519 static final int PROC_START_TIMEOUT = 10*1000;
520 // How long we wait for an attached process to publish its content providers
521 // before we decide it must be hung.
522 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
524 // How long we wait for a launched process to attach to the activity manager
525 // before we decide it's never going to come up for real, when the process was
526 // started with a wrapper for instrumentation (such as Valgrind) because it
527 // could take much longer than usual.
528 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
530 // How long we allow a receiver to run before giving up on it.
531 static final int BROADCAST_FG_TIMEOUT = 10*1000;
532 static final int BROADCAST_BG_TIMEOUT = 60*1000;
534 // How long we wait until we timeout on key dispatching.
535 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
537 // How long we wait until we timeout on key dispatching during instrumentation.
538 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
540 // How long to wait in getAssistContextExtras for the activity and foreground services
541 // to respond with the result.
542 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
544 // How long top wait when going through the modern assist (which doesn't need to block
545 // on getting this result before starting to launch its UI).
546 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
548 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
549 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
551 // Maximum number of persisted Uri grants a package is allowed
552 static final int MAX_PERSISTED_URI_GRANTS = 128;
554 static final int MY_PID = myPid();
556 static final String[] EMPTY_STRING_ARRAY = new String[0];
558 // How many bytes to write into the dropbox log before truncating
559 static final int DROPBOX_MAX_SIZE = 192 * 1024;
560 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
561 // as one line, but close enough for now.
562 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
564 // Access modes for handleIncomingUser.
565 static final int ALLOW_NON_FULL = 0;
566 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
567 static final int ALLOW_FULL_ONLY = 2;
569 // Necessary ApplicationInfo flags to mark an app as persistent
570 private static final int PERSISTENT_MASK =
571 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
573 // Intent sent when remote bugreport collection has been completed
574 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
575 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
577 // Used to indicate that an app transition should be animated.
578 static final boolean ANIMATE = true;
580 // Determines whether to take full screen screenshots
581 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
584 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
586 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
589 * State indicating that there is no need for any blocking for network.
592 static final int NETWORK_STATE_NO_CHANGE = 0;
595 * State indicating that the main thread needs to be informed about the network wait.
598 static final int NETWORK_STATE_BLOCK = 1;
601 * State indicating that any threads waiting for network state to get updated can be unblocked.
604 static final int NETWORK_STATE_UNBLOCK = 2;
606 // Max character limit for a notification title. If the notification title is larger than this
607 // the notification will not be legible to the user.
608 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
610 /** All system services */
611 SystemServiceManager mSystemServiceManager;
612 AssistUtils mAssistUtils;
614 private Installer mInstaller;
616 /** Run all ActivityStacks through this */
617 final ActivityStackSupervisor mStackSupervisor;
618 private final KeyguardController mKeyguardController;
620 final ActivityStarter mActivityStarter;
622 final TaskChangeNotificationController mTaskChangeNotificationController;
624 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
626 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
628 public final IntentFirewall mIntentFirewall;
630 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
631 // default action automatically. Important for devices without direct input
633 private boolean mShowDialogs = true;
635 private final VrController mVrController;
637 // VR Vr2d Display Id.
638 int mVr2dDisplayId = INVALID_DISPLAY;
640 // Whether we should use SCHED_FIFO for UI and RenderThreads.
641 private boolean mUseFifoUiScheduling = false;
643 BroadcastQueue mFgBroadcastQueue;
644 BroadcastQueue mBgBroadcastQueue;
645 // Convenient for easy iteration over the queues. Foreground is first
646 // so that dispatch of foreground broadcasts gets precedence.
647 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
649 BroadcastStats mLastBroadcastStats;
650 BroadcastStats mCurBroadcastStats;
652 BroadcastQueue broadcastQueueForIntent(Intent intent) {
653 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
654 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
655 "Broadcast intent " + intent + " on "
656 + (isFg ? "foreground" : "background") + " queue");
657 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
661 * The last resumed activity. This is identical to the current resumed activity most
662 * of the time but could be different when we're pausing one activity before we resume
665 private ActivityRecord mLastResumedActivity;
668 * If non-null, we are tracking the time the user spends in the currently focused app.
670 private AppTimeTracker mCurAppTimeTracker;
673 * List of intents that were used to start the most recent tasks.
675 final RecentTasks mRecentTasks;
678 * For addAppTask: cached of the last activity component that was added.
680 ComponentName mLastAddedTaskComponent;
683 * For addAppTask: cached of the last activity uid that was added.
685 int mLastAddedTaskUid;
688 * For addAppTask: cached of the last ActivityInfo that was added.
690 ActivityInfo mLastAddedTaskActivity;
693 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
695 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
698 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
700 String mDeviceOwnerName;
702 final UserController mUserController;
704 final AppErrors mAppErrors;
707 * Dump of the activity state at the time of the last ANR. Cleared after
708 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
710 String mLastANRState;
713 * Indicates the maximum time spent waiting for the network rules to get updated.
716 long mWaitForNetworkTimeoutMs;
718 public boolean canShowErrorDialogs() {
719 return mShowDialogs && !mSleeping && !mShuttingDown
720 && !mKeyguardController.isKeyguardShowing();
723 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
724 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
726 static void boostPriorityForLockedSection() {
727 sThreadPriorityBooster.boost();
730 static void resetPriorityAfterLockedSection() {
731 sThreadPriorityBooster.reset();
734 public class PendingAssistExtras extends Binder implements Runnable {
735 public final ActivityRecord activity;
736 public boolean isHome;
737 public final Bundle extras;
738 public final Intent intent;
739 public final String hint;
740 public final IResultReceiver receiver;
741 public final int userHandle;
742 public boolean haveResult = false;
743 public Bundle result = null;
744 public AssistStructure structure = null;
745 public AssistContent content = null;
746 public Bundle receiverExtras;
748 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
749 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
750 activity = _activity;
754 receiver = _receiver;
755 receiverExtras = _receiverExtras;
756 userHandle = _userHandle;
761 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
762 synchronized (this) {
766 pendingAssistExtrasTimedOut(this);
770 final ArrayList<PendingAssistExtras> mPendingAssistExtras
771 = new ArrayList<PendingAssistExtras>();
774 * Process management.
776 final ProcessList mProcessList = new ProcessList();
779 * All of the applications we currently have running organized by name.
780 * The keys are strings of the application package name (as
781 * returned by the package manager), and the keys are ApplicationRecord
784 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
787 * Tracking long-term execution of processes to look for abuse and other
790 final ProcessStatsService mProcessStats;
793 * The currently running isolated processes.
795 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
798 * Counter for assigning isolated process uids, to avoid frequently reusing the
801 int mNextIsolatedProcessUid = 0;
804 * The currently running heavy-weight process, if any.
806 ProcessRecord mHeavyWeightProcess = null;
809 * Non-persistent appId whitelist for background restrictions
811 int[] mBackgroundAppIdWhitelist = new int[] {
816 * Broadcast actions that will always be deliverable to unlaunched/background apps
818 ArraySet<String> mBackgroundLaunchBroadcasts;
821 * All of the processes we currently have running organized by pid.
822 * The keys are the pid running the application.
824 * <p>NOTE: This object is protected by its own lock, NOT the global
825 * activity manager lock!
827 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
830 * All of the processes that have been forced to be important. The key
831 * is the pid of the caller who requested it (we hold a death
834 abstract class ImportanceToken implements IBinder.DeathRecipient {
839 ImportanceToken(int _pid, IBinder _token, String _reason) {
846 public String toString() {
847 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
848 + " " + reason + " " + pid + " " + token + " }";
851 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
854 * List of records for processes that someone had tried to start before the
855 * system was ready. We don't start them at that point, but ensure they
856 * are started by the time booting is complete.
858 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
861 * List of persistent applications that are in the process
864 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
867 * Processes that are being forcibly torn down.
869 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
872 * List of running applications, sorted by recent usage.
873 * The first entry in the list is the least recently used.
875 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
878 * Where in mLruProcesses that the processes hosting activities start.
880 int mLruProcessActivityStart = 0;
883 * Where in mLruProcesses that the processes hosting services start.
884 * This is after (lower index) than mLruProcessesActivityStart.
886 int mLruProcessServiceStart = 0;
889 * List of processes that should gc as soon as things are idle.
891 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
894 * Processes we want to collect PSS data from.
896 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
898 private boolean mBinderTransactionTrackingEnabled = false;
901 * Last time we requested PSS data of all processes.
903 long mLastFullPssTime = SystemClock.uptimeMillis();
906 * If set, the next time we collect PSS data we should do a full collection
907 * with data from native processes and the kernel.
909 boolean mFullPssPending = false;
912 * This is the process holding what we currently consider to be
913 * the "home" activity.
915 ProcessRecord mHomeProcess;
918 * This is the process holding the activity the user last visited that
919 * is in a different process from the one they are currently in.
921 ProcessRecord mPreviousProcess;
924 * The time at which the previous process was last visible.
926 long mPreviousProcessVisibleTime;
929 * Track all uids that have actively running processes.
931 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
934 * This is for verifying the UID report flow.
936 static final boolean VALIDATE_UID_STATES = true;
937 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
940 * Packages that the user has asked to have run in screen size
941 * compatibility mode instead of filling the screen.
943 final CompatModePackages mCompatModePackages;
946 * Set of IntentSenderRecord objects that are currently active.
948 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
949 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
952 * Fingerprints (hashCode()) of stack traces that we've
953 * already logged DropBox entries for. Guarded by itself. If
954 * something (rogue user app) forces this over
955 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
957 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
958 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
961 * Strict Mode background batched logging state.
963 * The string buffer is guarded by itself, and its lock is also
964 * used to determine if another batched write is already
967 private final StringBuilder mStrictModeBuffer = new StringBuilder();
970 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
971 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
973 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
976 * Resolver for broadcast intents to registered receivers.
977 * Holds BroadcastFilter (subclass of IntentFilter).
979 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
980 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
982 protected boolean allowFilterResult(
983 BroadcastFilter filter, List<BroadcastFilter> dest) {
984 IBinder target = filter.receiverList.receiver.asBinder();
985 for (int i = dest.size() - 1; i >= 0; i--) {
986 if (dest.get(i).receiverList.receiver.asBinder() == target) {
994 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
995 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
996 || userId == filter.owningUserId) {
997 return super.newResult(filter, match, userId);
1003 protected BroadcastFilter[] newArray(int size) {
1004 return new BroadcastFilter[size];
1008 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1009 return packageName.equals(filter.packageName);
1014 * State of all active sticky broadcasts per user. Keys are the action of the
1015 * sticky Intent, values are an ArrayList of all broadcasted intents with
1016 * that action (which should usually be one). The SparseArray is keyed
1017 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1018 * for stickies that are sent to all users.
1020 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1021 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1023 final ActiveServices mServices;
1025 final static class Association {
1026 final int mSourceUid;
1027 final String mSourceProcess;
1028 final int mTargetUid;
1029 final ComponentName mTargetComponent;
1030 final String mTargetProcess;
1038 // states of the source process when the bind occurred.
1039 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1040 long mLastStateUptime;
1041 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1042 - ActivityManager.MIN_PROCESS_STATE+1];
1044 Association(int sourceUid, String sourceProcess, int targetUid,
1045 ComponentName targetComponent, String targetProcess) {
1046 mSourceUid = sourceUid;
1047 mSourceProcess = sourceProcess;
1048 mTargetUid = targetUid;
1049 mTargetComponent = targetComponent;
1050 mTargetProcess = targetProcess;
1055 * When service association tracking is enabled, this is all of the associations we
1056 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1057 * -> association data.
1059 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1060 mAssociations = new SparseArray<>();
1061 boolean mTrackingAssociations;
1064 * Backup/restore process management
1066 String mBackupAppName = null;
1067 BackupRecord mBackupTarget = null;
1069 final ProviderMap mProviderMap;
1072 * List of content providers who have clients waiting for them. The
1073 * application is currently being launched and the provider will be
1074 * removed from this list once it is published.
1076 final ArrayList<ContentProviderRecord> mLaunchingProviders
1077 = new ArrayList<ContentProviderRecord>();
1080 * File storing persisted {@link #mGrantedUriPermissions}.
1082 private final AtomicFile mGrantFile;
1084 /** XML constants used in {@link #mGrantFile} */
1085 private static final String TAG_URI_GRANTS = "uri-grants";
1086 private static final String TAG_URI_GRANT = "uri-grant";
1087 private static final String ATTR_USER_HANDLE = "userHandle";
1088 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1089 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1090 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1091 private static final String ATTR_TARGET_PKG = "targetPkg";
1092 private static final String ATTR_URI = "uri";
1093 private static final String ATTR_MODE_FLAGS = "modeFlags";
1094 private static final String ATTR_CREATED_TIME = "createdTime";
1095 private static final String ATTR_PREFIX = "prefix";
1098 * Global set of specific {@link Uri} permissions that have been granted.
1099 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1100 * to {@link UriPermission#uri} to {@link UriPermission}.
1103 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1104 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1106 public static class GrantUri {
1107 public final int sourceUserId;
1108 public final Uri uri;
1109 public boolean prefix;
1111 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1112 this.sourceUserId = sourceUserId;
1114 this.prefix = prefix;
1118 public int hashCode() {
1120 hashCode = 31 * hashCode + sourceUserId;
1121 hashCode = 31 * hashCode + uri.hashCode();
1122 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1127 public boolean equals(Object o) {
1128 if (o instanceof GrantUri) {
1129 GrantUri other = (GrantUri) o;
1130 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1131 && prefix == other.prefix;
1137 public String toString() {
1138 String result = uri.toString() + " [user " + sourceUserId + "]";
1139 if (prefix) result += " [prefix]";
1143 public String toSafeString() {
1144 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1145 if (prefix) result += " [prefix]";
1149 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1150 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1151 ContentProvider.getUriWithoutUserId(uri), false);
1155 CoreSettingsObserver mCoreSettingsObserver;
1157 FontScaleSettingObserver mFontScaleSettingObserver;
1159 private final class FontScaleSettingObserver extends ContentObserver {
1160 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1162 public FontScaleSettingObserver() {
1164 ContentResolver resolver = mContext.getContentResolver();
1165 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1169 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1170 if (mFontScaleUri.equals(uri)) {
1171 updateFontScaleIfNeeded(userId);
1177 * Thread-local storage used to carry caller permissions over through
1178 * indirect content-provider access.
1180 private class Identity {
1181 public final IBinder token;
1182 public final int pid;
1183 public final int uid;
1185 Identity(IBinder _token, int _pid, int _uid) {
1192 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1195 * All information we have collected about the runtime performance of
1196 * any user id that can impact battery performance.
1198 final BatteryStatsService mBatteryStatsService;
1201 * Information about component usage
1203 UsageStatsManagerInternal mUsageStatsService;
1206 * Access to DeviceIdleController service.
1208 DeviceIdleController.LocalService mLocalDeviceIdleController;
1211 * Set of app ids that are whitelisted for device idle and thus background check.
1213 int[] mDeviceIdleWhitelist = new int[0];
1216 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1218 int[] mDeviceIdleTempWhitelist = new int[0];
1220 static final class PendingTempWhitelist {
1221 final int targetUid;
1222 final long duration;
1225 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1226 targetUid = _targetUid;
1227 duration = _duration;
1232 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1235 * Information about and control over application operations
1237 final AppOpsService mAppOpsService;
1239 /** Current sequencing integer of the configuration, for skipping old configurations. */
1240 private int mConfigurationSeq;
1243 * Temp object used when global and/or display override configuration is updated. It is also
1244 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1247 private Configuration mTempConfig = new Configuration();
1249 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1250 new UpdateConfigurationResult();
1251 private static final class UpdateConfigurationResult {
1252 // Configuration changes that were updated.
1254 // If the activity was relaunched to match the new configuration.
1255 boolean activityRelaunched;
1259 activityRelaunched = false;
1263 boolean mSuppressResizeConfigChanges;
1266 * Hardware-reported OpenGLES version.
1268 final int GL_ES_VERSION;
1271 * List of initialization arguments to pass to all processes when binding applications to them.
1272 * For example, references to the commonly used services.
1274 HashMap<String, IBinder> mAppBindArgs;
1275 HashMap<String, IBinder> mIsolatedAppBindArgs;
1278 * Temporary to avoid allocations. Protected by main lock.
1280 final StringBuilder mStringBuilder = new StringBuilder(256);
1283 * Used to control how we initialize the service.
1285 ComponentName mTopComponent;
1286 String mTopAction = Intent.ACTION_MAIN;
1289 volatile boolean mProcessesReady = false;
1290 volatile boolean mSystemReady = false;
1291 volatile boolean mOnBattery = false;
1292 volatile int mFactoryTest;
1294 @GuardedBy("this") boolean mBooting = false;
1295 @GuardedBy("this") boolean mCallFinishBooting = false;
1296 @GuardedBy("this") boolean mBootAnimationComplete = false;
1297 @GuardedBy("this") boolean mLaunchWarningShown = false;
1298 @GuardedBy("this") boolean mCheckedForSetup = false;
1300 final Context mContext;
1303 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1304 * change at runtime. Use mContext for non-UI purposes.
1306 final Context mUiContext;
1309 * The time at which we will allow normal application switches again,
1310 * after a call to {@link #stopAppSwitches()}.
1312 long mAppSwitchesAllowedTime;
1315 * This is set to true after the first switch after mAppSwitchesAllowedTime
1316 * is set; any switches after that will clear the time.
1318 boolean mDidAppSwitch;
1321 * Last time (in realtime) at which we checked for power usage.
1323 long mLastPowerCheckRealtime;
1326 * Last time (in uptime) at which we checked for power usage.
1328 long mLastPowerCheckUptime;
1331 * Set while we are wanting to sleep, to prevent any
1332 * activities from being started/resumed.
1334 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1336 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1337 * while in the sleep state until there is a pending transition out of sleep, in which case
1338 * mSleeping is set to false, and remains false while awake.
1340 * Whether mSleeping can quickly toggled between true/false without the device actually
1341 * display changing states is undefined.
1343 private boolean mSleeping = false;
1346 * The process state used for processes that are running the top activities.
1347 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1349 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1352 * Set while we are running a voice interaction. This overrides
1353 * sleeping while it is active.
1355 private IVoiceInteractionSession mRunningVoice;
1358 * For some direct access we need to power manager.
1360 PowerManagerInternal mLocalPowerManager;
1363 * We want to hold a wake lock while running a voice interaction session, since
1364 * this may happen with the screen off and we need to keep the CPU running to
1365 * be able to continue to interact with the user.
1367 PowerManager.WakeLock mVoiceWakeLock;
1370 * State of external calls telling us if the device is awake or asleep.
1372 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1375 * A list of tokens that cause the top activity to be put to sleep.
1376 * They are used by components that may hide and block interaction with underlying
1379 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1382 * Set if we are shutting down the system, similar to sleeping.
1384 boolean mShuttingDown = false;
1387 * Current sequence id for oom_adj computation traversal.
1392 * Current sequence id for process LRU updating.
1397 * Keep track of the non-cached/empty process we last found, to help
1398 * determine how to distribute cached/empty processes next time.
1400 int mNumNonCachedProcs = 0;
1403 * Keep track of the number of cached hidden procs, to balance oom adj
1404 * distribution between those and empty procs.
1406 int mNumCachedHiddenProcs = 0;
1409 * Keep track of the number of service processes we last found, to
1410 * determine on the next iteration which should be B services.
1412 int mNumServiceProcs = 0;
1413 int mNewNumAServiceProcs = 0;
1414 int mNewNumServiceProcs = 0;
1417 * Allow the current computed overall memory level of the system to go down?
1418 * This is set to false when we are killing processes for reasons other than
1419 * memory management, so that the now smaller process list will not be taken as
1420 * an indication that memory is tighter.
1422 boolean mAllowLowerMemLevel = false;
1425 * The last computed memory level, for holding when we are in a state that
1426 * processes are going away for other reasons.
1428 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1431 * The last total number of process we have, to determine if changes actually look
1432 * like a shrinking number of process due to lower RAM.
1434 int mLastNumProcesses;
1437 * The uptime of the last time we performed idle maintenance.
1439 long mLastIdleTime = SystemClock.uptimeMillis();
1442 * Total time spent with RAM that has been added in the past since the last idle time.
1444 long mLowRamTimeSinceLastIdle = 0;
1447 * If RAM is currently low, when that horrible situation started.
1449 long mLowRamStartTime = 0;
1452 * For reporting to battery stats the current top application.
1454 private String mCurResumedPackage = null;
1455 private int mCurResumedUid = -1;
1458 * For reporting to battery stats the apps currently running foreground
1459 * service. The ProcessMap is package/uid tuples; each of these contain
1460 * an array of the currently foreground processes.
1462 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1463 = new ProcessMap<ArrayList<ProcessRecord>>();
1466 * This is set if we had to do a delayed dexopt of an app before launching
1467 * it, to increase the ANR timeouts in that case.
1472 * Set if the systemServer made a call to enterSafeMode.
1477 * If true, we are running under a test environment so will sample PSS from processes
1478 * much more rapidly to try to collect better data when the tests are rapidly
1479 * running through apps.
1481 boolean mTestPssMode = false;
1483 String mDebugApp = null;
1484 boolean mWaitForDebugger = false;
1485 boolean mDebugTransient = false;
1486 String mOrigDebugApp = null;
1487 boolean mOrigWaitForDebugger = false;
1488 boolean mAlwaysFinishActivities = false;
1489 boolean mForceResizableActivities;
1491 * Flag that indicates if multi-window is enabled.
1493 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1494 * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
1495 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1496 * At least one of the forms of multi-window must be enabled in order for this flag to be
1497 * initialized to 'true'.
1499 * @see #mSupportsSplitScreenMultiWindow
1500 * @see #mSupportsFreeformWindowManagement
1501 * @see #mSupportsPictureInPicture
1502 * @see #mSupportsMultiDisplay
1504 boolean mSupportsMultiWindow;
1505 boolean mSupportsSplitScreenMultiWindow;
1506 boolean mSupportsFreeformWindowManagement;
1507 boolean mSupportsPictureInPicture;
1508 boolean mSupportsMultiDisplay;
1509 boolean mSupportsLeanbackOnly;
1510 IActivityController mController = null;
1511 boolean mControllerIsAMonkey = false;
1512 String mProfileApp = null;
1513 ProcessRecord mProfileProc = null;
1514 String mProfileFile;
1515 ParcelFileDescriptor mProfileFd;
1516 int mSamplingInterval = 0;
1517 boolean mAutoStopProfiler = false;
1518 boolean mStreamingOutput = false;
1519 int mProfileType = 0;
1520 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1521 String mMemWatchDumpProcName;
1522 String mMemWatchDumpFile;
1523 int mMemWatchDumpPid;
1524 int mMemWatchDumpUid;
1525 String mTrackAllocationApp = null;
1526 String mNativeDebuggingApp = null;
1528 final long[] mTmpLong = new long[2];
1530 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1533 * A global counter for generating sequence numbers.
1534 * This value will be used when incrementing sequence numbers in individual uidRecords.
1536 * Having a global counter ensures that seq numbers are monotonically increasing for a
1537 * particular uid even when the uidRecord is re-created.
1541 long mProcStateSeqCounter = 0;
1543 private final Injector mInjector;
1545 static final class ProcessChangeItem {
1546 static final int CHANGE_ACTIVITIES = 1<<0;
1551 boolean foregroundActivities;
1554 static final class UidObserverRegistration {
1560 final SparseIntArray lastProcStates;
1562 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1566 cutpoint = _cutpoint;
1567 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1568 lastProcStates = new SparseIntArray();
1570 lastProcStates = null;
1575 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1576 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1578 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1579 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1581 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1582 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1584 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1585 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1588 * Runtime CPU use collection thread. This object's lock is used to
1589 * perform synchronization with the thread (notifying it to run).
1591 final Thread mProcessCpuThread;
1594 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1595 * Must acquire this object's lock when accessing it.
1596 * NOTE: this lock will be held while doing long operations (trawling
1597 * through all processes in /proc), so it should never be acquired by
1598 * any critical paths such as when holding the main activity manager lock.
1600 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1601 MONITOR_THREAD_CPU_USAGE);
1602 final AtomicLong mLastCpuTime = new AtomicLong(0);
1603 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1604 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1606 long mLastWriteTime = 0;
1609 * Used to retain an update lock when the foreground activity is in
1612 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1615 * Set to true after the system has finished booting.
1617 boolean mBooted = false;
1619 WindowManagerService mWindowManager;
1620 final ActivityThread mSystemThread;
1622 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1623 final ProcessRecord mApp;
1625 final IApplicationThread mAppThread;
1627 AppDeathRecipient(ProcessRecord app, int pid,
1628 IApplicationThread thread) {
1629 if (DEBUG_ALL) Slog.v(
1630 TAG, "New death recipient " + this
1631 + " for thread " + thread.asBinder());
1634 mAppThread = thread;
1638 public void binderDied() {
1639 if (DEBUG_ALL) Slog.v(
1640 TAG, "Death received in " + this
1641 + " for thread " + mAppThread.asBinder());
1642 synchronized(ActivityManagerService.this) {
1643 appDiedLocked(mApp, mPid, mAppThread, true);
1648 static final int SHOW_ERROR_UI_MSG = 1;
1649 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1650 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1651 static final int UPDATE_CONFIGURATION_MSG = 4;
1652 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1653 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1654 static final int SERVICE_TIMEOUT_MSG = 12;
1655 static final int UPDATE_TIME_ZONE = 13;
1656 static final int SHOW_UID_ERROR_UI_MSG = 14;
1657 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1658 static final int PROC_START_TIMEOUT_MSG = 20;
1659 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1660 static final int KILL_APPLICATION_MSG = 22;
1661 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1662 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1663 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1664 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1665 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1666 static final int CLEAR_DNS_CACHE_MSG = 28;
1667 static final int UPDATE_HTTP_PROXY_MSG = 29;
1668 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1669 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1670 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1671 static final int REPORT_MEM_USAGE_MSG = 33;
1672 static final int REPORT_USER_SWITCH_MSG = 34;
1673 static final int CONTINUE_USER_SWITCH_MSG = 35;
1674 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1675 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1676 static final int PERSIST_URI_GRANTS_MSG = 38;
1677 static final int REQUEST_ALL_PSS_MSG = 39;
1678 static final int START_PROFILES_MSG = 40;
1679 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1680 static final int SYSTEM_USER_START_MSG = 42;
1681 static final int SYSTEM_USER_CURRENT_MSG = 43;
1682 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1683 static final int FINISH_BOOTING_MSG = 45;
1684 static final int START_USER_SWITCH_UI_MSG = 46;
1685 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1686 static final int DISMISS_DIALOG_UI_MSG = 48;
1687 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1688 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1689 static final int DELETE_DUMPHEAP_MSG = 51;
1690 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1691 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1692 static final int REPORT_TIME_TRACKER_MSG = 54;
1693 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1694 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1695 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1696 static final int IDLE_UIDS_MSG = 58;
1697 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1698 static final int LOG_STACK_STATE = 60;
1699 static final int VR_MODE_CHANGE_MSG = 61;
1700 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1701 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1702 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1703 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1704 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1705 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1706 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1707 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1708 static final int START_USER_SWITCH_FG_MSG = 712;
1710 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1711 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1712 static final int FIRST_COMPAT_MODE_MSG = 300;
1713 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1715 static ServiceThread sKillThread = null;
1716 static KillHandler sKillHandler = null;
1718 CompatModeDialog mCompatModeDialog;
1719 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1720 long mLastMemUsageReportTime = 0;
1723 * Flag whether the current user is a "monkey", i.e. whether
1724 * the UI is driven by a UI automation tool.
1726 private boolean mUserIsMonkey;
1728 /** Flag whether the device has a Recents UI */
1729 boolean mHasRecents;
1731 /** The dimensions of the thumbnails in the Recents UI. */
1732 int mThumbnailWidth;
1733 int mThumbnailHeight;
1734 float mFullscreenThumbnailScale;
1736 final ServiceThread mHandlerThread;
1737 final MainHandler mHandler;
1738 final Handler mUiHandler;
1740 final ActivityManagerConstants mConstants;
1742 PackageManagerInternal mPackageManagerInt;
1744 // VoiceInteraction session ID that changes for each new request except when
1745 // being called for multiwindow assist in a single session.
1746 private int mViSessionId = 1000;
1748 final boolean mPermissionReviewRequired;
1751 * Current global configuration information. Contains general settings for the entire system,
1752 * also corresponds to the merged configuration of the default display.
1754 Configuration getGlobalConfiguration() {
1755 return mStackSupervisor.getConfiguration();
1758 final class KillHandler extends Handler {
1759 static final int KILL_PROCESS_GROUP_MSG = 4000;
1761 public KillHandler(Looper looper) {
1762 super(looper, null, true);
1766 public void handleMessage(Message msg) {
1768 case KILL_PROCESS_GROUP_MSG:
1770 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1771 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1772 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1777 super.handleMessage(msg);
1782 final class UiHandler extends Handler {
1783 public UiHandler() {
1784 super(com.android.server.UiThread.get().getLooper(), null, true);
1788 public void handleMessage(Message msg) {
1790 case SHOW_ERROR_UI_MSG: {
1791 mAppErrors.handleShowAppErrorUi(msg);
1792 ensureBootCompleted();
1794 case SHOW_NOT_RESPONDING_UI_MSG: {
1795 mAppErrors.handleShowAnrUi(msg);
1796 ensureBootCompleted();
1798 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1799 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1800 synchronized (ActivityManagerService.this) {
1801 ProcessRecord proc = (ProcessRecord) data.get("app");
1803 Slog.e(TAG, "App not found when showing strict mode dialog.");
1806 if (proc.crashDialog != null) {
1807 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1810 AppErrorResult res = (AppErrorResult) data.get("result");
1811 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1812 Dialog d = new StrictModeViolationDialog(mUiContext,
1813 ActivityManagerService.this, res, proc);
1815 proc.crashDialog = d;
1817 // The device is asleep, so just pretend that the user
1818 // saw a crash dialog and hit "force quit".
1822 ensureBootCompleted();
1824 case SHOW_FACTORY_ERROR_UI_MSG: {
1825 Dialog d = new FactoryErrorDialog(
1826 mUiContext, msg.getData().getCharSequence("msg"));
1828 ensureBootCompleted();
1830 case WAIT_FOR_DEBUGGER_UI_MSG: {
1831 synchronized (ActivityManagerService.this) {
1832 ProcessRecord app = (ProcessRecord)msg.obj;
1833 if (msg.arg1 != 0) {
1834 if (!app.waitedForDebugger) {
1835 Dialog d = new AppWaitingForDebuggerDialog(
1836 ActivityManagerService.this,
1839 app.waitedForDebugger = true;
1843 if (app.waitDialog != null) {
1844 app.waitDialog.dismiss();
1845 app.waitDialog = null;
1850 case SHOW_UID_ERROR_UI_MSG: {
1852 AlertDialog d = new BaseErrorDialog(mUiContext);
1853 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1854 d.setCancelable(false);
1855 d.setTitle(mUiContext.getText(R.string.android_system_label));
1856 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1857 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1858 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1862 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1864 AlertDialog d = new BaseErrorDialog(mUiContext);
1865 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1866 d.setCancelable(false);
1867 d.setTitle(mUiContext.getText(R.string.android_system_label));
1868 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1869 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1870 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1874 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1875 synchronized (ActivityManagerService.this) {
1876 ActivityRecord ar = (ActivityRecord) msg.obj;
1877 if (mCompatModeDialog != null) {
1878 if (mCompatModeDialog.mAppInfo.packageName.equals(
1879 ar.info.applicationInfo.packageName)) {
1882 mCompatModeDialog.dismiss();
1883 mCompatModeDialog = null;
1885 if (ar != null && false) {
1886 if (mCompatModePackages.getPackageAskCompatModeLocked(
1888 int mode = mCompatModePackages.computeCompatModeLocked(
1889 ar.info.applicationInfo);
1890 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1891 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1892 mCompatModeDialog = new CompatModeDialog(
1893 ActivityManagerService.this, mUiContext,
1894 ar.info.applicationInfo);
1895 mCompatModeDialog.show();
1902 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1903 synchronized (ActivityManagerService.this) {
1904 final ActivityRecord ar = (ActivityRecord) msg.obj;
1905 if (mUnsupportedDisplaySizeDialog != null) {
1906 mUnsupportedDisplaySizeDialog.dismiss();
1907 mUnsupportedDisplaySizeDialog = null;
1909 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1911 // TODO(multi-display): Show dialog on appropriate display.
1912 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1913 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1914 mUnsupportedDisplaySizeDialog.show();
1919 case START_USER_SWITCH_UI_MSG: {
1920 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1923 case DISMISS_DIALOG_UI_MSG: {
1924 final Dialog d = (Dialog) msg.obj;
1928 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1929 dispatchProcessesChanged();
1932 case DISPATCH_PROCESS_DIED_UI_MSG: {
1933 final int pid = msg.arg1;
1934 final int uid = msg.arg2;
1935 dispatchProcessDied(pid, uid);
1938 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1939 dispatchUidsChanged();
1941 case PUSH_TEMP_WHITELIST_UI_MSG: {
1942 pushTempWhitelist();
1948 final class MainHandler extends Handler {
1949 public MainHandler(Looper looper) {
1950 super(looper, null, true);
1954 public void handleMessage(Message msg) {
1956 case UPDATE_CONFIGURATION_MSG: {
1957 final ContentResolver resolver = mContext.getContentResolver();
1958 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1961 case GC_BACKGROUND_PROCESSES_MSG: {
1962 synchronized (ActivityManagerService.this) {
1963 performAppGcsIfAppropriateLocked();
1966 case SERVICE_TIMEOUT_MSG: {
1969 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1971 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1974 mServices.serviceTimeout((ProcessRecord)msg.obj);
1976 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1977 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1979 case SERVICE_FOREGROUND_CRASH_MSG: {
1980 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1982 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1983 RemoteCallbackList<IResultReceiver> callbacks
1984 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1985 int N = callbacks.beginBroadcast();
1986 for (int i = 0; i < N; i++) {
1988 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1989 } catch (RemoteException e) {
1992 callbacks.finishBroadcast();
1994 case UPDATE_TIME_ZONE: {
1995 synchronized (ActivityManagerService.this) {
1996 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1997 ProcessRecord r = mLruProcesses.get(i);
1998 if (r.thread != null) {
2000 r.thread.updateTimeZone();
2001 } catch (RemoteException ex) {
2002 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2008 case CLEAR_DNS_CACHE_MSG: {
2009 synchronized (ActivityManagerService.this) {
2010 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2011 ProcessRecord r = mLruProcesses.get(i);
2012 if (r.thread != null) {
2014 r.thread.clearDnsCache();
2015 } catch (RemoteException ex) {
2016 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2022 case UPDATE_HTTP_PROXY_MSG: {
2023 ProxyInfo proxy = (ProxyInfo)msg.obj;
2026 String exclList = "";
2027 Uri pacFileUrl = Uri.EMPTY;
2028 if (proxy != null) {
2029 host = proxy.getHost();
2030 port = Integer.toString(proxy.getPort());
2031 exclList = proxy.getExclusionListAsString();
2032 pacFileUrl = proxy.getPacFileUrl();
2034 synchronized (ActivityManagerService.this) {
2035 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2036 ProcessRecord r = mLruProcesses.get(i);
2037 if (r.thread != null) {
2039 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2040 } catch (RemoteException ex) {
2041 Slog.w(TAG, "Failed to update http proxy for: " +
2042 r.info.processName);
2048 case PROC_START_TIMEOUT_MSG: {
2051 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2053 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
2056 ProcessRecord app = (ProcessRecord)msg.obj;
2057 synchronized (ActivityManagerService.this) {
2058 processStartTimedOutLocked(app);
2061 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2062 ProcessRecord app = (ProcessRecord)msg.obj;
2063 synchronized (ActivityManagerService.this) {
2064 processContentProviderPublishTimedOutLocked(app);
2067 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2068 synchronized (ActivityManagerService.this) {
2069 mActivityStarter.doPendingActivityLaunchesLocked(true);
2072 case KILL_APPLICATION_MSG: {
2073 synchronized (ActivityManagerService.this) {
2074 final int appId = msg.arg1;
2075 final int userId = msg.arg2;
2076 Bundle bundle = (Bundle)msg.obj;
2077 String pkg = bundle.getString("pkg");
2078 String reason = bundle.getString("reason");
2079 forceStopPackageLocked(pkg, appId, false, false, true, false,
2080 false, userId, reason);
2083 case FINALIZE_PENDING_INTENT_MSG: {
2084 ((PendingIntentRecord)msg.obj).completeFinalize();
2086 case POST_HEAVY_NOTIFICATION_MSG: {
2087 INotificationManager inm = NotificationManager.getService();
2092 ActivityRecord root = (ActivityRecord)msg.obj;
2093 ProcessRecord process = root.app;
2094 if (process == null) {
2099 Context context = mContext.createPackageContext(process.info.packageName, 0);
2100 String text = mContext.getString(R.string.heavy_weight_notification,
2101 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2102 Notification notification =
2103 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2104 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2108 .setColor(mContext.getColor(
2109 com.android.internal.R.color.system_notification_accent_color))
2110 .setContentTitle(text)
2112 mContext.getText(R.string.heavy_weight_notification_detail))
2113 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2114 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2115 new UserHandle(root.userId)))
2118 inm.enqueueNotificationWithTag("android", "android", null,
2119 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2120 notification, root.userId);
2121 } catch (RuntimeException e) {
2122 Slog.w(ActivityManagerService.TAG,
2123 "Error showing notification for heavy-weight app", e);
2124 } catch (RemoteException e) {
2126 } catch (NameNotFoundException e) {
2127 Slog.w(TAG, "Unable to create context for heavy notification", e);
2130 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2131 INotificationManager inm = NotificationManager.getService();
2136 inm.cancelNotificationWithTag("android", null,
2137 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2138 } catch (RuntimeException e) {
2139 Slog.w(ActivityManagerService.TAG,
2140 "Error canceling notification for service", e);
2141 } catch (RemoteException e) {
2144 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2145 synchronized (ActivityManagerService.this) {
2146 checkExcessivePowerUsageLocked(true);
2147 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2148 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2149 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2152 case REPORT_MEM_USAGE_MSG: {
2153 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2154 Thread thread = new Thread() {
2155 @Override public void run() {
2156 reportMemUsage(memInfos);
2162 case START_USER_SWITCH_FG_MSG: {
2163 mUserController.startUserInForeground(msg.arg1);
2166 case REPORT_USER_SWITCH_MSG: {
2167 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2170 case CONTINUE_USER_SWITCH_MSG: {
2171 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2174 case USER_SWITCH_TIMEOUT_MSG: {
2175 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2178 case IMMERSIVE_MODE_LOCK_MSG: {
2179 final boolean nextState = (msg.arg1 != 0);
2180 if (mUpdateLock.isHeld() != nextState) {
2181 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2182 "Applying new update lock state '" + nextState
2183 + "' for " + (ActivityRecord)msg.obj);
2185 mUpdateLock.acquire();
2187 mUpdateLock.release();
2192 case PERSIST_URI_GRANTS_MSG: {
2193 writeGrantedUriPermissions();
2196 case REQUEST_ALL_PSS_MSG: {
2197 synchronized (ActivityManagerService.this) {
2198 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2202 case START_PROFILES_MSG: {
2203 synchronized (ActivityManagerService.this) {
2204 mUserController.startProfilesLocked();
2208 case UPDATE_TIME_PREFERENCE_MSG: {
2209 // The user's time format preference might have changed.
2210 // For convenience we re-use the Intent extra values.
2211 synchronized (ActivityManagerService.this) {
2212 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2213 ProcessRecord r = mLruProcesses.get(i);
2214 if (r.thread != null) {
2216 r.thread.updateTimePrefs(msg.arg1);
2217 } catch (RemoteException ex) {
2218 Slog.w(TAG, "Failed to update preferences for: "
2219 + r.info.processName);
2226 case SYSTEM_USER_START_MSG: {
2227 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2228 Integer.toString(msg.arg1), msg.arg1);
2229 mSystemServiceManager.startUser(msg.arg1);
2232 case SYSTEM_USER_UNLOCK_MSG: {
2233 final int userId = msg.arg1;
2234 mSystemServiceManager.unlockUser(userId);
2235 synchronized (ActivityManagerService.this) {
2236 mRecentTasks.loadUserRecentsLocked(userId);
2238 if (userId == UserHandle.USER_SYSTEM) {
2239 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2241 installEncryptionUnawareProviders(userId);
2242 mUserController.finishUserUnlocked((UserState) msg.obj);
2245 case SYSTEM_USER_CURRENT_MSG: {
2246 mBatteryStatsService.noteEvent(
2247 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2248 Integer.toString(msg.arg2), msg.arg2);
2249 mBatteryStatsService.noteEvent(
2250 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2251 Integer.toString(msg.arg1), msg.arg1);
2252 mSystemServiceManager.switchUser(msg.arg1);
2255 case ENTER_ANIMATION_COMPLETE_MSG: {
2256 synchronized (ActivityManagerService.this) {
2257 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2258 if (r != null && r.app != null && r.app.thread != null) {
2260 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2261 } catch (RemoteException e) {
2267 case FINISH_BOOTING_MSG: {
2268 if (msg.arg1 != 0) {
2269 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2271 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2273 if (msg.arg2 != 0) {
2274 enableScreenAfterBoot();
2278 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2280 Locale l = (Locale) msg.obj;
2281 IBinder service = ServiceManager.getService("mount");
2282 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2283 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2284 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2285 } catch (RemoteException e) {
2286 Log.e(TAG, "Error storing locale for decryption UI", e);
2290 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2291 final int uid = msg.arg1;
2292 final byte[] firstPacket = (byte[]) msg.obj;
2294 synchronized (mPidsSelfLocked) {
2295 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2296 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2299 p.thread.notifyCleartextNetwork(firstPacket);
2300 } catch (RemoteException ignored) {
2307 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2308 final String procName;
2310 final long memLimit;
2311 final String reportPackage;
2312 synchronized (ActivityManagerService.this) {
2313 procName = mMemWatchDumpProcName;
2314 uid = mMemWatchDumpUid;
2315 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2317 val = mMemWatchProcesses.get(procName, 0);
2320 memLimit = val.first;
2321 reportPackage = val.second;
2324 reportPackage = null;
2327 if (procName == null) {
2331 if (DEBUG_PSS) Slog.d(TAG_PSS,
2332 "Showing dump heap notification from " + procName + "/" + uid);
2334 INotificationManager inm = NotificationManager.getService();
2339 String text = mContext.getString(R.string.dump_heap_notification, procName);
2342 Intent deleteIntent = new Intent();
2343 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2344 Intent intent = new Intent();
2345 intent.setClassName("android", DumpHeapActivity.class.getName());
2346 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2347 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2348 if (reportPackage != null) {
2349 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2351 int userId = UserHandle.getUserId(uid);
2352 Notification notification =
2353 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2354 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2357 .setAutoCancel(true)
2359 .setColor(mContext.getColor(
2360 com.android.internal.R.color.system_notification_accent_color))
2361 .setContentTitle(text)
2363 mContext.getText(R.string.dump_heap_notification_detail))
2364 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2365 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2366 new UserHandle(userId)))
2367 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2368 deleteIntent, 0, UserHandle.SYSTEM))
2372 inm.enqueueNotificationWithTag("android", "android", null,
2373 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2374 notification, userId);
2375 } catch (RuntimeException e) {
2376 Slog.w(ActivityManagerService.TAG,
2377 "Error showing notification for dump heap", e);
2378 } catch (RemoteException e) {
2381 case DELETE_DUMPHEAP_MSG: {
2382 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2383 null, DumpHeapActivity.JAVA_URI,
2384 Intent.FLAG_GRANT_READ_URI_PERMISSION
2385 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2386 UserHandle.myUserId());
2387 synchronized (ActivityManagerService.this) {
2388 mMemWatchDumpFile = null;
2389 mMemWatchDumpProcName = null;
2390 mMemWatchDumpPid = -1;
2391 mMemWatchDumpUid = -1;
2394 case FOREGROUND_PROFILE_CHANGED_MSG: {
2395 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2397 case REPORT_TIME_TRACKER_MSG: {
2398 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2399 tracker.deliverResult(mContext);
2401 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2402 mUserController.dispatchUserSwitchComplete(msg.arg1);
2404 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2405 mUserController.dispatchLockedBootComplete(msg.arg1);
2407 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2408 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2410 connection.shutdown();
2411 } catch (RemoteException e) {
2412 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2414 // Only a UiAutomation can set this flag and now that
2415 // it is finished we make sure it is reset to its default.
2416 mUserIsMonkey = false;
2418 case IDLE_UIDS_MSG: {
2421 case VR_MODE_CHANGE_MSG: {
2422 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2425 synchronized (ActivityManagerService.this) {
2426 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2427 mWindowManager.disableNonVrUi(disableNonVrUi);
2428 if (disableNonVrUi) {
2429 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2430 // then remove the pinned stack.
2431 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2433 if (pinnedStack != null) {
2434 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2439 case NOTIFY_VR_SLEEPING_MSG: {
2440 notifyVrManagerOfSleepState(msg.arg1 != 0);
2442 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2443 synchronized (ActivityManagerService.this) {
2444 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2445 ProcessRecord r = mLruProcesses.get(i);
2446 if (r.thread != null) {
2448 r.thread.handleTrustStorageUpdate();
2449 } catch (RemoteException ex) {
2450 Slog.w(TAG, "Failed to handle trust storage update for: " +
2451 r.info.processName);
2461 static final int COLLECT_PSS_BG_MSG = 1;
2463 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2465 public void handleMessage(Message msg) {
2467 case COLLECT_PSS_BG_MSG: {
2468 long start = SystemClock.uptimeMillis();
2469 MemInfoReader memInfo = null;
2470 synchronized (ActivityManagerService.this) {
2471 if (mFullPssPending) {
2472 mFullPssPending = false;
2473 memInfo = new MemInfoReader();
2476 if (memInfo != null) {
2477 updateCpuStatsNow();
2478 long nativeTotalPss = 0;
2479 final List<ProcessCpuTracker.Stats> stats;
2480 synchronized (mProcessCpuTracker) {
2481 stats = mProcessCpuTracker.getStats( (st)-> {
2482 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2485 final int N = stats.size();
2486 for (int j = 0; j < N; j++) {
2487 synchronized (mPidsSelfLocked) {
2488 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2489 // This is one of our own processes; skip it.
2493 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2495 memInfo.readMemInfo();
2496 synchronized (ActivityManagerService.this) {
2497 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2498 + (SystemClock.uptimeMillis()-start) + "ms");
2499 final long cachedKb = memInfo.getCachedSizeKb();
2500 final long freeKb = memInfo.getFreeSizeKb();
2501 final long zramKb = memInfo.getZramTotalSizeKb();
2502 final long kernelKb = memInfo.getKernelUsedSizeKb();
2503 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2504 kernelKb*1024, nativeTotalPss*1024);
2505 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2511 long[] tmp = new long[2];
2517 synchronized (ActivityManagerService.this) {
2518 if (mPendingPssProcesses.size() <= 0) {
2519 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2520 "Collected PSS of " + num + " processes in "
2521 + (SystemClock.uptimeMillis() - start) + "ms");
2522 mPendingPssProcesses.clear();
2525 proc = mPendingPssProcesses.remove(0);
2526 procState = proc.pssProcState;
2527 lastPssTime = proc.lastPssTime;
2528 if (proc.thread != null && procState == proc.setProcState
2529 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2530 < SystemClock.uptimeMillis()) {
2538 long pss = Debug.getPss(pid, tmp, null);
2539 synchronized (ActivityManagerService.this) {
2540 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2541 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2543 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2544 SystemClock.uptimeMillis());
2554 public void setSystemProcess() {
2556 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2557 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2558 ServiceManager.addService("meminfo", new MemBinder(this));
2559 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2560 ServiceManager.addService("dbinfo", new DbBinder(this));
2561 if (MONITOR_CPU_USAGE) {
2562 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2564 ServiceManager.addService("permission", new PermissionController(this));
2565 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2567 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2568 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2569 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2571 synchronized (this) {
2572 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2573 app.persistent = true;
2575 app.maxAdj = ProcessList.SYSTEM_ADJ;
2576 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2577 synchronized (mPidsSelfLocked) {
2578 mPidsSelfLocked.put(app.pid, app);
2580 updateLruProcessLocked(app, false, null);
2581 updateOomAdjLocked();
2583 } catch (PackageManager.NameNotFoundException e) {
2584 throw new RuntimeException(
2585 "Unable to find android system package", e);
2589 public void setWindowManager(WindowManagerService wm) {
2590 mWindowManager = wm;
2591 mStackSupervisor.setWindowManager(wm);
2592 mActivityStarter.setWindowManager(wm);
2595 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2596 mUsageStatsService = usageStatsManager;
2599 public void startObservingNativeCrashes() {
2600 final NativeCrashListener ncl = new NativeCrashListener(this);
2604 public IAppOpsService getAppOpsService() {
2605 return mAppOpsService;
2608 static class MemBinder extends Binder {
2609 ActivityManagerService mActivityManagerService;
2610 MemBinder(ActivityManagerService activityManagerService) {
2611 mActivityManagerService = activityManagerService;
2615 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2616 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2617 "meminfo", pw)) return;
2618 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2622 static class GraphicsBinder extends Binder {
2623 ActivityManagerService mActivityManagerService;
2624 GraphicsBinder(ActivityManagerService activityManagerService) {
2625 mActivityManagerService = activityManagerService;
2629 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2630 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2631 "gfxinfo", pw)) return;
2632 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2636 static class DbBinder extends Binder {
2637 ActivityManagerService mActivityManagerService;
2638 DbBinder(ActivityManagerService activityManagerService) {
2639 mActivityManagerService = activityManagerService;
2643 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2644 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2645 "dbinfo", pw)) return;
2646 mActivityManagerService.dumpDbInfo(fd, pw, args);
2650 static class CpuBinder extends Binder {
2651 ActivityManagerService mActivityManagerService;
2652 CpuBinder(ActivityManagerService activityManagerService) {
2653 mActivityManagerService = activityManagerService;
2657 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2658 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2659 "cpuinfo", pw)) return;
2660 synchronized (mActivityManagerService.mProcessCpuTracker) {
2661 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2662 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2663 SystemClock.uptimeMillis()));
2668 public static final class Lifecycle extends SystemService {
2669 private final ActivityManagerService mService;
2671 public Lifecycle(Context context) {
2673 mService = new ActivityManagerService(context);
2677 public void onStart() {
2681 public ActivityManagerService getService() {
2687 public ActivityManagerService(Injector injector) {
2688 mInjector = injector;
2689 mContext = mInjector.getContext();
2692 mActivityStarter = null;
2694 mAppOpsService = mInjector.getAppOpsService(null, null);
2695 mBatteryStatsService = null;
2696 mCompatModePackages = null;
2700 mHandlerThread = null;
2701 mIntentFirewall = null;
2702 mKeyguardController = null;
2703 mPermissionReviewRequired = false;
2704 mProcessCpuThread = null;
2705 mProcessStats = null;
2706 mProviderMap = null;
2707 mRecentTasks = null;
2709 mStackSupervisor = null;
2710 mSystemThread = null;
2711 mTaskChangeNotificationController = null;
2712 mUiHandler = injector.getUiHandler(null);
2713 mUserController = null;
2714 mVrController = null;
2717 // Note: This method is invoked on the main thread but may need to attach various
2718 // handlers to other threads. So take care to be explicit about the looper.
2719 public ActivityManagerService(Context systemContext) {
2720 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2721 mInjector = new Injector();
2722 mContext = systemContext;
2724 mFactoryTest = FactoryTest.getMode();
2725 mSystemThread = ActivityThread.currentActivityThread();
2726 mUiContext = mSystemThread.getSystemUiContext();
2728 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2730 mPermissionReviewRequired = mContext.getResources().getBoolean(
2731 com.android.internal.R.bool.config_permissionReviewRequired);
2733 mHandlerThread = new ServiceThread(TAG,
2734 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2735 mHandlerThread.start();
2736 mHandler = new MainHandler(mHandlerThread.getLooper());
2737 mUiHandler = mInjector.getUiHandler(this);
2739 mConstants = new ActivityManagerConstants(this, mHandler);
2741 /* static; one-time init here */
2742 if (sKillHandler == null) {
2743 sKillThread = new ServiceThread(TAG + ":kill",
2744 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2745 sKillThread.start();
2746 sKillHandler = new KillHandler(sKillThread.getLooper());
2749 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2750 "foreground", BROADCAST_FG_TIMEOUT, false);
2751 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2752 "background", BROADCAST_BG_TIMEOUT, true);
2753 mBroadcastQueues[0] = mFgBroadcastQueue;
2754 mBroadcastQueues[1] = mBgBroadcastQueue;
2756 mServices = new ActiveServices(this);
2757 mProviderMap = new ProviderMap(this);
2758 mAppErrors = new AppErrors(mUiContext, this);
2760 // TODO: Move creation of battery stats service outside of activity manager service.
2761 File dataDir = Environment.getDataDirectory();
2762 File systemDir = new File(dataDir, "system");
2764 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2765 mBatteryStatsService.getActiveStatistics().readLocked();
2766 mBatteryStatsService.scheduleWriteToDisk();
2767 mOnBattery = DEBUG_POWER ? true
2768 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2769 mBatteryStatsService.getActiveStatistics().setCallback(this);
2771 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2773 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2774 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2775 new IAppOpsCallback.Stub() {
2776 @Override public void opChanged(int op, int uid, String packageName) {
2777 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2778 if (mAppOpsService.checkOperation(op, uid, packageName)
2779 != AppOpsManager.MODE_ALLOWED) {
2780 runInBackgroundDisabled(uid);
2786 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2788 mUserController = new UserController(this);
2790 mVrController = new VrController(this);
2792 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2793 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2795 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2796 mUseFifoUiScheduling = true;
2799 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2800 mTempConfig.setToDefaults();
2801 mTempConfig.setLocales(LocaleList.getDefault());
2802 mConfigurationSeq = mTempConfig.seq = 1;
2803 mStackSupervisor = createStackSupervisor();
2804 mStackSupervisor.onConfigurationChanged(mTempConfig);
2805 mKeyguardController = mStackSupervisor.mKeyguardController;
2806 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2807 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2808 mTaskChangeNotificationController =
2809 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2810 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2811 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2813 mProcessCpuThread = new Thread("CpuTracker") {
2816 synchronized (mProcessCpuTracker) {
2817 mProcessCpuInitLatch.countDown();
2818 mProcessCpuTracker.init();
2823 synchronized(this) {
2824 final long now = SystemClock.uptimeMillis();
2825 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2826 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2827 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2828 // + ", write delay=" + nextWriteDelay);
2829 if (nextWriteDelay < nextCpuDelay) {
2830 nextCpuDelay = nextWriteDelay;
2832 if (nextCpuDelay > 0) {
2833 mProcessCpuMutexFree.set(true);
2834 this.wait(nextCpuDelay);
2837 } catch (InterruptedException e) {
2839 updateCpuStatsNow();
2840 } catch (Exception e) {
2841 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2847 Watchdog.getInstance().addMonitor(this);
2848 Watchdog.getInstance().addThread(mHandler);
2851 protected ActivityStackSupervisor createStackSupervisor() {
2852 return new ActivityStackSupervisor(this, mHandler.getLooper());
2855 public void setSystemServiceManager(SystemServiceManager mgr) {
2856 mSystemServiceManager = mgr;
2859 public void setInstaller(Installer installer) {
2860 mInstaller = installer;
2863 private void start() {
2864 removeAllProcessGroups();
2865 mProcessCpuThread.start();
2867 mBatteryStatsService.publish(mContext);
2868 mAppOpsService.publish(mContext);
2869 Slog.d("AppOps", "AppOpsService published");
2870 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2871 // Wait for the synchronized block started in mProcessCpuThread,
2872 // so that any other acccess to mProcessCpuTracker from main thread
2873 // will be blocked during mProcessCpuTracker initialization.
2875 mProcessCpuInitLatch.await();
2876 } catch (InterruptedException e) {
2877 Slog.wtf(TAG, "Interrupted wait during start", e);
2878 Thread.currentThread().interrupt();
2879 throw new IllegalStateException("Interrupted wait during start");
2883 void onUserStoppedLocked(int userId) {
2884 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2887 public void initPowerManagement() {
2888 mStackSupervisor.initPowerManagement();
2889 mBatteryStatsService.initPowerManagement();
2890 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2891 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2892 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2893 mVoiceWakeLock.setReferenceCounted(false);
2896 private ArraySet<String> getBackgroundLaunchBroadcasts() {
2897 if (mBackgroundLaunchBroadcasts == null) {
2898 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2900 return mBackgroundLaunchBroadcasts;
2904 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2905 throws RemoteException {
2906 if (code == SYSPROPS_TRANSACTION) {
2907 // We need to tell all apps about the system property change.
2908 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2909 synchronized(this) {
2910 final int NP = mProcessNames.getMap().size();
2911 for (int ip=0; ip<NP; ip++) {
2912 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2913 final int NA = apps.size();
2914 for (int ia=0; ia<NA; ia++) {
2915 ProcessRecord app = apps.valueAt(ia);
2916 if (app.thread != null) {
2917 procs.add(app.thread.asBinder());
2923 int N = procs.size();
2924 for (int i=0; i<N; i++) {
2925 Parcel data2 = Parcel.obtain();
2927 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2928 Binder.FLAG_ONEWAY);
2929 } catch (RemoteException e) {
2935 return super.onTransact(code, data, reply, flags);
2936 } catch (RuntimeException e) {
2937 // The activity manager only throws security exceptions, so let's
2939 if (!(e instanceof SecurityException)) {
2940 Slog.wtf(TAG, "Activity Manager Crash."
2941 + " UID:" + Binder.getCallingUid()
2942 + " PID:" + Binder.getCallingPid()
2943 + " TRANS:" + code, e);
2949 void updateCpuStats() {
2950 final long now = SystemClock.uptimeMillis();
2951 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2954 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2955 synchronized (mProcessCpuThread) {
2956 mProcessCpuThread.notify();
2961 void updateCpuStatsNow() {
2962 synchronized (mProcessCpuTracker) {
2963 mProcessCpuMutexFree.set(false);
2964 final long now = SystemClock.uptimeMillis();
2965 boolean haveNewCpuStats = false;
2967 if (MONITOR_CPU_USAGE &&
2968 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2969 mLastCpuTime.set(now);
2970 mProcessCpuTracker.update();
2971 if (mProcessCpuTracker.hasGoodLastStats()) {
2972 haveNewCpuStats = true;
2973 //Slog.i(TAG, mProcessCpu.printCurrentState());
2974 //Slog.i(TAG, "Total CPU usage: "
2975 // + mProcessCpu.getTotalCpuPercent() + "%");
2977 // Slog the cpu usage if the property is set.
2978 if ("true".equals(SystemProperties.get("events.cpu"))) {
2979 int user = mProcessCpuTracker.getLastUserTime();
2980 int system = mProcessCpuTracker.getLastSystemTime();
2981 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2982 int irq = mProcessCpuTracker.getLastIrqTime();
2983 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2984 int idle = mProcessCpuTracker.getLastIdleTime();
2986 int total = user + system + iowait + irq + softIrq + idle;
2987 if (total == 0) total = 1;
2989 EventLog.writeEvent(EventLogTags.CPU,
2990 ((user+system+iowait+irq+softIrq) * 100) / total,
2991 (user * 100) / total,
2992 (system * 100) / total,
2993 (iowait * 100) / total,
2994 (irq * 100) / total,
2995 (softIrq * 100) / total);
3000 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3001 synchronized(bstats) {
3002 synchronized(mPidsSelfLocked) {
3003 if (haveNewCpuStats) {
3004 if (bstats.startAddingCpuLocked()) {
3007 final int N = mProcessCpuTracker.countStats();
3008 for (int i=0; i<N; i++) {
3009 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3013 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3014 totalUTime += st.rel_utime;
3015 totalSTime += st.rel_stime;
3017 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3018 if (ps == null || !ps.isActive()) {
3019 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3020 pr.info.uid, pr.processName);
3022 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3023 pr.curCpuTime += st.rel_utime + st.rel_stime;
3025 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3026 if (ps == null || !ps.isActive()) {
3027 st.batteryStats = ps = bstats.getProcessStatsLocked(
3028 bstats.mapUid(st.uid), st.name);
3030 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3033 final int userTime = mProcessCpuTracker.getLastUserTime();
3034 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3035 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3036 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3037 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3038 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3039 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3040 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3045 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3046 mLastWriteTime = now;
3047 mBatteryStatsService.scheduleWriteToDisk();
3054 public void batteryNeedsCpuUpdate() {
3055 updateCpuStatsNow();
3059 public void batteryPowerChanged(boolean onBattery) {
3060 // When plugging in, update the CPU stats first before changing
3062 updateCpuStatsNow();
3063 synchronized (this) {
3064 synchronized(mPidsSelfLocked) {
3065 mOnBattery = DEBUG_POWER ? true : onBattery;
3071 public void batterySendBroadcast(Intent intent) {
3072 synchronized (this) {
3073 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3074 AppOpsManager.OP_NONE, null, false, false,
3075 -1, SYSTEM_UID, UserHandle.USER_ALL);
3080 * Initialize the application bind args. These are passed to each
3081 * process when the bindApplication() IPC is sent to the process. They're
3082 * lazily setup to make sure the services are running when they're asked for.
3084 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3085 // Isolated processes won't get this optimization, so that we don't
3086 // violate the rules about which services they have access to.
3088 if (mIsolatedAppBindArgs == null) {
3089 mIsolatedAppBindArgs = new HashMap<>();
3090 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3092 return mIsolatedAppBindArgs;
3095 if (mAppBindArgs == null) {
3096 mAppBindArgs = new HashMap<>();
3098 // Setup the application init args
3099 mAppBindArgs.put("package", ServiceManager.getService("package"));
3100 mAppBindArgs.put("window", ServiceManager.getService("window"));
3101 mAppBindArgs.put(Context.ALARM_SERVICE,
3102 ServiceManager.getService(Context.ALARM_SERVICE));
3104 return mAppBindArgs;
3108 * Update AMS states when an activity is resumed. This should only be called by
3109 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3111 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3112 final TaskRecord task = r.getTask();
3113 if (task.isApplicationTask()) {
3114 if (mCurAppTimeTracker != r.appTimeTracker) {
3115 // We are switching app tracking. Complete the current one.
3116 if (mCurAppTimeTracker != null) {
3117 mCurAppTimeTracker.stop();
3118 mHandler.obtainMessage(
3119 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3120 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3121 mCurAppTimeTracker = null;
3123 if (r.appTimeTracker != null) {
3124 mCurAppTimeTracker = r.appTimeTracker;
3125 startTimeTrackingFocusedActivityLocked();
3128 startTimeTrackingFocusedActivityLocked();
3131 r.appTimeTracker = null;
3133 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3134 // TODO: Probably not, because we don't want to resume voice on switching
3135 // back to this activity
3136 if (task.voiceInteractor != null) {
3137 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3139 finishRunningVoiceLocked();
3141 if (mLastResumedActivity != null) {
3142 final IVoiceInteractionSession session;
3144 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3145 if (lastResumedActivityTask != null
3146 && lastResumedActivityTask.voiceSession != null) {
3147 session = lastResumedActivityTask.voiceSession;
3149 session = mLastResumedActivity.voiceSession;
3152 if (session != null) {
3153 // We had been in a voice interaction session, but now focused has
3154 // move to something different. Just finish the session, we can't
3155 // return to it and retain the proper state and synchronization with
3156 // the voice interaction service.
3157 finishVoiceTask(session);
3162 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3163 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3164 mHandler.obtainMessage(
3165 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3167 mLastResumedActivity = r;
3169 mWindowManager.setFocusedApp(r.appToken, true);
3171 applyUpdateLockStateLocked(r);
3172 applyUpdateVrModeLocked(r);
3174 EventLogTags.writeAmSetResumedActivity(
3175 r == null ? -1 : r.userId,
3176 r == null ? "NULL" : r.shortComponentName,
3181 public void setFocusedStack(int stackId) {
3182 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3183 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3184 final long callingId = Binder.clearCallingIdentity();
3186 synchronized (this) {
3187 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3188 if (stack == null) {
3191 final ActivityRecord r = stack.topRunningActivityLocked();
3192 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3193 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3197 Binder.restoreCallingIdentity(callingId);
3202 public void setFocusedTask(int taskId) {
3203 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3204 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3205 final long callingId = Binder.clearCallingIdentity();
3207 synchronized (this) {
3208 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3212 final ActivityRecord r = task.topRunningActivityLocked();
3213 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3214 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3218 Binder.restoreCallingIdentity(callingId);
3222 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3224 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3225 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3226 mTaskChangeNotificationController.registerTaskStackListener(listener);
3230 * Unregister a task stack listener so that it stops receiving callbacks.
3233 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3234 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3235 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3239 public void notifyActivityDrawn(IBinder token) {
3240 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3241 synchronized (this) {
3242 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3244 r.getStack().notifyActivityDrawnLocked(r);
3249 final void applyUpdateLockStateLocked(ActivityRecord r) {
3250 // Modifications to the UpdateLock state are done on our handler, outside
3251 // the activity manager's locks. The new state is determined based on the
3252 // state *now* of the relevant activity record. The object is passed to
3253 // the handler solely for logging detail, not to be consulted/modified.
3254 final boolean nextState = r != null && r.immersive;
3255 mHandler.sendMessage(
3256 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3259 final void applyUpdateVrModeLocked(ActivityRecord r) {
3260 mHandler.sendMessage(
3261 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3264 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3265 mHandler.sendMessage(
3266 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3269 private void notifyVrManagerOfSleepState(boolean isSleeping) {
3270 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3271 if (vrService == null) {
3274 vrService.onSleepStateChanged(isSleeping);
3277 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3278 Message msg = Message.obtain();
3279 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3280 msg.obj = r.getTask().askedCompatMode ? null : r;
3281 mUiHandler.sendMessage(msg);
3284 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3285 final Configuration globalConfig = getGlobalConfiguration();
3286 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3287 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3288 final Message msg = Message.obtain();
3289 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3291 mUiHandler.sendMessage(msg);
3295 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3296 String what, Object obj, ProcessRecord srcApp) {
3297 app.lastActivityTime = now;
3299 if (app.activities.size() > 0) {
3300 // Don't want to touch dependent processes that are hosting activities.
3304 int lrui = mLruProcesses.lastIndexOf(app);
3306 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3307 + what + " " + obj + " from " + srcApp);
3311 if (lrui >= index) {
3312 // Don't want to cause this to move dependent processes *back* in the
3313 // list as if they were less frequently used.
3317 if (lrui >= mLruProcessActivityStart) {
3318 // Don't want to touch dependent processes that are hosting activities.
3322 mLruProcesses.remove(lrui);
3326 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3327 + " in LRU list: " + app);
3328 mLruProcesses.add(index, app);
3332 static void killProcessGroup(int uid, int pid) {
3333 if (sKillHandler != null) {
3334 sKillHandler.sendMessage(
3335 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3337 Slog.w(TAG, "Asked to kill process group before system bringup!");
3338 Process.killProcessGroup(uid, pid);
3342 final void removeLruProcessLocked(ProcessRecord app) {
3343 int lrui = mLruProcesses.lastIndexOf(app);
3346 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3347 killProcessQuiet(app.pid);
3348 killProcessGroup(app.uid, app.pid);
3350 if (lrui <= mLruProcessActivityStart) {
3351 mLruProcessActivityStart--;
3353 if (lrui <= mLruProcessServiceStart) {
3354 mLruProcessServiceStart--;
3356 mLruProcesses.remove(lrui);
3360 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3361 ProcessRecord client) {
3362 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3363 || app.treatLikeActivity;
3364 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3365 if (!activityChange && hasActivity) {
3366 // The process has activities, so we are only allowing activity-based adjustments
3367 // to move it. It should be kept in the front of the list with other
3368 // processes that have activities, and we don't want those to change their
3369 // order except due to activity operations.
3374 final long now = SystemClock.uptimeMillis();
3375 app.lastActivityTime = now;
3377 // First a quick reject: if the app is already at the position we will
3378 // put it, then there is nothing to do.
3380 final int N = mLruProcesses.size();
3381 if (N > 0 && mLruProcesses.get(N-1) == app) {
3382 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3386 if (mLruProcessServiceStart > 0
3387 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3388 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3393 int lrui = mLruProcesses.lastIndexOf(app);
3395 if (app.persistent && lrui >= 0) {
3396 // We don't care about the position of persistent processes, as long as
3397 // they are in the list.
3398 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3402 /* In progress: compute new position first, so we can avoid doing work
3403 if the process is not actually going to move. Not yet working.
3406 boolean inActivity = false, inService = false;
3408 // Process has activities, put it at the very tipsy-top.
3409 addIndex = mLruProcesses.size();
3410 nextIndex = mLruProcessServiceStart;
3412 } else if (hasService) {
3413 // Process has services, put it at the top of the service list.
3414 addIndex = mLruProcessActivityStart;
3415 nextIndex = mLruProcessServiceStart;
3419 // Process not otherwise of interest, it goes to the top of the non-service area.
3420 addIndex = mLruProcessServiceStart;
3421 if (client != null) {
3422 int clientIndex = mLruProcesses.lastIndexOf(client);
3423 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3425 if (clientIndex >= 0 && addIndex > clientIndex) {
3426 addIndex = clientIndex;
3429 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3432 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3433 + mLruProcessActivityStart + "): " + app);
3437 if (lrui < mLruProcessActivityStart) {
3438 mLruProcessActivityStart--;
3440 if (lrui < mLruProcessServiceStart) {
3441 mLruProcessServiceStart--;
3444 if (addIndex > lrui) {
3447 if (nextIndex > lrui) {
3451 mLruProcesses.remove(lrui);
3455 mLruProcesses.add(addIndex, app);
3457 mLruProcessActivityStart++;
3460 mLruProcessActivityStart++;
3466 final int N = mLruProcesses.size();
3467 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3468 // Process doesn't have activities, but has clients with
3469 // activities... move it up, but one below the top (the top
3470 // should always have a real activity).
3471 if (DEBUG_LRU) Slog.d(TAG_LRU,
3472 "Adding to second-top of LRU activity list: " + app);
3473 mLruProcesses.add(N - 1, app);
3474 // To keep it from spamming the LRU list (by making a bunch of clients),
3475 // we will push down any other entries owned by the app.
3476 final int uid = app.info.uid;
3477 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3478 ProcessRecord subProc = mLruProcesses.get(i);
3479 if (subProc.info.uid == uid) {
3480 // We want to push this one down the list. If the process after
3481 // it is for the same uid, however, don't do so, because we don't
3482 // want them internally to be re-ordered.
3483 if (mLruProcesses.get(i - 1).info.uid != uid) {
3484 if (DEBUG_LRU) Slog.d(TAG_LRU,
3485 "Pushing uid " + uid + " swapping at " + i + ": "
3486 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3487 ProcessRecord tmp = mLruProcesses.get(i);
3488 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3489 mLruProcesses.set(i - 1, tmp);
3493 // A gap, we can stop here.
3498 // Process has activities, put it at the very tipsy-top.
3499 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3500 mLruProcesses.add(app);
3502 nextIndex = mLruProcessServiceStart;
3503 } else if (hasService) {
3504 // Process has services, put it at the top of the service list.
3505 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3506 mLruProcesses.add(mLruProcessActivityStart, app);
3507 nextIndex = mLruProcessServiceStart;
3508 mLruProcessActivityStart++;
3510 // Process not otherwise of interest, it goes to the top of the non-service area.
3511 int index = mLruProcessServiceStart;
3512 if (client != null) {
3513 // If there is a client, don't allow the process to be moved up higher
3514 // in the list than that client.
3515 int clientIndex = mLruProcesses.lastIndexOf(client);
3516 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3517 + " when updating " + app);
3518 if (clientIndex <= lrui) {
3519 // Don't allow the client index restriction to push it down farther in the
3520 // list than it already is.
3523 if (clientIndex >= 0 && index > clientIndex) {
3524 index = clientIndex;
3527 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3528 mLruProcesses.add(index, app);
3529 nextIndex = index-1;
3530 mLruProcessActivityStart++;
3531 mLruProcessServiceStart++;
3534 // If the app is currently using a content provider or service,
3535 // bump those processes as well.
3536 for (int j=app.connections.size()-1; j>=0; j--) {
3537 ConnectionRecord cr = app.connections.valueAt(j);
3538 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3539 && cr.binding.service.app != null
3540 && cr.binding.service.app.lruSeq != mLruSeq
3541 && !cr.binding.service.app.persistent) {
3542 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3543 "service connection", cr, app);
3546 for (int j=app.conProviders.size()-1; j>=0; j--) {
3547 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3548 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3549 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3550 "provider reference", cpr, app);
3555 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3556 if (uid == SYSTEM_UID) {
3557 // The system gets to run in any process. If there are multiple
3558 // processes with the same uid, just pick the first (this
3559 // should never happen).
3560 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3561 if (procs == null) return null;
3562 final int procCount = procs.size();
3563 for (int i = 0; i < procCount; i++) {
3564 final int procUid = procs.keyAt(i);
3565 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3566 // Don't use an app process or different user process for system component.
3569 return procs.valueAt(i);
3572 ProcessRecord proc = mProcessNames.get(processName, uid);
3573 if (false && proc != null && !keepIfLarge
3574 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3575 && proc.lastCachedPss >= 4000) {
3576 // Turn this condition on to cause killing to happen regularly, for testing.
3577 if (proc.baseProcessTracker != null) {
3578 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3580 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3581 } else if (proc != null && !keepIfLarge
3582 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3583 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3584 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3585 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3586 if (proc.baseProcessTracker != null) {
3587 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3589 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3595 void notifyPackageUse(String packageName, int reason) {
3596 IPackageManager pm = AppGlobals.getPackageManager();
3598 pm.notifyPackageUse(packageName, reason);
3599 } catch (RemoteException e) {
3603 boolean isNextTransitionForward() {
3604 int transit = mWindowManager.getPendingAppTransition();
3605 return transit == TRANSIT_ACTIVITY_OPEN
3606 || transit == TRANSIT_TASK_OPEN
3607 || transit == TRANSIT_TASK_TO_FRONT;
3610 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3611 String processName, String abiOverride, int uid, Runnable crashHandler) {
3612 synchronized(this) {
3613 ApplicationInfo info = new ApplicationInfo();
3614 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3615 // For isolated processes, the former contains the parent's uid and the latter the
3616 // actual uid of the isolated process.
3617 // In the special case introduced by this method (which is, starting an isolated
3618 // process directly from the SystemServer without an actual parent app process) the
3619 // closest thing to a parent's uid is SYSTEM_UID.
3620 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3621 // the |isolated| logic in the ProcessRecord constructor.
3622 info.uid = SYSTEM_UID;
3623 info.processName = processName;
3624 info.className = entryPoint;
3625 info.packageName = "android";
3626 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3627 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3628 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3629 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3630 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3632 return proc != null ? proc.pid : 0;
3636 final ProcessRecord startProcessLocked(String processName,
3637 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3638 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3639 boolean isolated, boolean keepIfLarge) {
3640 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3641 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3642 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3643 null /* crashHandler */);
3646 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3647 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3648 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3649 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3650 long startTime = SystemClock.elapsedRealtime();
3653 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3654 checkTime(startTime, "startProcess: after getProcessRecord");
3656 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3657 // If we are in the background, then check to see if this process
3658 // is bad. If so, we will just silently fail.
3659 if (mAppErrors.isBadProcessLocked(info)) {
3660 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3661 + "/" + info.processName);
3665 // When the user is explicitly starting a process, then clear its
3666 // crash count so that we won't make it bad until they see at
3667 // least one crash dialog again, and make the process good again
3668 // if it had been bad.
3669 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3670 + "/" + info.processName);
3671 mAppErrors.resetProcessCrashTimeLocked(info);
3672 if (mAppErrors.isBadProcessLocked(info)) {
3673 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3674 UserHandle.getUserId(info.uid), info.uid,
3676 mAppErrors.clearBadProcessLocked(info);
3683 // If this is an isolated process, it can't re-use an existing process.
3687 // We don't have to do anything more if:
3688 // (1) There is an existing application record; and
3689 // (2) The caller doesn't think it is dead, OR there is no thread
3690 // object attached to it so we know it couldn't have crashed; and
3691 // (3) There is a pid assigned to it, so it is either starting or
3693 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3694 + " app=" + app + " knownToBeDead=" + knownToBeDead
3695 + " thread=" + (app != null ? app.thread : null)
3696 + " pid=" + (app != null ? app.pid : -1));
3697 if (app != null && app.pid > 0) {
3698 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3699 // We already have the app running, or are waiting for it to
3700 // come up (we have a pid but not yet its thread), so keep it.
3701 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3702 // If this is a new package in the process, add the package to the list
3703 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3704 checkTime(startTime, "startProcess: done, added package to proc");
3708 // An application record is attached to a previous process,
3710 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3711 checkTime(startTime, "startProcess: bad proc running, killing");
3712 killProcessGroup(app.uid, app.pid);
3713 handleAppDiedLocked(app, true, true);
3714 checkTime(startTime, "startProcess: done killing old proc");
3717 String hostingNameStr = hostingName != null
3718 ? hostingName.flattenToShortString() : null;
3721 checkTime(startTime, "startProcess: creating new process record");
3722 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3724 Slog.w(TAG, "Failed making new process record for "
3725 + processName + "/" + info.uid + " isolated=" + isolated);
3728 app.crashHandler = crashHandler;
3729 checkTime(startTime, "startProcess: done creating new process record");
3731 // If this is a new package in the process, add the package to the list
3732 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3733 checkTime(startTime, "startProcess: added package to existing proc");
3736 // If the system is not ready yet, then hold off on starting this
3737 // process until it is.
3738 if (!mProcessesReady
3739 && !isAllowedWhileBooting(info)
3740 && !allowWhileBooting) {
3741 if (!mProcessesOnHold.contains(app)) {
3742 mProcessesOnHold.add(app);
3744 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3745 "System not ready, putting on hold: " + app);
3746 checkTime(startTime, "startProcess: returning with proc on hold");
3750 checkTime(startTime, "startProcess: stepping in to startProcess");
3752 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3753 checkTime(startTime, "startProcess: done starting proc!");
3754 return (app.pid != 0) ? app : null;
3757 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3758 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3761 private final void startProcessLocked(ProcessRecord app,
3762 String hostingType, String hostingNameStr) {
3763 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3764 null /* entryPoint */, null /* entryPointArgs */);
3767 private final void startProcessLocked(ProcessRecord app, String hostingType,
3768 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3769 long startTime = SystemClock.elapsedRealtime();
3770 if (app.pid > 0 && app.pid != MY_PID) {
3771 checkTime(startTime, "startProcess: removing from pids map");
3772 synchronized (mPidsSelfLocked) {
3773 mPidsSelfLocked.remove(app.pid);
3774 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3776 checkTime(startTime, "startProcess: done removing from pids map");
3780 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3781 "startProcessLocked removing on hold: " + app);
3782 mProcessesOnHold.remove(app);
3784 checkTime(startTime, "startProcess: starting to update cpu stats");
3786 checkTime(startTime, "startProcess: done updating cpu stats");
3790 final int userId = UserHandle.getUserId(app.uid);
3791 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3792 } catch (RemoteException e) {
3793 throw e.rethrowAsRuntimeException();
3798 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3799 if (!app.isolated) {
3800 int[] permGids = null;
3802 checkTime(startTime, "startProcess: getting gids from package manager");
3803 final IPackageManager pm = AppGlobals.getPackageManager();
3804 permGids = pm.getPackageGids(app.info.packageName,
3805 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3806 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3807 StorageManagerInternal.class);
3808 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3809 app.info.packageName);
3810 } catch (RemoteException e) {
3811 throw e.rethrowAsRuntimeException();
3815 * Add shared application and profile GIDs so applications can share some
3816 * resources like shared libraries and access user-wide resources
3818 if (ArrayUtils.isEmpty(permGids)) {
3821 gids = new int[permGids.length + 3];
3822 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3824 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3825 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3826 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3828 checkTime(startTime, "startProcess: building args");
3829 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3830 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3831 && mTopComponent != null
3832 && app.processName.equals(mTopComponent.getPackageName())) {
3835 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3836 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3841 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3842 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3843 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3844 // Also turn on CheckJNI for debuggable apps. It's quite
3845 // awkward to turn on otherwise.
3846 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3848 // Run the app in safe mode if its manifest requests so or the
3849 // system is booted in safe mode.
3850 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3851 mSafeMode == true) {
3852 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3854 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3855 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3857 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3858 if ("true".equals(genDebugInfoProperty)) {
3859 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3861 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3862 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3864 if ("1".equals(SystemProperties.get("debug.assert"))) {
3865 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3867 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3868 // Enable all debug flags required by the native debugger.
3869 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3870 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3871 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3872 mNativeDebuggingApp = null;
3875 String invokeWith = null;
3876 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3877 // Debuggable apps may include a wrapper script with their library directory.
3878 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3879 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3881 if (new File(wrapperFileName).exists()) {
3882 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3885 StrictMode.setThreadPolicy(oldPolicy);
3889 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3890 if (requiredAbi == null) {
3891 requiredAbi = Build.SUPPORTED_ABIS[0];
3894 String instructionSet = null;
3895 if (app.info.primaryCpuAbi != null) {
3896 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3900 app.requiredAbi = requiredAbi;
3901 app.instructionSet = instructionSet;
3903 // the per-user SELinux context must be set
3904 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3905 Slog.wtf(TAG, "SELinux tag not defined",
3906 new IllegalStateException("SELinux tag not defined for "
3907 + app.info.packageName + " (uid " + app.uid + ")"));
3909 final String seInfo = app.info.seInfo
3910 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3911 // Start the process. It will either succeed and return a result containing
3912 // the PID of the new process, or else throw a RuntimeException.
3913 boolean isActivityProcess = (entryPoint == null);
3914 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3915 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3917 checkTime(startTime, "startProcess: asking zygote to start proc");
3918 ProcessStartResult startResult;
3919 if (hostingType.equals("webview_service")) {
3920 startResult = startWebView(entryPoint,
3921 app.processName, uid, uid, gids, debugFlags, mountExternal,
3922 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3923 app.info.dataDir, null, entryPointArgs);
3925 startResult = Process.start(entryPoint,
3926 app.processName, uid, uid, gids, debugFlags, mountExternal,
3927 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3928 app.info.dataDir, invokeWith, entryPointArgs);
3930 checkTime(startTime, "startProcess: returned from zygote!");
3931 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3933 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3934 checkTime(startTime, "startProcess: done updating battery stats");
3936 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3937 UserHandle.getUserId(uid), startResult.pid, uid,
3938 app.processName, hostingType,
3939 hostingNameStr != null ? hostingNameStr : "");
3942 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3943 seInfo, app.info.sourceDir, startResult.pid);
3944 } catch (RemoteException ex) {
3948 if (app.persistent) {
3949 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3952 checkTime(startTime, "startProcess: building log message");
3953 StringBuilder buf = mStringBuilder;
3955 buf.append("Start proc ");
3956 buf.append(startResult.pid);
3958 buf.append(app.processName);
3960 UserHandle.formatUid(buf, uid);
3961 if (!isActivityProcess) {
3963 buf.append(entryPoint);
3966 buf.append(" for ");
3967 buf.append(hostingType);
3968 if (hostingNameStr != null) {
3970 buf.append(hostingNameStr);
3972 Slog.i(TAG, buf.toString());
3973 app.setPid(startResult.pid);
3974 app.usingWrapper = startResult.usingWrapper;
3975 app.removed = false;
3977 app.killedByAm = false;
3978 checkTime(startTime, "startProcess: starting to update pids map");
3979 ProcessRecord oldApp;
3980 synchronized (mPidsSelfLocked) {
3981 oldApp = mPidsSelfLocked.get(startResult.pid);
3983 // If there is already an app occupying that pid that hasn't been cleaned up
3984 if (oldApp != null && !app.isolated) {
3985 // Clean up anything relating to this pid first
3986 Slog.w(TAG, "Reusing pid " + startResult.pid
3987 + " while app is still mapped to it");
3988 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3989 true /*replacingPid*/);
3991 synchronized (mPidsSelfLocked) {
3992 this.mPidsSelfLocked.put(startResult.pid, app);
3993 if (isActivityProcess) {
3994 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3996 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3997 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4000 checkTime(startTime, "startProcess: done updating pids map");
4001 } catch (RuntimeException e) {
4002 Slog.e(TAG, "Failure starting process " + app.processName, e);
4004 // Something went very wrong while trying to start this process; one
4005 // common case is when the package is frozen due to an active
4006 // upgrade. To recover, clean up any active bookkeeping related to
4007 // starting this process. (We already invoked this method once when
4008 // the package was initially frozen through KILL_APPLICATION_MSG, so
4009 // it doesn't hurt to use it again.)
4010 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4011 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4015 void updateUsageStats(ActivityRecord component, boolean resumed) {
4016 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4017 "updateUsageStats: comp=" + component + "res=" + resumed);
4018 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4020 if (mUsageStatsService != null) {
4021 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4022 UsageEvents.Event.MOVE_TO_FOREGROUND);
4024 synchronized (stats) {
4025 stats.noteActivityResumedLocked(component.app.uid);
4028 if (mUsageStatsService != null) {
4029 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4030 UsageEvents.Event.MOVE_TO_BACKGROUND);
4032 synchronized (stats) {
4033 stats.noteActivityPausedLocked(component.app.uid);
4038 Intent getHomeIntent() {
4039 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4040 intent.setComponent(mTopComponent);
4041 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4042 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4043 intent.addCategory(Intent.CATEGORY_HOME);
4048 boolean startHomeActivityLocked(int userId, String reason) {
4049 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4050 && mTopAction == null) {
4051 // We are running in factory test mode, but unable to find
4052 // the factory test app, so just sit around displaying the
4053 // error message and don't try to start anything.
4056 Intent intent = getHomeIntent();
4057 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4058 if (aInfo != null) {
4059 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4060 // Don't do this if the home app is currently being
4062 aInfo = new ActivityInfo(aInfo);
4063 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4064 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4065 aInfo.applicationInfo.uid, true);
4066 if (app == null || app.instr == null) {
4067 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4068 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4069 // For ANR debugging to verify if the user activity is the one that actually
4071 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4072 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4075 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4081 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4082 ActivityInfo ai = null;
4083 ComponentName comp = intent.getComponent();
4087 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4089 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4091 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4095 ai = info.activityInfo;
4098 } catch (RemoteException e) {
4106 * Starts the "new version setup screen" if appropriate.
4108 void startSetupActivityLocked() {
4109 // Only do this once per boot.
4110 if (mCheckedForSetup) {
4114 // We will show this screen if the current one is a different
4115 // version than the last one shown, and we are not running in
4116 // low-level factory test mode.
4117 final ContentResolver resolver = mContext.getContentResolver();
4118 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4119 Settings.Global.getInt(resolver,
4120 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4121 mCheckedForSetup = true;
4123 // See if we should be showing the platform update setup UI.
4124 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4125 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4126 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4127 if (!ris.isEmpty()) {
4128 final ResolveInfo ri = ris.get(0);
4129 String vers = ri.activityInfo.metaData != null
4130 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4132 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4133 vers = ri.activityInfo.applicationInfo.metaData.getString(
4134 Intent.METADATA_SETUP_VERSION);
4136 String lastVers = Settings.Secure.getString(
4137 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4138 if (vers != null && !vers.equals(lastVers)) {
4139 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4140 intent.setComponent(new ComponentName(
4141 ri.activityInfo.packageName, ri.activityInfo.name));
4142 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4143 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4144 null, 0, 0, 0, null, false, false, null, null, null,
4145 "startSetupActivity");
4151 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4152 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4155 void enforceNotIsolatedCaller(String caller) {
4156 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4157 throw new SecurityException("Isolated process not allowed to call " + caller);
4161 void enforceShellRestriction(String restriction, int userHandle) {
4162 if (Binder.getCallingUid() == SHELL_UID) {
4163 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4164 throw new SecurityException("Shell does not have permission to access user "
4171 public int getFrontActivityScreenCompatMode() {
4172 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4173 synchronized (this) {
4174 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4179 public void setFrontActivityScreenCompatMode(int mode) {
4180 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4181 "setFrontActivityScreenCompatMode");
4182 synchronized (this) {
4183 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4188 public int getPackageScreenCompatMode(String packageName) {
4189 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4190 synchronized (this) {
4191 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4196 public void setPackageScreenCompatMode(String packageName, int mode) {
4197 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4198 "setPackageScreenCompatMode");
4199 synchronized (this) {
4200 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4205 public boolean getPackageAskScreenCompat(String packageName) {
4206 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4207 synchronized (this) {
4208 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4213 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4214 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4215 "setPackageAskScreenCompat");
4216 synchronized (this) {
4217 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4221 private boolean hasUsageStatsPermission(String callingPackage) {
4222 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4223 Binder.getCallingUid(), callingPackage);
4224 if (mode == AppOpsManager.MODE_DEFAULT) {
4225 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4226 == PackageManager.PERMISSION_GRANTED;
4228 return mode == AppOpsManager.MODE_ALLOWED;
4232 public int getPackageProcessState(String packageName, String callingPackage) {
4233 if (!hasUsageStatsPermission(callingPackage)) {
4234 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4235 "getPackageProcessState");
4238 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4239 synchronized (this) {
4240 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4241 final ProcessRecord proc = mLruProcesses.get(i);
4242 if (procState > proc.setProcState) {
4243 if (proc.pkgList.containsKey(packageName) ||
4244 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4245 procState = proc.setProcState;
4254 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4255 throws RemoteException {
4256 synchronized (this) {
4257 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4259 throw new IllegalArgumentException("Unknown process: " + process);
4261 if (app.thread == null) {
4262 throw new IllegalArgumentException("Process has no app thread");
4264 if (app.trimMemoryLevel >= level) {
4265 throw new IllegalArgumentException(
4266 "Unable to set a higher trim level than current level");
4268 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4269 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4270 throw new IllegalArgumentException("Unable to set a background trim level "
4271 + "on a foreground process");
4273 app.thread.scheduleTrimMemory(level);
4274 app.trimMemoryLevel = level;
4279 private void dispatchProcessesChanged() {
4281 synchronized (this) {
4282 N = mPendingProcessChanges.size();
4283 if (mActiveProcessChanges.length < N) {
4284 mActiveProcessChanges = new ProcessChangeItem[N];
4286 mPendingProcessChanges.toArray(mActiveProcessChanges);
4287 mPendingProcessChanges.clear();
4288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4289 "*** Delivering " + N + " process changes");
4292 int i = mProcessObservers.beginBroadcast();
4295 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4296 if (observer != null) {
4298 for (int j=0; j<N; j++) {
4299 ProcessChangeItem item = mActiveProcessChanges[j];
4300 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4301 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4302 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4303 + item.uid + ": " + item.foregroundActivities);
4304 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4305 item.foregroundActivities);
4308 } catch (RemoteException e) {
4312 mProcessObservers.finishBroadcast();
4314 synchronized (this) {
4315 for (int j=0; j<N; j++) {
4316 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4321 private void dispatchProcessDied(int pid, int uid) {
4322 int i = mProcessObservers.beginBroadcast();
4325 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4326 if (observer != null) {
4328 observer.onProcessDied(pid, uid);
4329 } catch (RemoteException e) {
4333 mProcessObservers.finishBroadcast();
4337 void dispatchUidsChanged() {
4339 synchronized (this) {
4340 N = mPendingUidChanges.size();
4341 if (mActiveUidChanges.length < N) {
4342 mActiveUidChanges = new UidRecord.ChangeItem[N];
4344 for (int i=0; i<N; i++) {
4345 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4346 mActiveUidChanges[i] = change;
4347 if (change.uidRecord != null) {
4348 change.uidRecord.pendingChange = null;
4349 change.uidRecord = null;
4352 mPendingUidChanges.clear();
4353 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4354 "*** Delivering " + N + " uid changes");
4357 int i = mUidObservers.beginBroadcast();
4360 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4361 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4363 mUidObservers.finishBroadcast();
4365 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4366 for (int j = 0; j < N; ++j) {
4367 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4368 if (item.change == UidRecord.CHANGE_GONE
4369 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4370 mValidateUids.remove(item.uid);
4372 UidRecord validateUid = mValidateUids.get(item.uid);
4373 if (validateUid == null) {
4374 validateUid = new UidRecord(item.uid);
4375 mValidateUids.put(item.uid, validateUid);
4377 if (item.change == UidRecord.CHANGE_IDLE) {
4378 validateUid.idle = true;
4379 } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4380 validateUid.idle = false;
4382 validateUid.curProcState = validateUid.setProcState = item.processState;
4383 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4388 synchronized (this) {
4389 for (int j = 0; j < N; j++) {
4390 mAvailUidChanges.add(mActiveUidChanges[j]);
4395 private void dispatchUidsChangedForObserver(IUidObserver observer,
4396 UidObserverRegistration reg, int changesSize) {
4397 if (observer == null) {
4401 for (int j = 0; j < changesSize; j++) {
4402 UidRecord.ChangeItem item = mActiveUidChanges[j];
4403 final int change = item.change;
4404 if (change == UidRecord.CHANGE_IDLE
4405 || change == UidRecord.CHANGE_GONE_IDLE) {
4406 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4407 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4408 "UID idle uid=" + item.uid);
4409 observer.onUidIdle(item.uid, item.ephemeral);
4411 } else if (change == UidRecord.CHANGE_ACTIVE) {
4412 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4413 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4414 "UID active uid=" + item.uid);
4415 observer.onUidActive(item.uid);
4418 if (change == UidRecord.CHANGE_GONE
4419 || change == UidRecord.CHANGE_GONE_IDLE) {
4420 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4421 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422 "UID gone uid=" + item.uid);
4423 observer.onUidGone(item.uid, item.ephemeral);
4425 if (reg.lastProcStates != null) {
4426 reg.lastProcStates.delete(item.uid);
4429 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4430 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4431 "UID CHANGED uid=" + item.uid
4432 + ": " + item.processState);
4433 boolean doReport = true;
4434 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4435 final int lastState = reg.lastProcStates.get(item.uid,
4436 ActivityManager.PROCESS_STATE_UNKNOWN);
4437 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4438 final boolean lastAboveCut = lastState <= reg.cutpoint;
4439 final boolean newAboveCut = item.processState <= reg.cutpoint;
4440 doReport = lastAboveCut != newAboveCut;
4442 doReport = item.processState
4443 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4447 if (reg.lastProcStates != null) {
4448 reg.lastProcStates.put(item.uid, item.processState);
4450 observer.onUidStateChanged(item.uid, item.processState,
4456 } catch (RemoteException e) {
4461 public final int startActivity(IApplicationThread caller, String callingPackage,
4462 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4463 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4464 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4465 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4466 UserHandle.getCallingUserId());
4469 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4470 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4471 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4472 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4473 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4475 // TODO: Switch to user app stacks here.
4476 String mimeType = intent.getType();
4477 final Uri data = intent.getData();
4478 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4479 mimeType = getProviderMimeType(data, userId);
4481 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4483 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4484 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
4485 null, null, 0, 0, null, null, null, null, false, userId, container, null,
4490 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4491 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4492 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4493 enforceNotIsolatedCaller("startActivity");
4494 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4495 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4496 // TODO: Switch to user app stacks here.
4497 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4498 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4499 profilerInfo, null, null, bOptions, false, userId, null, null,
4500 "startActivityAsUser");
4504 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4505 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4506 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4509 // This is very dangerous -- it allows you to perform a start activity (including
4510 // permission grants) as any app that may launch one of your own activities. So
4511 // we will only allow this to be done from activities that are part of the core framework,
4512 // and then only when they are running as the system.
4513 final ActivityRecord sourceRecord;
4514 final int targetUid;
4515 final String targetPackage;
4516 synchronized (this) {
4517 if (resultTo == null) {
4518 throw new SecurityException("Must be called from an activity");
4520 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4521 if (sourceRecord == null) {
4522 throw new SecurityException("Called with bad activity token: " + resultTo);
4524 if (!sourceRecord.info.packageName.equals("android")) {
4525 throw new SecurityException(
4526 "Must be called from an activity that is declared in the android package");
4528 if (sourceRecord.app == null) {
4529 throw new SecurityException("Called without a process attached to activity");
4531 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4532 // This is still okay, as long as this activity is running under the
4533 // uid of the original calling activity.
4534 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4535 throw new SecurityException(
4536 "Calling activity in uid " + sourceRecord.app.uid
4537 + " must be system uid or original calling uid "
4538 + sourceRecord.launchedFromUid);
4541 if (ignoreTargetSecurity) {
4542 if (intent.getComponent() == null) {
4543 throw new SecurityException(
4544 "Component must be specified with ignoreTargetSecurity");
4546 if (intent.getSelector() != null) {
4547 throw new SecurityException(
4548 "Selector not allowed with ignoreTargetSecurity");
4551 targetUid = sourceRecord.launchedFromUid;
4552 targetPackage = sourceRecord.launchedFromPackage;
4555 if (userId == UserHandle.USER_NULL) {
4556 userId = UserHandle.getUserId(sourceRecord.app.uid);
4559 // TODO: Switch to user app stacks here.
4561 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4562 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4563 null, null, bOptions, ignoreTargetSecurity, userId, null, null,
4564 "startActivityAsCaller");
4566 } catch (SecurityException e) {
4567 // XXX need to figure out how to propagate to original app.
4568 // A SecurityException here is generally actually a fault of the original
4569 // calling activity (such as a fairly granting permissions), so propagate it
4572 StringBuilder msg = new StringBuilder();
4573 msg.append("While launching");
4574 msg.append(intent.toString());
4576 msg.append(e.getMessage());
4583 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4584 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4585 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4586 enforceNotIsolatedCaller("startActivityAndWait");
4587 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4588 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4589 WaitResult res = new WaitResult();
4590 // TODO: Switch to user app stacks here.
4591 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4592 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4593 bOptions, false, userId, null, null, "startActivityAndWait");
4598 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4599 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4600 int startFlags, Configuration config, Bundle bOptions, int userId) {
4601 enforceNotIsolatedCaller("startActivityWithConfig");
4602 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4603 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4604 // TODO: Switch to user app stacks here.
4605 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4606 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4607 null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
4612 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4613 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4614 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4615 throws TransactionTooLargeException {
4616 enforceNotIsolatedCaller("startActivityIntentSender");
4617 // Refuse possible leaked file descriptors
4618 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4619 throw new IllegalArgumentException("File descriptors passed in Intent");
4622 if (!(target instanceof PendingIntentRecord)) {
4623 throw new IllegalArgumentException("Bad PendingIntent object");
4626 PendingIntentRecord pir = (PendingIntentRecord)target;
4628 synchronized (this) {
4629 // If this is coming from the currently resumed activity, it is
4630 // effectively saying that app switches are allowed at this point.
4631 final ActivityStack stack = getFocusedStack();
4632 if (stack.mResumedActivity != null &&
4633 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4634 mAppSwitchesAllowedTime = 0;
4637 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4638 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4643 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4644 Intent intent, String resolvedType, IVoiceInteractionSession session,
4645 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4646 Bundle bOptions, int userId) {
4647 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4648 != PackageManager.PERMISSION_GRANTED) {
4649 String msg = "Permission Denial: startVoiceActivity() from pid="
4650 + Binder.getCallingPid()
4651 + ", uid=" + Binder.getCallingUid()
4652 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4654 throw new SecurityException(msg);
4656 if (session == null || interactor == null) {
4657 throw new NullPointerException("null session or interactor");
4659 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4660 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4661 // TODO: Switch to user app stacks here.
4662 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4663 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4664 null, bOptions, false, userId, null, null, "startVoiceActivity");
4668 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4669 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4670 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4671 != PackageManager.PERMISSION_GRANTED) {
4672 final String msg = "Permission Denial: startAssistantActivity() from pid="
4673 + Binder.getCallingPid()
4674 + ", uid=" + Binder.getCallingUid()
4675 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4677 throw new SecurityException(msg);
4679 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4680 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4681 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4682 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4683 userId, null, null, "startAssistantActivity");
4687 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4688 throws RemoteException {
4689 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4690 synchronized (this) {
4691 ActivityRecord activity = getFocusedStack().topActivity();
4692 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4693 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4695 if (mRunningVoice != null || activity.getTask().voiceSession != null
4696 || activity.voiceSession != null) {
4697 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4700 if (activity.pendingVoiceInteractionStart) {
4701 Slog.w(TAG, "Pending start of voice interaction already.");
4704 activity.pendingVoiceInteractionStart = true;
4706 LocalServices.getService(VoiceInteractionManagerInternal.class)
4707 .startLocalVoiceInteraction(callingActivity, options);
4711 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4712 LocalServices.getService(VoiceInteractionManagerInternal.class)
4713 .stopLocalVoiceInteraction(callingActivity);
4717 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4718 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4719 .supportsLocalVoiceInteraction();
4722 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4723 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4724 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4725 if (activityToCallback == null) return;
4726 activityToCallback.setVoiceSessionLocked(voiceSession);
4728 // Inform the activity
4730 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4732 long token = Binder.clearCallingIdentity();
4734 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4736 Binder.restoreCallingIdentity(token);
4738 // TODO: VI Should we cache the activity so that it's easier to find later
4739 // rather than scan through all the stacks and activities?
4740 } catch (RemoteException re) {
4741 activityToCallback.clearVoiceSessionLocked();
4742 // TODO: VI Should this terminate the voice session?
4747 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4748 synchronized (this) {
4749 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4751 mVoiceWakeLock.acquire();
4753 mVoiceWakeLock.release();
4760 public boolean startNextMatchingActivity(IBinder callingActivity,
4761 Intent intent, Bundle bOptions) {
4762 // Refuse possible leaked file descriptors
4763 if (intent != null && intent.hasFileDescriptors() == true) {
4764 throw new IllegalArgumentException("File descriptors passed in Intent");
4766 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4768 synchronized (this) {
4769 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4771 ActivityOptions.abort(options);
4774 if (r.app == null || r.app.thread == null) {
4775 // The caller is not running... d'oh!
4776 ActivityOptions.abort(options);
4779 intent = new Intent(intent);
4780 // The caller is not allowed to change the data.
4781 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4782 // And we are resetting to find the next component...
4783 intent.setComponent(null);
4785 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4787 ActivityInfo aInfo = null;
4789 List<ResolveInfo> resolves =
4790 AppGlobals.getPackageManager().queryIntentActivities(
4791 intent, r.resolvedType,
4792 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4793 UserHandle.getCallingUserId()).getList();
4795 // Look for the original activity in the list...
4796 final int N = resolves != null ? resolves.size() : 0;
4797 for (int i=0; i<N; i++) {
4798 ResolveInfo rInfo = resolves.get(i);
4799 if (rInfo.activityInfo.packageName.equals(r.packageName)
4800 && rInfo.activityInfo.name.equals(r.info.name)) {
4801 // We found the current one... the next matching is
4805 aInfo = resolves.get(i).activityInfo;
4808 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4809 + "/" + r.info.name);
4810 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4811 ? "null" : aInfo.packageName + "/" + aInfo.name));
4816 } catch (RemoteException e) {
4819 if (aInfo == null) {
4820 // Nobody who is next!
4821 ActivityOptions.abort(options);
4822 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4826 intent.setComponent(new ComponentName(
4827 aInfo.applicationInfo.packageName, aInfo.name));
4828 intent.setFlags(intent.getFlags()&~(
4829 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4830 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4831 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4832 Intent.FLAG_ACTIVITY_NEW_TASK));
4834 // Okay now we need to start the new activity, replacing the
4835 // currently running activity. This is a little tricky because
4836 // we want to start the new one as if the current one is finished,
4837 // but not finish the current one first so that there is no flicker.
4839 final boolean wasFinishing = r.finishing;
4842 // Propagate reply information over to the new activity.
4843 final ActivityRecord resultTo = r.resultTo;
4844 final String resultWho = r.resultWho;
4845 final int requestCode = r.requestCode;
4847 if (resultTo != null) {
4848 resultTo.removeResultsLocked(r, resultWho, requestCode);
4851 final long origId = Binder.clearCallingIdentity();
4852 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4853 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4854 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4855 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4856 false, false, null, null, null, "startNextMatchingActivity");
4857 Binder.restoreCallingIdentity(origId);
4859 r.finishing = wasFinishing;
4860 if (res != ActivityManager.START_SUCCESS) {
4868 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4869 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4870 String msg = "Permission Denial: startActivityFromRecents called without " +
4871 START_TASKS_FROM_RECENTS;
4873 throw new SecurityException(msg);
4875 final long origId = Binder.clearCallingIdentity();
4877 synchronized (this) {
4878 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4881 Binder.restoreCallingIdentity(origId);
4885 final int startActivityInPackage(int uid, String callingPackage,
4886 Intent intent, String resolvedType, IBinder resultTo,
4887 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4888 IActivityContainer container, TaskRecord inTask, String reason) {
4890 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4891 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4893 // TODO: Switch to user app stacks here.
4894 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4895 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4896 null, null, null, bOptions, false, userId, container, inTask, reason);
4901 public final int startActivities(IApplicationThread caller, String callingPackage,
4902 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4904 final String reason = "startActivities";
4905 enforceNotIsolatedCaller(reason);
4906 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4907 userId, false, ALLOW_FULL_ONLY, reason, null);
4908 // TODO: Switch to user app stacks here.
4909 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4910 resolvedTypes, resultTo, bOptions, userId, reason);
4914 final int startActivitiesInPackage(int uid, String callingPackage,
4915 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4916 Bundle bOptions, int userId) {
4918 final String reason = "startActivityInPackage";
4919 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4920 userId, false, ALLOW_FULL_ONLY, reason, null);
4921 // TODO: Switch to user app stacks here.
4922 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4923 resultTo, bOptions, userId, reason);
4928 public void reportActivityFullyDrawn(IBinder token) {
4929 synchronized (this) {
4930 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4934 r.reportFullyDrawnLocked();
4939 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4940 synchronized (this) {
4941 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4945 final long origId = Binder.clearCallingIdentity();
4947 r.setRequestedOrientation(requestedOrientation);
4949 Binder.restoreCallingIdentity(origId);
4955 public int getRequestedOrientation(IBinder token) {
4956 synchronized (this) {
4957 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4959 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4961 return r.getRequestedOrientation();
4966 public final void requestActivityRelaunch(IBinder token) {
4967 synchronized(this) {
4968 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4972 final long origId = Binder.clearCallingIdentity();
4974 r.forceNewConfig = true;
4975 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4976 true /* preserveWindow */);
4978 Binder.restoreCallingIdentity(origId);
4984 * This is the internal entry point for handling Activity.finish().
4986 * @param token The Binder token referencing the Activity we want to finish.
4987 * @param resultCode Result code, if any, from this Activity.
4988 * @param resultData Result data (Intent), if any, from this Activity.
4989 * @param finishTask Whether to finish the task associated with this Activity.
4991 * @return Returns true if the activity successfully finished, or false if it is still running.
4994 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4996 // Refuse possible leaked file descriptors
4997 if (resultData != null && resultData.hasFileDescriptors() == true) {
4998 throw new IllegalArgumentException("File descriptors passed in Intent");
5001 synchronized(this) {
5002 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5006 // Keep track of the root activity of the task before we finish it
5007 TaskRecord tr = r.getTask();
5008 ActivityRecord rootR = tr.getRootActivity();
5009 if (rootR == null) {
5010 Slog.w(TAG, "Finishing task with all activities already finished");
5012 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5014 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5015 mStackSupervisor.isLastLockedTask(tr)) {
5016 Slog.i(TAG, "Not finishing task in lock task mode");
5017 mStackSupervisor.showLockTaskToast();
5020 if (mController != null) {
5021 // Find the first activity that is not finishing.
5022 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5024 // ask watcher if this is allowed
5025 boolean resumeOK = true;
5027 resumeOK = mController.activityResuming(next.packageName);
5028 } catch (RemoteException e) {
5030 Watchdog.getInstance().setActivityController(null);
5034 Slog.i(TAG, "Not finishing activity because controller resumed");
5039 final long origId = Binder.clearCallingIdentity();
5042 final boolean finishWithRootActivity =
5043 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5044 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5045 || (finishWithRootActivity && r == rootR)) {
5046 // If requested, remove the task that is associated to this activity only if it
5047 // was the root activity in the task. The result code and data is ignored
5048 // because we don't support returning them across task boundaries. Also, to
5049 // keep backwards compatibility we remove the task from recents when finishing
5050 // task with root activity.
5051 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5053 Slog.i(TAG, "Removing task failed to finish activity");
5056 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5057 resultData, "app-request", true);
5059 Slog.i(TAG, "Failed to finish by app-request");
5064 Binder.restoreCallingIdentity(origId);
5070 public final void finishHeavyWeightApp() {
5071 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5072 != PackageManager.PERMISSION_GRANTED) {
5073 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5074 + Binder.getCallingPid()
5075 + ", uid=" + Binder.getCallingUid()
5076 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5078 throw new SecurityException(msg);
5081 synchronized(this) {
5082 if (mHeavyWeightProcess == null) {
5086 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5087 for (int i = 0; i < activities.size(); i++) {
5088 ActivityRecord r = activities.get(i);
5089 if (!r.finishing && r.isInStackLocked()) {
5090 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5091 null, "finish-heavy", true);
5095 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5096 mHeavyWeightProcess.userId, 0));
5097 mHeavyWeightProcess = null;
5102 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5104 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5105 != PackageManager.PERMISSION_GRANTED) {
5106 String msg = "Permission Denial: crashApplication() 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 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5120 public final void finishSubActivity(IBinder token, String resultWho,
5122 synchronized(this) {
5123 final long origId = Binder.clearCallingIdentity();
5124 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5126 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5128 Binder.restoreCallingIdentity(origId);
5133 public boolean finishActivityAffinity(IBinder token) {
5134 synchronized(this) {
5135 final long origId = Binder.clearCallingIdentity();
5137 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5142 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5144 final TaskRecord task = r.getTask();
5145 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5146 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5147 mStackSupervisor.showLockTaskToast();
5150 return task.getStack().finishActivityAffinityLocked(r);
5152 Binder.restoreCallingIdentity(origId);
5158 public void finishVoiceTask(IVoiceInteractionSession session) {
5159 synchronized (this) {
5160 final long origId = Binder.clearCallingIdentity();
5162 // TODO: VI Consider treating local voice interactions and voice tasks
5164 mStackSupervisor.finishVoiceTask(session);
5166 Binder.restoreCallingIdentity(origId);
5173 public boolean releaseActivityInstance(IBinder token) {
5174 synchronized(this) {
5175 final long origId = Binder.clearCallingIdentity();
5177 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5181 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5183 Binder.restoreCallingIdentity(origId);
5189 public void releaseSomeActivities(IApplicationThread appInt) {
5190 synchronized(this) {
5191 final long origId = Binder.clearCallingIdentity();
5193 ProcessRecord app = getRecordForAppLocked(appInt);
5194 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5196 Binder.restoreCallingIdentity(origId);
5202 public boolean willActivityBeVisible(IBinder token) {
5203 synchronized(this) {
5204 ActivityStack stack = ActivityRecord.getStackLocked(token);
5205 if (stack != null) {
5206 return stack.willActivityBeVisibleLocked(token);
5213 public void overridePendingTransition(IBinder token, String packageName,
5214 int enterAnim, int exitAnim) {
5215 synchronized(this) {
5216 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5221 final long origId = Binder.clearCallingIdentity();
5223 if (self.state == ActivityState.RESUMED
5224 || self.state == ActivityState.PAUSING) {
5225 mWindowManager.overridePendingAppTransition(packageName,
5226 enterAnim, exitAnim, null);
5229 Binder.restoreCallingIdentity(origId);
5234 * Main function for removing an existing process from the activity manager
5235 * as a result of that process going away. Clears out all connections
5238 private final void handleAppDiedLocked(ProcessRecord app,
5239 boolean restarting, boolean allowRestart) {
5241 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5242 false /*replacingPid*/);
5243 if (!kept && !restarting) {
5244 removeLruProcessLocked(app);
5246 ProcessList.remove(pid);
5250 if (mProfileProc == app) {
5251 clearProfilerLocked();
5254 // Remove this application's activities from active lists.
5255 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5257 app.activities.clear();
5259 if (app.instr != null) {
5260 Slog.w(TAG, "Crash of app " + app.processName
5261 + " running instrumentation " + app.instr.mClass);
5262 Bundle info = new Bundle();
5263 info.putString("shortMsg", "Process crashed.");
5264 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5267 mWindowManager.deferSurfaceLayout();
5269 if (!restarting && hasVisibleActivities
5270 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5271 // If there was nothing to resume, and we are not already restarting this process, but
5272 // there is a visible activity that is hosted by the process... then make sure all
5273 // visible activities are running, taking care of restarting this process.
5274 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5277 mWindowManager.continueSurfaceLayout();
5281 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5282 final IBinder threadBinder = thread.asBinder();
5283 // Find the application record.
5284 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5285 final ProcessRecord rec = mLruProcesses.get(i);
5286 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5293 final ProcessRecord getRecordForAppLocked(
5294 IApplicationThread thread) {
5295 if (thread == null) {
5299 int appIndex = getLRURecordIndexForAppLocked(thread);
5300 if (appIndex >= 0) {
5301 return mLruProcesses.get(appIndex);
5304 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5305 // double-check that.
5306 final IBinder threadBinder = thread.asBinder();
5307 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5308 for (int i = pmap.size()-1; i >= 0; i--) {
5309 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5310 for (int j = procs.size()-1; j >= 0; j--) {
5311 final ProcessRecord proc = procs.valueAt(j);
5312 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5313 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5323 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5324 // If there are no longer any background processes running,
5325 // and the app that died was not running instrumentation,
5326 // then tell everyone we are now low on memory.
5327 boolean haveBg = false;
5328 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5329 ProcessRecord rec = mLruProcesses.get(i);
5330 if (rec.thread != null
5331 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5338 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5340 long now = SystemClock.uptimeMillis();
5341 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5344 mLastMemUsageReportTime = now;
5347 final ArrayList<ProcessMemInfo> memInfos
5348 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5349 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5350 long now = SystemClock.uptimeMillis();
5351 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5352 ProcessRecord rec = mLruProcesses.get(i);
5353 if (rec == dyingProc || rec.thread == null) {
5357 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5358 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5360 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5361 // The low memory report is overriding any current
5362 // state for a GC request. Make sure to do
5363 // heavy/important/visible/foreground processes first.
5364 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5365 rec.lastRequestedGc = 0;
5367 rec.lastRequestedGc = rec.lastLowMemory;
5369 rec.reportLowMemory = true;
5370 rec.lastLowMemory = now;
5371 mProcessesToGc.remove(rec);
5372 addProcessToGcListLocked(rec);
5376 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5377 mHandler.sendMessage(msg);
5379 scheduleAppGcsLocked();
5383 final void appDiedLocked(ProcessRecord app) {
5384 appDiedLocked(app, app.pid, app.thread, false);
5387 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5388 boolean fromBinderDied) {
5389 // First check if this ProcessRecord is actually active for the pid.
5390 synchronized (mPidsSelfLocked) {
5391 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5392 if (curProc != app) {
5393 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5398 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5399 synchronized (stats) {
5400 stats.noteProcessDiedLocked(app.info.uid, pid);
5404 if (!fromBinderDied) {
5405 killProcessQuiet(pid);
5407 killProcessGroup(app.uid, pid);
5411 // Clean up already done if the process has been re-started.
5412 if (app.pid == pid && app.thread != null &&
5413 app.thread.asBinder() == thread.asBinder()) {
5414 boolean doLowMem = app.instr == null;
5415 boolean doOomAdj = doLowMem;
5416 if (!app.killedByAm) {
5417 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5418 + ProcessList.makeOomAdjString(app.setAdj)
5419 + ProcessList.makeProcStateString(app.setProcState));
5420 mAllowLowerMemLevel = true;
5422 // Note that we always want to do oom adj to update our state with the
5423 // new number of procs.
5424 mAllowLowerMemLevel = false;
5427 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5428 app.setAdj, app.setProcState);
5429 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5430 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5431 handleAppDiedLocked(app, false, true);
5434 updateOomAdjLocked();
5437 doLowMemReportIfNeededLocked(app);
5439 } else if (app.pid != pid) {
5440 // A new process has already been started.
5441 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5442 + ") has died and restarted (pid " + app.pid + ").");
5443 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5444 } else if (DEBUG_PROCESSES) {
5445 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5446 + thread.asBinder());
5451 * If a stack trace dump file is configured, dump process stack traces.
5452 * @param clearTraces causes the dump file to be erased prior to the new
5453 * traces being written, if true; when false, the new traces will be
5454 * appended to any existing file content.
5455 * @param firstPids of dalvik VM processes to dump stack traces for first
5456 * @param lastPids of dalvik VM processes to dump stack traces for last
5457 * @param nativePids optional list of native pids to dump stack crawls
5458 * @return file containing stack traces, or null if no dump file is configured
5460 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5461 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5462 ArrayList<Integer> nativePids) {
5463 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5464 if (tracesPath == null || tracesPath.length() == 0) {
5468 File tracesFile = new File(tracesPath);
5470 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5471 tracesFile.createNewFile();
5472 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5473 } catch (IOException e) {
5474 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5478 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
5482 public static class DumpStackFileObserver extends FileObserver {
5483 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5484 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5485 static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
5487 private final String mTracesPath;
5488 private boolean mClosed;
5490 public DumpStackFileObserver(String tracesPath) {
5491 super(tracesPath, FileObserver.CLOSE_WRITE);
5492 mTracesPath = tracesPath;
5496 public synchronized void onEvent(int event, String path) {
5501 public long dumpWithTimeout(int pid, long timeout) {
5502 sendSignal(pid, SIGNAL_QUIT);
5503 final long start = SystemClock.elapsedRealtime();
5505 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5506 synchronized (this) {
5508 wait(waitTime); // Wait for traces file to be closed.
5509 } catch (InterruptedException e) {
5514 // This avoids a corner case of passing a negative time to the native
5515 // trace in case we've already hit the overall timeout.
5516 final long timeWaited = SystemClock.elapsedRealtime() - start;
5517 if (timeWaited >= timeout) {
5522 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5523 ". Attempting native stack collection.");
5525 final long nativeDumpTimeoutMs = Math.min(
5526 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5528 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5529 (int) (nativeDumpTimeoutMs / 1000));
5532 final long end = SystemClock.elapsedRealtime();
5535 return (end - start);
5539 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5540 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5541 ArrayList<Integer> nativePids) {
5542 // Use a FileObserver to detect when traces finish writing.
5543 // The order of traces is considered important to maintain for legibility.
5544 DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
5546 // We must complete all stack dumps within 20 seconds.
5547 long remainingTime = 20 * 1000;
5549 observer.startWatching();
5551 // First collect all of the stacks of the most important pids.
5552 if (firstPids != null) {
5553 int num = firstPids.size();
5554 for (int i = 0; i < num; i++) {
5555 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5556 + firstPids.get(i));
5557 final long timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5559 remainingTime -= timeTaken;
5560 if (remainingTime <= 0) {
5561 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5562 "); deadline exceeded.");
5567 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5572 // Next collect the stacks of the native pids
5573 if (nativePids != null) {
5574 for (int pid : nativePids) {
5575 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5576 final long nativeDumpTimeoutMs = Math.min(
5577 DumpStackFileObserver.NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5579 final long start = SystemClock.elapsedRealtime();
5580 Debug.dumpNativeBacktraceToFileTimeout(
5581 pid, tracesPath, (int) (nativeDumpTimeoutMs / 1000));
5582 final long timeTaken = SystemClock.elapsedRealtime() - start;
5584 remainingTime -= timeTaken;
5585 if (remainingTime <= 0) {
5586 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5587 "); deadline exceeded.");
5592 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5597 // Lastly, measure CPU usage.
5598 if (processCpuTracker != null) {
5599 processCpuTracker.init();
5601 processCpuTracker.update();
5603 synchronized (processCpuTracker) {
5604 processCpuTracker.wait(500); // measure over 1/2 second.
5606 } catch (InterruptedException e) {
5608 processCpuTracker.update();
5610 // We'll take the stack crawls of just the top apps using CPU.
5611 final int N = processCpuTracker.countWorkingStats();
5613 for (int i=0; i<N && numProcs<5; i++) {
5614 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5615 if (lastPids.indexOfKey(stats.pid) >= 0) {
5618 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5620 final long timeTaken = observer.dumpWithTimeout(stats.pid, remainingTime);
5621 remainingTime -= timeTaken;
5622 if (remainingTime <= 0) {
5623 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + stats.pid +
5624 "); deadline exceeded.");
5629 Slog.d(TAG, "Done with extra pid " + stats.pid + " in " + timeTaken + "ms");
5631 } else if (DEBUG_ANR) {
5632 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5638 observer.stopWatching();
5642 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5643 if (true || IS_USER_BUILD) {
5646 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5647 if (tracesPath == null || tracesPath.length() == 0) {
5651 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5652 StrictMode.allowThreadDiskWrites();
5654 final File tracesFile = new File(tracesPath);
5655 final File tracesDir = tracesFile.getParentFile();
5656 final File tracesTmp = new File(tracesDir, "__tmp__");
5658 if (tracesFile.exists()) {
5660 tracesFile.renameTo(tracesTmp);
5662 StringBuilder sb = new StringBuilder();
5663 Time tobj = new Time();
5664 tobj.set(System.currentTimeMillis());
5665 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5667 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5668 sb.append(" since ");
5670 FileOutputStream fos = new FileOutputStream(tracesFile);
5671 fos.write(sb.toString().getBytes());
5673 fos.write("\n*** No application process!".getBytes());
5676 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5677 } catch (IOException e) {
5678 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5683 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5684 firstPids.add(app.pid);
5685 dumpStackTraces(tracesPath, firstPids, null, null, null);
5688 File lastTracesFile = null;
5689 File curTracesFile = null;
5690 for (int i=9; i>=0; i--) {
5691 String name = String.format(Locale.US, "slow%02d.txt", i);
5692 curTracesFile = new File(tracesDir, name);
5693 if (curTracesFile.exists()) {
5694 if (lastTracesFile != null) {
5695 curTracesFile.renameTo(lastTracesFile);
5697 curTracesFile.delete();
5700 lastTracesFile = curTracesFile;
5702 tracesFile.renameTo(curTracesFile);
5703 if (tracesTmp.exists()) {
5704 tracesTmp.renameTo(tracesFile);
5707 StrictMode.setThreadPolicy(oldPolicy);
5711 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5712 if (!mLaunchWarningShown) {
5713 mLaunchWarningShown = true;
5714 mUiHandler.post(new Runnable() {
5717 synchronized (ActivityManagerService.this) {
5718 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5720 mUiHandler.postDelayed(new Runnable() {
5723 synchronized (ActivityManagerService.this) {
5725 mLaunchWarningShown = false;
5736 public boolean clearApplicationUserData(final String packageName,
5737 final IPackageDataObserver observer, int userId) {
5738 enforceNotIsolatedCaller("clearApplicationUserData");
5739 int uid = Binder.getCallingUid();
5740 int pid = Binder.getCallingPid();
5741 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5742 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5745 long callingId = Binder.clearCallingIdentity();
5747 IPackageManager pm = AppGlobals.getPackageManager();
5749 synchronized(this) {
5750 if (getPackageManagerInternalLocked().isPackageDataProtected(
5751 userId, packageName)) {
5752 throw new SecurityException(
5753 "Cannot clear data for a protected package: " + packageName);
5757 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5758 } catch (RemoteException e) {
5761 Slog.w(TAG, "Invalid packageName: " + packageName);
5762 if (observer != null) {
5764 observer.onRemoveCompleted(packageName, false);
5765 } catch (RemoteException e) {
5766 Slog.i(TAG, "Observer no longer exists.");
5771 if (uid == pkgUid || checkComponentPermission(
5772 android.Manifest.permission.CLEAR_APP_USER_DATA,
5774 == PackageManager.PERMISSION_GRANTED) {
5775 forceStopPackageLocked(packageName, pkgUid, "clear data");
5777 throw new SecurityException("PID " + pid + " does not have permission "
5778 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5779 + " of package " + packageName);
5782 // Remove all tasks match the cleared application package and user
5783 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5784 final TaskRecord tr = mRecentTasks.get(i);
5785 final String taskPackageName =
5786 tr.getBaseIntent().getComponent().getPackageName();
5787 if (tr.userId != userId) continue;
5788 if (!taskPackageName.equals(packageName)) continue;
5789 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5793 final int pkgUidF = pkgUid;
5794 final int userIdF = userId;
5795 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5797 public void onRemoveCompleted(String packageName, boolean succeeded)
5798 throws RemoteException {
5799 synchronized (ActivityManagerService.this) {
5800 finishForceStopPackageLocked(packageName, pkgUidF);
5803 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5804 Uri.fromParts("package", packageName, null));
5805 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5806 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5807 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5808 broadcastIntentInPackage("android", SYSTEM_UID, intent,
5809 null, null, 0, null, null, null, null, false, false, userIdF);
5811 if (observer != null) {
5812 observer.onRemoveCompleted(packageName, succeeded);
5818 // Clear application user data
5819 pm.clearApplicationUserData(packageName, localObserver, userId);
5821 synchronized(this) {
5822 // Remove all permissions granted from/to this package
5823 removeUriPermissionsForPackageLocked(packageName, userId, true);
5826 // Reset notification settings.
5827 INotificationManager inm = NotificationManager.getService();
5828 inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5829 } catch (RemoteException e) {
5832 Binder.restoreCallingIdentity(callingId);
5838 public void killBackgroundProcesses(final String packageName, int userId) {
5839 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5840 != PackageManager.PERMISSION_GRANTED &&
5841 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5842 != PackageManager.PERMISSION_GRANTED) {
5843 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5844 + Binder.getCallingPid()
5845 + ", uid=" + Binder.getCallingUid()
5846 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5848 throw new SecurityException(msg);
5851 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5852 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5853 long callingId = Binder.clearCallingIdentity();
5855 IPackageManager pm = AppGlobals.getPackageManager();
5856 synchronized(this) {
5859 appId = UserHandle.getAppId(
5860 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5861 } catch (RemoteException e) {
5864 Slog.w(TAG, "Invalid packageName: " + packageName);
5867 killPackageProcessesLocked(packageName, appId, userId,
5868 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5871 Binder.restoreCallingIdentity(callingId);
5876 public void killAllBackgroundProcesses() {
5877 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5878 != PackageManager.PERMISSION_GRANTED) {
5879 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5880 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5881 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5883 throw new SecurityException(msg);
5886 final long callingId = Binder.clearCallingIdentity();
5888 synchronized (this) {
5889 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5890 final int NP = mProcessNames.getMap().size();
5891 for (int ip = 0; ip < NP; ip++) {
5892 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5893 final int NA = apps.size();
5894 for (int ia = 0; ia < NA; ia++) {
5895 final ProcessRecord app = apps.valueAt(ia);
5896 if (app.persistent) {
5897 // We don't kill persistent processes.
5902 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5909 final int N = procs.size();
5910 for (int i = 0; i < N; i++) {
5911 removeProcessLocked(procs.get(i), false, true, "kill all background");
5914 mAllowLowerMemLevel = true;
5916 updateOomAdjLocked();
5917 doLowMemReportIfNeededLocked(null);
5920 Binder.restoreCallingIdentity(callingId);
5925 * Kills all background processes, except those matching any of the
5926 * specified properties.
5928 * @param minTargetSdk the target SDK version at or above which to preserve
5929 * processes, or {@code -1} to ignore the target SDK
5930 * @param maxProcState the process state at or below which to preserve
5931 * processes, or {@code -1} to ignore the process state
5933 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5934 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5935 != PackageManager.PERMISSION_GRANTED) {
5936 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5937 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5938 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5940 throw new SecurityException(msg);
5943 final long callingId = Binder.clearCallingIdentity();
5945 synchronized (this) {
5946 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5947 final int NP = mProcessNames.getMap().size();
5948 for (int ip = 0; ip < NP; ip++) {
5949 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5950 final int NA = apps.size();
5951 for (int ia = 0; ia < NA; ia++) {
5952 final ProcessRecord app = apps.valueAt(ia);
5955 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5956 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5963 final int N = procs.size();
5964 for (int i = 0; i < N; i++) {
5965 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5969 Binder.restoreCallingIdentity(callingId);
5974 public void forceStopPackage(final String packageName, int userId) {
5975 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5976 != PackageManager.PERMISSION_GRANTED) {
5977 String msg = "Permission Denial: forceStopPackage() from pid="
5978 + Binder.getCallingPid()
5979 + ", uid=" + Binder.getCallingUid()
5980 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5982 throw new SecurityException(msg);
5984 final int callingPid = Binder.getCallingPid();
5985 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5986 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5987 long callingId = Binder.clearCallingIdentity();
5989 IPackageManager pm = AppGlobals.getPackageManager();
5990 synchronized(this) {
5991 int[] users = userId == UserHandle.USER_ALL
5992 ? mUserController.getUsers() : new int[] { userId };
5993 for (int user : users) {
5996 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5998 } catch (RemoteException e) {
6001 Slog.w(TAG, "Invalid packageName: " + packageName);
6005 pm.setPackageStoppedState(packageName, true, user);
6006 } catch (RemoteException e) {
6007 } catch (IllegalArgumentException e) {
6008 Slog.w(TAG, "Failed trying to unstop package "
6009 + packageName + ": " + e);
6011 if (mUserController.isUserRunningLocked(user, 0)) {
6012 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6013 finishForceStopPackageLocked(packageName, pkgUid);
6018 Binder.restoreCallingIdentity(callingId);
6023 public void addPackageDependency(String packageName) {
6024 synchronized (this) {
6025 int callingPid = Binder.getCallingPid();
6026 if (callingPid == myPid()) {
6031 synchronized (mPidsSelfLocked) {
6032 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6035 if (proc.pkgDeps == null) {
6036 proc.pkgDeps = new ArraySet<String>(1);
6038 proc.pkgDeps.add(packageName);
6044 * The pkg name and app id have to be specified.
6047 public void killApplication(String pkg, int appId, int userId, String reason) {
6051 // Make sure the uid is valid.
6053 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6056 int callerUid = Binder.getCallingUid();
6057 // Only the system server can kill an application
6058 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6059 // Post an aysnc message to kill the application
6060 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6063 Bundle bundle = new Bundle();
6064 bundle.putString("pkg", pkg);
6065 bundle.putString("reason", reason);
6067 mHandler.sendMessage(msg);
6069 throw new SecurityException(callerUid + " cannot kill pkg: " +
6075 public void closeSystemDialogs(String reason) {
6076 enforceNotIsolatedCaller("closeSystemDialogs");
6078 final int pid = Binder.getCallingPid();
6079 final int uid = Binder.getCallingUid();
6080 final long origId = Binder.clearCallingIdentity();
6082 synchronized (this) {
6083 // Only allow this from foreground processes, so that background
6084 // applications can't abuse it to prevent system UI from being shown.
6085 if (uid >= FIRST_APPLICATION_UID) {
6087 synchronized (mPidsSelfLocked) {
6088 proc = mPidsSelfLocked.get(pid);
6090 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6091 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6092 + " from background process " + proc);
6096 closeSystemDialogsLocked(reason);
6099 Binder.restoreCallingIdentity(origId);
6103 void closeSystemDialogsLocked(String reason) {
6104 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6105 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6106 | Intent.FLAG_RECEIVER_FOREGROUND);
6107 if (reason != null) {
6108 intent.putExtra("reason", reason);
6110 mWindowManager.closeSystemDialogs(reason);
6112 mStackSupervisor.closeSystemDialogsLocked();
6114 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6115 AppOpsManager.OP_NONE, null, false, false,
6116 -1, SYSTEM_UID, UserHandle.USER_ALL);
6120 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6121 enforceNotIsolatedCaller("getProcessMemoryInfo");
6122 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6123 for (int i=pids.length-1; i>=0; i--) {
6126 synchronized (this) {
6127 synchronized (mPidsSelfLocked) {
6128 proc = mPidsSelfLocked.get(pids[i]);
6129 oomAdj = proc != null ? proc.setAdj : 0;
6132 infos[i] = new Debug.MemoryInfo();
6133 Debug.getMemoryInfo(pids[i], infos[i]);
6135 synchronized (this) {
6136 if (proc.thread != null && proc.setAdj == oomAdj) {
6137 // Record this for posterity if the process has been stable.
6138 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6139 infos[i].getTotalUss(), false, proc.pkgList);
6148 public long[] getProcessPss(int[] pids) {
6149 enforceNotIsolatedCaller("getProcessPss");
6150 long[] pss = new long[pids.length];
6151 for (int i=pids.length-1; i>=0; i--) {
6154 synchronized (this) {
6155 synchronized (mPidsSelfLocked) {
6156 proc = mPidsSelfLocked.get(pids[i]);
6157 oomAdj = proc != null ? proc.setAdj : 0;
6160 long[] tmpUss = new long[1];
6161 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6163 synchronized (this) {
6164 if (proc.thread != null && proc.setAdj == oomAdj) {
6165 // Record this for posterity if the process has been stable.
6166 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6175 public void killApplicationProcess(String processName, int uid) {
6176 if (processName == null) {
6180 int callerUid = Binder.getCallingUid();
6181 // Only the system server can kill an application
6182 if (callerUid == SYSTEM_UID) {
6183 synchronized (this) {
6184 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6185 if (app != null && app.thread != null) {
6187 app.thread.scheduleSuicide();
6188 } catch (RemoteException e) {
6189 // If the other end already died, then our work here is done.
6192 Slog.w(TAG, "Process/uid not found attempting kill of "
6193 + processName + " / " + uid);
6197 throw new SecurityException(callerUid + " cannot kill app process: " +
6202 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6203 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6204 false, true, false, false, UserHandle.getUserId(uid), reason);
6207 private void finishForceStopPackageLocked(final String packageName, int uid) {
6208 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6209 Uri.fromParts("package", packageName, null));
6210 if (!mProcessesReady) {
6211 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6212 | Intent.FLAG_RECEIVER_FOREGROUND);
6214 intent.putExtra(Intent.EXTRA_UID, uid);
6215 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6216 broadcastIntentLocked(null, null, intent,
6217 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6218 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6222 private final boolean killPackageProcessesLocked(String packageName, int appId,
6223 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6224 boolean doit, boolean evenPersistent, String reason) {
6225 ArrayList<ProcessRecord> procs = new ArrayList<>();
6227 // Remove all processes this package may have touched: all with the
6228 // same UID (except for the system or root user), and all whose name
6229 // matches the package name.
6230 final int NP = mProcessNames.getMap().size();
6231 for (int ip=0; ip<NP; ip++) {
6232 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6233 final int NA = apps.size();
6234 for (int ia=0; ia<NA; ia++) {
6235 ProcessRecord app = apps.valueAt(ia);
6236 if (app.persistent && !evenPersistent) {
6237 // we don't kill persistent processes
6247 // Skip process if it doesn't meet our oom adj requirement.
6248 if (app.setAdj < minOomAdj) {
6252 // If no package is specified, we call all processes under the
6254 if (packageName == null) {
6255 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6258 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6261 // Package has been specified, we want to hit all processes
6262 // that match it. We need to qualify this by the processes
6263 // that are running under the specified app and user ID.
6265 final boolean isDep = app.pkgDeps != null
6266 && app.pkgDeps.contains(packageName);
6267 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6270 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6273 if (!app.pkgList.containsKey(packageName) && !isDep) {
6278 // Process has passed all conditions, kill it!
6287 int N = procs.size();
6288 for (int i=0; i<N; i++) {
6289 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6291 updateOomAdjLocked();
6295 private void cleanupDisabledPackageComponentsLocked(
6296 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6298 Set<String> disabledClasses = null;
6299 boolean packageDisabled = false;
6300 IPackageManager pm = AppGlobals.getPackageManager();
6302 if (changedClasses == null) {
6303 // Nothing changed...
6307 // Determine enable/disable state of the package and its components.
6308 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6309 for (int i = changedClasses.length - 1; i >= 0; i--) {
6310 final String changedClass = changedClasses[i];
6312 if (changedClass.equals(packageName)) {
6314 // Entire package setting changed
6315 enabled = pm.getApplicationEnabledSetting(packageName,
6316 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6317 } catch (Exception e) {
6318 // No such package/component; probably racing with uninstall. In any
6319 // event it means we have nothing further to do here.
6322 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6323 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6324 if (packageDisabled) {
6325 // Entire package is disabled.
6326 // No need to continue to check component states.
6327 disabledClasses = null;
6332 enabled = pm.getComponentEnabledSetting(
6333 new ComponentName(packageName, changedClass),
6334 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6335 } catch (Exception e) {
6336 // As above, probably racing with uninstall.
6339 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6340 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6341 if (disabledClasses == null) {
6342 disabledClasses = new ArraySet<>(changedClasses.length);
6344 disabledClasses.add(changedClass);
6349 if (!packageDisabled && disabledClasses == null) {
6350 // Nothing to do here...
6354 // Clean-up disabled activities.
6355 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6356 packageName, disabledClasses, true, false, userId) && mBooted) {
6357 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6358 mStackSupervisor.scheduleIdleLocked();
6361 // Clean-up disabled tasks
6362 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6364 // Clean-up disabled services.
6365 mServices.bringDownDisabledPackageServicesLocked(
6366 packageName, disabledClasses, userId, false, killProcess, true);
6368 // Clean-up disabled providers.
6369 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6370 mProviderMap.collectPackageProvidersLocked(
6371 packageName, disabledClasses, true, false, userId, providers);
6372 for (int i = providers.size() - 1; i >= 0; i--) {
6373 removeDyingProviderLocked(null, providers.get(i), true);
6376 // Clean-up disabled broadcast receivers.
6377 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6378 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6379 packageName, disabledClasses, userId, true);
6384 final boolean clearBroadcastQueueForUserLocked(int userId) {
6385 boolean didSomething = false;
6386 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6387 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6388 null, null, userId, true);
6390 return didSomething;
6393 final boolean forceStopPackageLocked(String packageName, int appId,
6394 boolean callerWillRestart, boolean purgeCache, boolean doit,
6395 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6398 if (userId == UserHandle.USER_ALL && packageName == null) {
6399 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6402 if (appId < 0 && packageName != null) {
6404 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6405 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6406 } catch (RemoteException e) {
6411 if (packageName != null) {
6412 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6413 + " user=" + userId + ": " + reason);
6415 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6418 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6421 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6422 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6423 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6425 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6427 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6428 packageName, null, doit, evenPersistent, userId)) {
6432 didSomething = true;
6435 if (mServices.bringDownDisabledPackageServicesLocked(
6436 packageName, null, userId, evenPersistent, true, doit)) {
6440 didSomething = true;
6443 if (packageName == null) {
6444 // Remove all sticky broadcasts from this user.
6445 mStickyBroadcasts.remove(userId);
6448 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6449 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6450 userId, providers)) {
6454 didSomething = true;
6456 for (i = providers.size() - 1; i >= 0; i--) {
6457 removeDyingProviderLocked(null, providers.get(i), true);
6460 // Remove transient permissions granted from/to this package/user
6461 removeUriPermissionsForPackageLocked(packageName, userId, false);
6464 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6465 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6466 packageName, null, userId, doit);
6470 if (packageName == null || uninstalling) {
6471 // Remove pending intents. For now we only do this when force
6472 // stopping users, because we have some problems when doing this
6473 // for packages -- app widgets are not currently cleaned up for
6474 // such packages, so they can be left with bad pending intents.
6475 if (mIntentSenderRecords.size() > 0) {
6476 Iterator<WeakReference<PendingIntentRecord>> it
6477 = mIntentSenderRecords.values().iterator();
6478 while (it.hasNext()) {
6479 WeakReference<PendingIntentRecord> wpir = it.next();
6484 PendingIntentRecord pir = wpir.get();
6489 if (packageName == null) {
6490 // Stopping user, remove all objects for the user.
6491 if (pir.key.userId != userId) {
6492 // Not the same user, skip it.
6496 if (UserHandle.getAppId(pir.uid) != appId) {
6497 // Different app id, skip it.
6500 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6501 // Different user, skip it.
6504 if (!pir.key.packageName.equals(packageName)) {
6505 // Different package, skip it.
6512 didSomething = true;
6514 makeIntentSenderCanceledLocked(pir);
6515 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6516 pir.key.activity.pendingResults.remove(pir.ref);
6523 if (purgeCache && packageName != null) {
6524 AttributeCache ac = AttributeCache.instance();
6526 ac.removePackage(packageName);
6530 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6531 mStackSupervisor.scheduleIdleLocked();
6535 return didSomething;
6538 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6539 return removeProcessNameLocked(name, uid, null);
6542 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6543 final ProcessRecord expecting) {
6544 ProcessRecord old = mProcessNames.get(name, uid);
6545 // Only actually remove when the currently recorded value matches the
6546 // record that we expected; if it doesn't match then we raced with a
6547 // newly created process and we don't want to destroy the new one.
6548 if ((expecting == null) || (old == expecting)) {
6549 mProcessNames.remove(name, uid);
6551 if (old != null && old.uidRecord != null) {
6552 old.uidRecord.numProcs--;
6553 if (old.uidRecord.numProcs == 0) {
6554 // No more processes using this uid, tell clients it is gone.
6555 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6556 "No more processes in " + old.uidRecord);
6557 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6558 EventLogTags.writeAmUidStopped(uid);
6559 mActiveUids.remove(uid);
6560 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6562 old.uidRecord = null;
6564 mIsolatedProcesses.remove(uid);
6568 private final void addProcessNameLocked(ProcessRecord proc) {
6569 // We shouldn't already have a process under this name, but just in case we
6570 // need to clean up whatever may be there now.
6571 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6572 if (old == proc && proc.persistent) {
6573 // We are re-adding a persistent process. Whatevs! Just leave it there.
6574 Slog.w(TAG, "Re-adding persistent process " + proc);
6575 } else if (old != null) {
6576 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6578 UidRecord uidRec = mActiveUids.get(proc.uid);
6579 if (uidRec == null) {
6580 uidRec = new UidRecord(proc.uid);
6581 // This is the first appearance of the uid, report it now!
6582 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6583 "Creating new process uid: " + uidRec);
6584 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6585 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6586 uidRec.setWhitelist = uidRec.curWhitelist = true;
6588 uidRec.updateHasInternetPermission();
6589 mActiveUids.put(proc.uid, uidRec);
6590 EventLogTags.writeAmUidRunning(uidRec.uid);
6591 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6592 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6594 proc.uidRecord = uidRec;
6596 // Reset render thread tid if it was already set, so new process can set it again.
6597 proc.renderThreadTid = 0;
6599 mProcessNames.put(proc.processName, proc.uid, proc);
6600 if (proc.isolated) {
6601 mIsolatedProcesses.put(proc.uid, proc);
6605 boolean removeProcessLocked(ProcessRecord app,
6606 boolean callerWillRestart, boolean allowRestart, String reason) {
6607 final String name = app.processName;
6608 final int uid = app.uid;
6609 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6610 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6612 ProcessRecord old = mProcessNames.get(name, uid);
6614 // This process is no longer active, so nothing to do.
6615 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6618 removeProcessNameLocked(name, uid);
6619 if (mHeavyWeightProcess == app) {
6620 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6621 mHeavyWeightProcess.userId, 0));
6622 mHeavyWeightProcess = null;
6624 boolean needRestart = false;
6625 if (app.pid > 0 && app.pid != MY_PID) {
6627 synchronized (mPidsSelfLocked) {
6628 mPidsSelfLocked.remove(pid);
6629 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6631 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6633 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6634 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6636 boolean willRestart = false;
6637 if (app.persistent && !app.isolated) {
6638 if (!callerWillRestart) {
6644 app.kill(reason, true);
6645 handleAppDiedLocked(app, willRestart, allowRestart);
6647 removeLruProcessLocked(app);
6648 addAppLocked(app.info, null, false, null /* ABI override */);
6651 mRemovedProcesses.add(app);
6657 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6658 cleanupAppInLaunchingProvidersLocked(app, true);
6659 removeProcessLocked(app, false, true, "timeout publishing content providers");
6662 private final void processStartTimedOutLocked(ProcessRecord app) {
6663 final int pid = app.pid;
6664 boolean gone = false;
6665 synchronized (mPidsSelfLocked) {
6666 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6667 if (knownApp != null && knownApp.thread == null) {
6668 mPidsSelfLocked.remove(pid);
6674 Slog.w(TAG, "Process " + app + " failed to attach");
6675 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6676 pid, app.uid, app.processName);
6677 removeProcessNameLocked(app.processName, app.uid);
6678 if (mHeavyWeightProcess == app) {
6679 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6680 mHeavyWeightProcess.userId, 0));
6681 mHeavyWeightProcess = null;
6683 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6685 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6687 // Take care of any launching providers waiting for this process.
6688 cleanupAppInLaunchingProvidersLocked(app, true);
6689 // Take care of any services that are waiting for the process.
6690 mServices.processStartTimedOutLocked(app);
6691 app.kill("start timeout", true);
6692 removeLruProcessLocked(app);
6693 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6694 Slog.w(TAG, "Unattached app died before backup, skipping");
6695 mHandler.post(new Runnable() {
6699 IBackupManager bm = IBackupManager.Stub.asInterface(
6700 ServiceManager.getService(Context.BACKUP_SERVICE));
6701 bm.agentDisconnected(app.info.packageName);
6702 } catch (RemoteException e) {
6703 // Can't happen; the backup manager is local
6708 if (isPendingBroadcastProcessLocked(pid)) {
6709 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6710 skipPendingBroadcastLocked(pid);
6713 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6717 private final boolean attachApplicationLocked(IApplicationThread thread,
6720 // Find the application record that is being attached... either via
6721 // the pid if we are running in multiple processes, or just pull the
6722 // next app record if we are emulating process with anonymous threads.
6724 long startTime = SystemClock.uptimeMillis();
6725 if (pid != MY_PID && pid >= 0) {
6726 synchronized (mPidsSelfLocked) {
6727 app = mPidsSelfLocked.get(pid);
6734 Slog.w(TAG, "No pending application record for pid " + pid
6735 + " (IApplicationThread " + thread + "); dropping process");
6736 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6737 if (pid > 0 && pid != MY_PID) {
6738 killProcessQuiet(pid);
6739 //TODO: killProcessGroup(app.info.uid, pid);
6742 thread.scheduleExit();
6743 } catch (Exception e) {
6744 // Ignore exceptions.
6750 // If this application record is still attached to a previous
6751 // process, clean it up now.
6752 if (app.thread != null) {
6753 handleAppDiedLocked(app, true, true);
6756 // Tell the process all about itself.
6758 if (DEBUG_ALL) Slog.v(
6759 TAG, "Binding process pid " + pid + " to record " + app);
6761 final String processName = app.processName;
6763 AppDeathRecipient adr = new AppDeathRecipient(
6765 thread.asBinder().linkToDeath(adr, 0);
6766 app.deathRecipient = adr;
6767 } catch (RemoteException e) {
6768 app.resetPackageList(mProcessStats);
6769 startProcessLocked(app, "link fail", processName);
6773 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6775 app.makeActive(thread, mProcessStats);
6776 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6777 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6778 app.forcingToImportant = null;
6779 updateProcessForegroundLocked(app, false, false);
6780 app.hasShownUi = false;
6781 app.debugging = false;
6783 app.killedByAm = false;
6787 // We carefully use the same state that PackageManager uses for
6788 // filtering, since we use this flag to decide if we need to install
6789 // providers when user is unlocked later
6790 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6792 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6794 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6795 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6797 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6798 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6800 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6803 checkTime(startTime, "attachApplicationLocked: before bindApplication");
6806 Slog.i(TAG, "Launching preboot mode app: " + app);
6809 if (DEBUG_ALL) Slog.v(
6810 TAG, "New app record " + app
6811 + " thread=" + thread.asBinder() + " pid=" + pid);
6813 int testMode = ApplicationThreadConstants.DEBUG_OFF;
6814 if (mDebugApp != null && mDebugApp.equals(processName)) {
6815 testMode = mWaitForDebugger
6816 ? ApplicationThreadConstants.DEBUG_WAIT
6817 : ApplicationThreadConstants.DEBUG_ON;
6818 app.debugging = true;
6819 if (mDebugTransient) {
6820 mDebugApp = mOrigDebugApp;
6821 mWaitForDebugger = mOrigWaitForDebugger;
6824 String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6825 ParcelFileDescriptor profileFd = null;
6826 int samplingInterval = 0;
6827 boolean profileAutoStop = false;
6828 boolean profileStreamingOutput = false;
6829 if (mProfileApp != null && mProfileApp.equals(processName)) {
6831 profileFile = mProfileFile;
6832 profileFd = mProfileFd;
6833 samplingInterval = mSamplingInterval;
6834 profileAutoStop = mAutoStopProfiler;
6835 profileStreamingOutput = mStreamingOutput;
6837 boolean enableTrackAllocation = false;
6838 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6839 enableTrackAllocation = true;
6840 mTrackAllocationApp = null;
6843 // If the app is being launched for restore or full backup, set it up specially
6844 boolean isRestrictedBackupMode = false;
6845 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6846 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6847 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6848 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6849 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6852 if (app.instr != null) {
6853 notifyPackageUse(app.instr.mClass.getPackageName(),
6854 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6856 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6857 + processName + " with config " + getGlobalConfiguration());
6858 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6859 app.compat = compatibilityInfoForPackageLocked(appInfo);
6860 if (profileFd != null) {
6861 profileFd = profileFd.dup();
6863 ProfilerInfo profilerInfo = profileFile == null ? null
6864 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6865 profileStreamingOutput);
6867 // We deprecated Build.SERIAL and it is not accessible to
6868 // apps that target the v2 security sandbox. Since access to
6869 // the serial is now behind a permission we push down the value.
6870 String buildSerial = Build.UNKNOWN;
6871 if (appInfo.targetSandboxVersion != 2) {
6872 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6873 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6877 // Check if this is a secondary process that should be incorporated into some
6878 // currently active instrumentation. (Note we do this AFTER all of the profiling
6879 // stuff above because profiling can currently happen only in the primary
6880 // instrumentation process.)
6881 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6882 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6883 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6884 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6885 if (aInstr.mTargetProcesses.length == 0) {
6886 // This is the wildcard mode, where every process brought up for
6887 // the target instrumentation should be included.
6888 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6890 aInstr.mRunningProcesses.add(app);
6893 for (String proc : aInstr.mTargetProcesses) {
6894 if (proc.equals(app.processName)) {
6896 aInstr.mRunningProcesses.add(app);
6905 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6906 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6907 if (app.instr != null) {
6908 thread.bindApplication(processName, appInfo, providers,
6910 profilerInfo, app.instr.mArguments,
6912 app.instr.mUiAutomationConnection, testMode,
6913 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6914 isRestrictedBackupMode || !normalMode, app.persistent,
6915 new Configuration(getGlobalConfiguration()), app.compat,
6916 getCommonServicesLocked(app.isolated),
6917 mCoreSettingsObserver.getCoreSettingsLocked(),
6920 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6921 null, null, null, testMode,
6922 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6923 isRestrictedBackupMode || !normalMode, app.persistent,
6924 new Configuration(getGlobalConfiguration()), app.compat,
6925 getCommonServicesLocked(app.isolated),
6926 mCoreSettingsObserver.getCoreSettingsLocked(),
6930 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6931 updateLruProcessLocked(app, false, null);
6932 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6933 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6934 } catch (Exception e) {
6935 // todo: Yikes! What should we do? For now we will try to
6936 // start another process, but that could easily get us in
6937 // an infinite loop of restarting processes...
6938 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6940 app.resetPackageList(mProcessStats);
6941 app.unlinkDeathRecipient();
6942 startProcessLocked(app, "bind fail", processName);
6946 // Remove this record from the list of starting applications.
6947 mPersistentStartingProcesses.remove(app);
6948 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6949 "Attach application locked removing on hold: " + app);
6950 mProcessesOnHold.remove(app);
6952 boolean badApp = false;
6953 boolean didSomething = false;
6955 // See if the top visible activity is waiting to run in this process...
6958 if (mStackSupervisor.attachApplicationLocked(app)) {
6959 didSomething = true;
6961 } catch (Exception e) {
6962 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6967 // Find any services that should be running in this process...
6970 didSomething |= mServices.attachApplicationLocked(app, processName);
6971 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6972 } catch (Exception e) {
6973 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6978 // Check if a next-broadcast receiver is in this process...
6979 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6981 didSomething |= sendPendingBroadcastsLocked(app);
6982 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6983 } catch (Exception e) {
6984 // If the app died trying to launch the receiver we declare it 'bad'
6985 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6990 // Check whether the next backup agent is in this process...
6991 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
6992 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6993 "New app is backup target, launching agent for " + app);
6994 notifyPackageUse(mBackupTarget.appInfo.packageName,
6995 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6997 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6998 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6999 mBackupTarget.backupMode);
7000 } catch (Exception e) {
7001 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7007 app.kill("error during init", true);
7008 handleAppDiedLocked(app, false, true);
7012 if (!didSomething) {
7013 updateOomAdjLocked();
7014 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7021 public final void attachApplication(IApplicationThread thread) {
7022 synchronized (this) {
7023 int callingPid = Binder.getCallingPid();
7024 final long origId = Binder.clearCallingIdentity();
7025 attachApplicationLocked(thread, callingPid);
7026 Binder.restoreCallingIdentity(origId);
7031 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7032 final long origId = Binder.clearCallingIdentity();
7033 synchronized (this) {
7034 ActivityStack stack = ActivityRecord.getStackLocked(token);
7035 if (stack != null) {
7037 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7038 false /* processPausingActivities */, config);
7039 if (stopProfiling) {
7040 if ((mProfileProc == r.app) && (mProfileFd != null)) {
7043 } catch (IOException e) {
7045 clearProfilerLocked();
7050 Binder.restoreCallingIdentity(origId);
7053 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7054 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7055 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7058 void enableScreenAfterBoot() {
7059 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7060 SystemClock.uptimeMillis());
7061 mWindowManager.enableScreenAfterBoot();
7063 synchronized (this) {
7064 updateEventDispatchingLocked();
7069 public void showBootMessage(final CharSequence msg, final boolean always) {
7070 if (Binder.getCallingUid() != myUid()) {
7071 throw new SecurityException();
7073 mWindowManager.showBootMessage(msg, always);
7077 public void keyguardGoingAway(int flags) {
7078 enforceNotIsolatedCaller("keyguardGoingAway");
7079 final long token = Binder.clearCallingIdentity();
7081 synchronized (this) {
7082 mKeyguardController.keyguardGoingAway(flags);
7085 Binder.restoreCallingIdentity(token);
7090 * @return whther the keyguard is currently locked.
7092 boolean isKeyguardLocked() {
7093 return mKeyguardController.isKeyguardLocked();
7096 final void finishBooting() {
7097 synchronized (this) {
7098 if (!mBootAnimationComplete) {
7099 mCallFinishBooting = true;
7102 mCallFinishBooting = false;
7105 ArraySet<String> completedIsas = new ArraySet<String>();
7106 for (String abi : Build.SUPPORTED_ABIS) {
7107 zygoteProcess.establishZygoteConnectionForAbi(abi);
7108 final String instructionSet = VMRuntime.getInstructionSet(abi);
7109 if (!completedIsas.contains(instructionSet)) {
7111 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7112 } catch (InstallerException e) {
7113 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7114 e.getMessage() +")");
7116 completedIsas.add(instructionSet);
7120 IntentFilter pkgFilter = new IntentFilter();
7121 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7122 pkgFilter.addDataScheme("package");
7123 mContext.registerReceiver(new BroadcastReceiver() {
7125 public void onReceive(Context context, Intent intent) {
7126 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7128 for (String pkg : pkgs) {
7129 synchronized (ActivityManagerService.this) {
7130 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7131 0, "query restart")) {
7132 setResultCode(Activity.RESULT_OK);
7141 IntentFilter dumpheapFilter = new IntentFilter();
7142 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7143 mContext.registerReceiver(new BroadcastReceiver() {
7145 public void onReceive(Context context, Intent intent) {
7146 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7147 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7149 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7154 // Let system services know.
7155 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7157 synchronized (this) {
7158 // Ensure that any processes we had put on hold are now started
7160 final int NP = mProcessesOnHold.size();
7162 ArrayList<ProcessRecord> procs =
7163 new ArrayList<ProcessRecord>(mProcessesOnHold);
7164 for (int ip=0; ip<NP; ip++) {
7165 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7167 startProcessLocked(procs.get(ip), "on-hold", null);
7171 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7172 // Start looking for apps that are abusing wake locks.
7173 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7174 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7175 // Tell anyone interested that we are done booting!
7176 SystemProperties.set("sys.boot_completed", "1");
7178 // And trigger dev.bootcomplete if we are not showing encryption progress
7179 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7180 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7181 SystemProperties.set("dev.bootcomplete", "1");
7183 mUserController.sendBootCompletedLocked(
7184 new IIntentReceiver.Stub() {
7186 public void performReceive(Intent intent, int resultCode,
7187 String data, Bundle extras, boolean ordered,
7188 boolean sticky, int sendingUser) {
7189 synchronized (ActivityManagerService.this) {
7190 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7195 scheduleStartProfilesLocked();
7201 public void bootAnimationComplete() {
7202 final boolean callFinishBooting;
7203 synchronized (this) {
7204 callFinishBooting = mCallFinishBooting;
7205 mBootAnimationComplete = true;
7207 if (callFinishBooting) {
7208 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7210 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7214 final void ensureBootCompleted() {
7216 boolean enableScreen;
7217 synchronized (this) {
7220 enableScreen = !mBooted;
7225 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7227 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7231 enableScreenAfterBoot();
7236 public final void activityResumed(IBinder token) {
7237 final long origId = Binder.clearCallingIdentity();
7238 synchronized(this) {
7239 ActivityRecord.activityResumedLocked(token);
7240 mWindowManager.notifyAppResumedFinished(token);
7242 Binder.restoreCallingIdentity(origId);
7246 public final void activityPaused(IBinder token) {
7247 final long origId = Binder.clearCallingIdentity();
7248 synchronized(this) {
7249 ActivityStack stack = ActivityRecord.getStackLocked(token);
7250 if (stack != null) {
7251 stack.activityPausedLocked(token, false);
7254 Binder.restoreCallingIdentity(origId);
7258 public final void activityStopped(IBinder token, Bundle icicle,
7259 PersistableBundle persistentState, CharSequence description) {
7260 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7262 // Refuse possible leaked file descriptors
7263 if (icicle != null && icicle.hasFileDescriptors()) {
7264 throw new IllegalArgumentException("File descriptors passed in Bundle");
7267 final long origId = Binder.clearCallingIdentity();
7269 synchronized (this) {
7270 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7272 r.activityStoppedLocked(icicle, persistentState, description);
7278 Binder.restoreCallingIdentity(origId);
7282 public final void activityDestroyed(IBinder token) {
7283 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7284 synchronized (this) {
7285 ActivityStack stack = ActivityRecord.getStackLocked(token);
7286 if (stack != null) {
7287 stack.activityDestroyedLocked(token, "activityDestroyed");
7293 public final void activityRelaunched(IBinder token) {
7294 final long origId = Binder.clearCallingIdentity();
7295 synchronized (this) {
7296 mStackSupervisor.activityRelaunchedLocked(token);
7298 Binder.restoreCallingIdentity(origId);
7302 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7303 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7304 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7305 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7306 synchronized (this) {
7307 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7308 if (record == null) {
7309 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7310 + "found for: " + token);
7312 record.setSizeConfigurations(horizontalSizeConfiguration,
7313 verticalSizeConfigurations, smallestSizeConfigurations);
7318 public final void backgroundResourcesReleased(IBinder token) {
7319 final long origId = Binder.clearCallingIdentity();
7321 synchronized (this) {
7322 ActivityStack stack = ActivityRecord.getStackLocked(token);
7323 if (stack != null) {
7324 stack.backgroundResourcesReleased();
7328 Binder.restoreCallingIdentity(origId);
7333 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7334 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7338 public final void notifyEnterAnimationComplete(IBinder token) {
7339 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7343 public String getCallingPackage(IBinder token) {
7344 synchronized (this) {
7345 ActivityRecord r = getCallingRecordLocked(token);
7346 return r != null ? r.info.packageName : null;
7351 public ComponentName getCallingActivity(IBinder token) {
7352 synchronized (this) {
7353 ActivityRecord r = getCallingRecordLocked(token);
7354 return r != null ? r.intent.getComponent() : null;
7358 private ActivityRecord getCallingRecordLocked(IBinder token) {
7359 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7367 public ComponentName getActivityClassForToken(IBinder token) {
7368 synchronized(this) {
7369 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7373 return r.intent.getComponent();
7378 public String getPackageForToken(IBinder token) {
7379 synchronized(this) {
7380 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7384 return r.packageName;
7389 public boolean isRootVoiceInteraction(IBinder token) {
7390 synchronized(this) {
7391 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7395 return r.rootVoiceInteraction;
7400 public IIntentSender getIntentSender(int type,
7401 String packageName, IBinder token, String resultWho,
7402 int requestCode, Intent[] intents, String[] resolvedTypes,
7403 int flags, Bundle bOptions, int userId) {
7404 enforceNotIsolatedCaller("getIntentSender");
7405 // Refuse possible leaked file descriptors
7406 if (intents != null) {
7407 if (intents.length < 1) {
7408 throw new IllegalArgumentException("Intents array length must be >= 1");
7410 for (int i=0; i<intents.length; i++) {
7411 Intent intent = intents[i];
7412 if (intent != null) {
7413 if (intent.hasFileDescriptors()) {
7414 throw new IllegalArgumentException("File descriptors passed in Intent");
7416 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7417 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7418 throw new IllegalArgumentException(
7419 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7421 intents[i] = new Intent(intent);
7424 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7425 throw new IllegalArgumentException(
7426 "Intent array length does not match resolvedTypes length");
7429 if (bOptions != null) {
7430 if (bOptions.hasFileDescriptors()) {
7431 throw new IllegalArgumentException("File descriptors passed in options");
7435 synchronized(this) {
7436 int callingUid = Binder.getCallingUid();
7437 int origUserId = userId;
7438 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7439 type == ActivityManager.INTENT_SENDER_BROADCAST,
7440 ALLOW_NON_FULL, "getIntentSender", null);
7441 if (origUserId == UserHandle.USER_CURRENT) {
7442 // We don't want to evaluate this until the pending intent is
7443 // actually executed. However, we do want to always do the
7444 // security checking for it above.
7445 userId = UserHandle.USER_CURRENT;
7448 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7449 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7450 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7451 if (!UserHandle.isSameApp(callingUid, uid)) {
7452 String msg = "Permission Denial: getIntentSender() from pid="
7453 + Binder.getCallingPid()
7454 + ", uid=" + Binder.getCallingUid()
7455 + ", (need uid=" + uid + ")"
7456 + " is not allowed to send as package " + packageName;
7458 throw new SecurityException(msg);
7462 return getIntentSenderLocked(type, packageName, callingUid, userId,
7463 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7465 } catch (RemoteException e) {
7466 throw new SecurityException(e);
7471 IIntentSender getIntentSenderLocked(int type, String packageName,
7472 int callingUid, int userId, IBinder token, String resultWho,
7473 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7475 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7476 ActivityRecord activity = null;
7477 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7478 activity = ActivityRecord.isInStackLocked(token);
7479 if (activity == null) {
7480 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7483 if (activity.finishing) {
7484 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7489 // We're going to be splicing together extras before sending, so we're
7490 // okay poking into any contained extras.
7491 if (intents != null) {
7492 for (int i = 0; i < intents.length; i++) {
7493 intents[i].setDefusable(true);
7496 Bundle.setDefusable(bOptions, true);
7498 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7499 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7500 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7501 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7502 |PendingIntent.FLAG_UPDATE_CURRENT);
7504 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7505 type, packageName, activity, resultWho,
7506 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7507 WeakReference<PendingIntentRecord> ref;
7508 ref = mIntentSenderRecords.get(key);
7509 PendingIntentRecord rec = ref != null ? ref.get() : null;
7511 if (!cancelCurrent) {
7512 if (updateCurrent) {
7513 if (rec.key.requestIntent != null) {
7514 rec.key.requestIntent.replaceExtras(intents != null ?
7515 intents[intents.length - 1] : null);
7517 if (intents != null) {
7518 intents[intents.length-1] = rec.key.requestIntent;
7519 rec.key.allIntents = intents;
7520 rec.key.allResolvedTypes = resolvedTypes;
7522 rec.key.allIntents = null;
7523 rec.key.allResolvedTypes = null;
7528 makeIntentSenderCanceledLocked(rec);
7529 mIntentSenderRecords.remove(key);
7534 rec = new PendingIntentRecord(this, key, callingUid);
7535 mIntentSenderRecords.put(key, rec.ref);
7536 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7537 if (activity.pendingResults == null) {
7538 activity.pendingResults
7539 = new HashSet<WeakReference<PendingIntentRecord>>();
7541 activity.pendingResults.add(rec.ref);
7547 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7548 Intent intent, String resolvedType,
7549 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7550 if (target instanceof PendingIntentRecord) {
7551 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7552 whitelistToken, finishedReceiver, requiredPermission, options);
7554 if (intent == null) {
7555 // Weird case: someone has given us their own custom IIntentSender, and now
7556 // they have someone else trying to send to it but of course this isn't
7557 // really a PendingIntent, so there is no base Intent, and the caller isn't
7558 // supplying an Intent... but we never want to dispatch a null Intent to
7559 // a receiver, so um... let's make something up.
7560 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7561 intent = new Intent(Intent.ACTION_MAIN);
7564 target.send(code, intent, resolvedType, whitelistToken, null,
7565 requiredPermission, options);
7566 } catch (RemoteException e) {
7568 // Platform code can rely on getting a result back when the send is done, but if
7569 // this intent sender is from outside of the system we can't rely on it doing that.
7570 // So instead we don't give it the result receiver, and instead just directly
7571 // report the finish immediately.
7572 if (finishedReceiver != null) {
7574 finishedReceiver.performReceive(intent, 0,
7575 null, null, false, false, UserHandle.getCallingUserId());
7576 } catch (RemoteException e) {
7584 public void cancelIntentSender(IIntentSender sender) {
7585 if (!(sender instanceof PendingIntentRecord)) {
7588 synchronized(this) {
7589 PendingIntentRecord rec = (PendingIntentRecord)sender;
7591 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7592 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7593 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7594 String msg = "Permission Denial: cancelIntentSender() from pid="
7595 + Binder.getCallingPid()
7596 + ", uid=" + Binder.getCallingUid()
7597 + " is not allowed to cancel package "
7598 + rec.key.packageName;
7600 throw new SecurityException(msg);
7602 } catch (RemoteException e) {
7603 throw new SecurityException(e);
7605 cancelIntentSenderLocked(rec, true);
7609 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7610 makeIntentSenderCanceledLocked(rec);
7611 mIntentSenderRecords.remove(rec.key);
7612 if (cleanActivity && rec.key.activity != null) {
7613 rec.key.activity.pendingResults.remove(rec.ref);
7617 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7618 rec.canceled = true;
7619 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7620 if (callbacks != null) {
7621 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7626 public String getPackageForIntentSender(IIntentSender pendingResult) {
7627 if (!(pendingResult instanceof PendingIntentRecord)) {
7631 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7632 return res.key.packageName;
7633 } catch (ClassCastException e) {
7639 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7640 if (!(sender instanceof PendingIntentRecord)) {
7643 synchronized(this) {
7644 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7649 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7650 IResultReceiver receiver) {
7651 if (!(sender instanceof PendingIntentRecord)) {
7654 synchronized(this) {
7655 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7660 public int getUidForIntentSender(IIntentSender sender) {
7661 if (sender instanceof PendingIntentRecord) {
7663 PendingIntentRecord res = (PendingIntentRecord)sender;
7665 } catch (ClassCastException e) {
7672 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7673 if (!(pendingResult instanceof PendingIntentRecord)) {
7677 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7678 if (res.key.allIntents == null) {
7681 for (int i=0; i<res.key.allIntents.length; i++) {
7682 Intent intent = res.key.allIntents[i];
7683 if (intent.getPackage() != null && intent.getComponent() != null) {
7688 } catch (ClassCastException e) {
7694 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7695 if (!(pendingResult instanceof PendingIntentRecord)) {
7699 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7700 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7704 } catch (ClassCastException e) {
7710 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7711 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7712 "getIntentForIntentSender()");
7713 if (!(pendingResult instanceof PendingIntentRecord)) {
7717 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7718 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7719 } catch (ClassCastException e) {
7725 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7726 if (!(pendingResult instanceof PendingIntentRecord)) {
7730 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7731 synchronized (this) {
7732 return getTagForIntentSenderLocked(res, prefix);
7734 } catch (ClassCastException e) {
7739 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7740 final Intent intent = res.key.requestIntent;
7741 if (intent != null) {
7742 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7743 || res.lastTagPrefix.equals(prefix))) {
7746 res.lastTagPrefix = prefix;
7747 final StringBuilder sb = new StringBuilder(128);
7748 if (prefix != null) {
7751 if (intent.getAction() != null) {
7752 sb.append(intent.getAction());
7753 } else if (intent.getComponent() != null) {
7754 intent.getComponent().appendShortString(sb);
7758 return res.lastTag = sb.toString();
7764 public void setProcessLimit(int max) {
7765 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7766 "setProcessLimit()");
7767 synchronized (this) {
7768 mConstants.setOverrideMaxCachedProcesses(max);
7774 public int getProcessLimit() {
7775 synchronized (this) {
7776 return mConstants.getOverrideMaxCachedProcesses();
7780 void importanceTokenDied(ImportanceToken token) {
7781 synchronized (ActivityManagerService.this) {
7782 synchronized (mPidsSelfLocked) {
7784 = mImportantProcesses.get(token.pid);
7788 mImportantProcesses.remove(token.pid);
7789 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7793 pr.forcingToImportant = null;
7794 updateProcessForegroundLocked(pr, false, false);
7796 updateOomAdjLocked();
7801 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7802 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7803 "setProcessImportant()");
7804 synchronized(this) {
7805 boolean changed = false;
7807 synchronized (mPidsSelfLocked) {
7808 ProcessRecord pr = mPidsSelfLocked.get(pid);
7809 if (pr == null && isForeground) {
7810 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7813 ImportanceToken oldToken = mImportantProcesses.get(pid);
7814 if (oldToken != null) {
7815 oldToken.token.unlinkToDeath(oldToken, 0);
7816 mImportantProcesses.remove(pid);
7818 pr.forcingToImportant = null;
7822 if (isForeground && token != null) {
7823 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7825 public void binderDied() {
7826 importanceTokenDied(this);
7830 token.linkToDeath(newToken, 0);
7831 mImportantProcesses.put(pid, newToken);
7832 pr.forcingToImportant = newToken;
7834 } catch (RemoteException e) {
7835 // If the process died while doing this, we will later
7836 // do the cleanup with the process death link.
7842 updateOomAdjLocked();
7848 public boolean isAppForeground(int uid) throws RemoteException {
7849 int callerUid = Binder.getCallingUid();
7850 if (UserHandle.isCore(callerUid) || callerUid == uid) {
7851 return isAppForegroundInternal(uid);
7856 private boolean isAppForegroundInternal(int uid) {
7857 synchronized (this) {
7858 UidRecord uidRec = mActiveUids.get(uid);
7859 if (uidRec == null || uidRec.idle) {
7862 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7866 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7867 // be guarded by permission checking.
7868 int getUidState(int uid) {
7869 synchronized (this) {
7870 return getUidStateLocked(uid);
7874 int getUidStateLocked(int uid) {
7875 UidRecord uidRec = mActiveUids.get(uid);
7876 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7880 public boolean isInMultiWindowMode(IBinder token) {
7881 final long origId = Binder.clearCallingIdentity();
7883 synchronized(this) {
7884 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7888 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7889 return !r.getTask().mFullscreen;
7892 Binder.restoreCallingIdentity(origId);
7897 public boolean isInPictureInPictureMode(IBinder token) {
7898 final long origId = Binder.clearCallingIdentity();
7900 synchronized(this) {
7901 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7904 Binder.restoreCallingIdentity(origId);
7908 private boolean isInPictureInPictureMode(ActivityRecord r) {
7909 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7910 r.getStack().isInStackLocked(r) == null) {
7914 // If we are animating to fullscreen then we have already dispatched the PIP mode
7915 // changed, so we should reflect that check here as well.
7916 final PinnedActivityStack stack = r.getStack();
7917 final PinnedStackWindowController windowController = stack.getWindowContainerController();
7918 return !windowController.isAnimatingBoundsToFullscreen();
7922 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7923 final long origId = Binder.clearCallingIdentity();
7925 synchronized(this) {
7926 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7927 "enterPictureInPictureMode", token, params);
7929 // If the activity is already in picture in picture mode, then just return early
7930 if (isInPictureInPictureMode(r)) {
7934 // Activity supports picture-in-picture, now check that we can enter PiP at this
7936 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7937 false /* noThrow */, false /* beforeStopping */)) {
7941 final Runnable enterPipRunnable = () -> {
7942 // Only update the saved args from the args that are set
7943 r.pictureInPictureArgs.copyOnlySet(params);
7944 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7945 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7946 // Adjust the source bounds by the insets for the transition down
7947 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
7948 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
7949 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7950 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7951 stack.setPictureInPictureAspectRatio(aspectRatio);
7952 stack.setPictureInPictureActions(actions);
7954 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7955 r.supportsPictureInPictureWhilePausing);
7956 logPictureInPictureArgs(params);
7959 if (isKeyguardLocked()) {
7960 // If the keyguard is showing or occluded, then try and dismiss it before
7961 // entering picture-in-picture (this will prompt the user to authenticate if the
7962 // device is currently locked).
7964 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7966 public void onDismissError() throws RemoteException {
7971 public void onDismissSucceeded() throws RemoteException {
7972 mHandler.post(enterPipRunnable);
7976 public void onDismissCancelled() throws RemoteException {
7980 } catch (RemoteException e) {
7984 // Enter picture in picture immediately otherwise
7985 enterPipRunnable.run();
7990 Binder.restoreCallingIdentity(origId);
7995 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
7996 final long origId = Binder.clearCallingIdentity();
7998 synchronized(this) {
7999 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8000 "setPictureInPictureParams", token, params);
8002 // Only update the saved args from the args that are set
8003 r.pictureInPictureArgs.copyOnlySet(params);
8004 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8005 // If the activity is already in picture-in-picture, update the pinned stack now
8006 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8007 // be used the next time the activity enters PiP
8008 final PinnedActivityStack stack = r.getStack();
8009 if (!stack.isAnimatingBoundsToFullscreen()) {
8010 stack.setPictureInPictureAspectRatio(
8011 r.pictureInPictureArgs.getAspectRatio());
8012 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8015 logPictureInPictureArgs(params);
8018 Binder.restoreCallingIdentity(origId);
8023 public int getMaxNumPictureInPictureActions(IBinder token) {
8024 // Currently, this is a static constant, but later, we may change this to be dependent on
8025 // the context of the activity
8029 private void logPictureInPictureArgs(PictureInPictureParams params) {
8030 if (params.hasSetActions()) {
8031 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8032 params.getActions().size());
8034 if (params.hasSetAspectRatio()) {
8035 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8036 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8037 MetricsLogger.action(lm);
8042 * Checks the state of the system and the activity associated with the given {@param token} to
8043 * verify that picture-in-picture is supported for that activity.
8045 * @return the activity record for the given {@param token} if all the checks pass.
8047 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8048 IBinder token, PictureInPictureParams params) {
8049 if (!mSupportsPictureInPicture) {
8050 throw new IllegalStateException(caller
8051 + ": Device doesn't support picture-in-picture mode.");
8054 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8056 throw new IllegalStateException(caller
8057 + ": Can't find activity for token=" + token);
8060 if (!r.supportsPictureInPicture()) {
8061 throw new IllegalStateException(caller
8062 + ": Current activity does not support picture-in-picture.");
8065 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8066 throw new IllegalStateException(caller
8067 + ": Activities on the home, assistant, or recents stack not supported");
8070 if (params.hasSetAspectRatio()
8071 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8072 params.getAspectRatio())) {
8073 final float minAspectRatio = mContext.getResources().getFloat(
8074 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8075 final float maxAspectRatio = mContext.getResources().getFloat(
8076 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8077 throw new IllegalArgumentException(String.format(caller
8078 + ": Aspect ratio is too extreme (must be between %f and %f).",
8079 minAspectRatio, maxAspectRatio));
8082 // Truncate the number of actions if necessary
8083 params.truncateActions(getMaxNumPictureInPictureActions(token));
8088 // =========================================================
8090 // =========================================================
8092 static class ProcessInfoService extends IProcessInfoService.Stub {
8093 final ActivityManagerService mActivityManagerService;
8094 ProcessInfoService(ActivityManagerService activityManagerService) {
8095 mActivityManagerService = activityManagerService;
8099 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8100 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8101 /*in*/ pids, /*out*/ states, null);
8105 public void getProcessStatesAndOomScoresFromPids(
8106 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8107 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8108 /*in*/ pids, /*out*/ states, /*out*/ scores);
8113 * For each PID in the given input array, write the current process state
8114 * for that process into the states array, or -1 to indicate that no
8115 * process with the given PID exists. If scores array is provided, write
8116 * the oom score for the process into the scores array, with INVALID_ADJ
8117 * indicating the PID doesn't exist.
8119 public void getProcessStatesAndOomScoresForPIDs(
8120 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8121 if (scores != null) {
8122 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8123 "getProcessStatesAndOomScoresForPIDs()");
8127 throw new NullPointerException("pids");
8128 } else if (states == null) {
8129 throw new NullPointerException("states");
8130 } else if (pids.length != states.length) {
8131 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8132 } else if (scores != null && pids.length != scores.length) {
8133 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8136 synchronized (mPidsSelfLocked) {
8137 for (int i = 0; i < pids.length; i++) {
8138 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8139 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8141 if (scores != null) {
8142 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8148 // =========================================================
8150 // =========================================================
8152 static class PermissionController extends IPermissionController.Stub {
8153 ActivityManagerService mActivityManagerService;
8154 PermissionController(ActivityManagerService activityManagerService) {
8155 mActivityManagerService = activityManagerService;
8159 public boolean checkPermission(String permission, int pid, int uid) {
8160 return mActivityManagerService.checkPermission(permission, pid,
8161 uid) == PackageManager.PERMISSION_GRANTED;
8165 public String[] getPackagesForUid(int uid) {
8166 return mActivityManagerService.mContext.getPackageManager()
8167 .getPackagesForUid(uid);
8171 public boolean isRuntimePermission(String permission) {
8173 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8174 .getPermissionInfo(permission, 0);
8175 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8176 == PermissionInfo.PROTECTION_DANGEROUS;
8177 } catch (NameNotFoundException nnfe) {
8178 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8184 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8186 public int checkComponentPermission(String permission, int pid, int uid,
8187 int owningUid, boolean exported) {
8188 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8189 owningUid, exported);
8193 public Object getAMSLock() {
8194 return ActivityManagerService.this;
8199 * This can be called with or without the global lock held.
8201 int checkComponentPermission(String permission, int pid, int uid,
8202 int owningUid, boolean exported) {
8203 if (pid == MY_PID) {
8204 return PackageManager.PERMISSION_GRANTED;
8206 return ActivityManager.checkComponentPermission(permission, uid,
8207 owningUid, exported);
8211 * As the only public entry point for permissions checking, this method
8212 * can enforce the semantic that requesting a check on a null global
8213 * permission is automatically denied. (Internally a null permission
8214 * string is used when calling {@link #checkComponentPermission} in cases
8215 * when only uid-based security is needed.)
8217 * This can be called with or without the global lock held.
8220 public int checkPermission(String permission, int pid, int uid) {
8221 if (permission == null) {
8222 return PackageManager.PERMISSION_DENIED;
8224 return checkComponentPermission(permission, pid, uid, -1, true);
8228 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8229 if (permission == null) {
8230 return PackageManager.PERMISSION_DENIED;
8233 // We might be performing an operation on behalf of an indirect binder
8234 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8235 // client identity accordingly before proceeding.
8236 Identity tlsIdentity = sCallerIdentity.get();
8237 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8238 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8239 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8240 uid = tlsIdentity.uid;
8241 pid = tlsIdentity.pid;
8244 return checkComponentPermission(permission, pid, uid, -1, true);
8248 * Binder IPC calls go through the public entry point.
8249 * This can be called with or without the global lock held.
8251 int checkCallingPermission(String permission) {
8252 return checkPermission(permission,
8253 Binder.getCallingPid(),
8254 UserHandle.getAppId(Binder.getCallingUid()));
8258 * This can be called with or without the global lock held.
8260 void enforceCallingPermission(String permission, String func) {
8261 if (checkCallingPermission(permission)
8262 == PackageManager.PERMISSION_GRANTED) {
8266 String msg = "Permission Denial: " + func + " from pid="
8267 + Binder.getCallingPid()
8268 + ", uid=" + Binder.getCallingUid()
8269 + " requires " + permission;
8271 throw new SecurityException(msg);
8275 * Determine if UID is holding permissions required to access {@link Uri} in
8276 * the given {@link ProviderInfo}. Final permission checking is always done
8277 * in {@link ContentProvider}.
8279 private final boolean checkHoldingPermissionsLocked(
8280 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8281 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8282 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8283 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8284 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8285 != PERMISSION_GRANTED) {
8289 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8292 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8293 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8294 if (pi.applicationInfo.uid == uid) {
8296 } else if (!pi.exported) {
8300 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8301 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8303 // check if target holds top-level <provider> permissions
8304 if (!readMet && pi.readPermission != null && considerUidPermissions
8305 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8308 if (!writeMet && pi.writePermission != null && considerUidPermissions
8309 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8313 // track if unprotected read/write is allowed; any denied
8314 // <path-permission> below removes this ability
8315 boolean allowDefaultRead = pi.readPermission == null;
8316 boolean allowDefaultWrite = pi.writePermission == null;
8318 // check if target holds any <path-permission> that match uri
8319 final PathPermission[] pps = pi.pathPermissions;
8321 final String path = grantUri.uri.getPath();
8323 while (i > 0 && (!readMet || !writeMet)) {
8325 PathPermission pp = pps[i];
8326 if (pp.match(path)) {
8328 final String pprperm = pp.getReadPermission();
8329 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8330 "Checking read perm for " + pprperm + " for " + pp.getPath()
8331 + ": match=" + pp.match(path)
8332 + " check=" + pm.checkUidPermission(pprperm, uid));
8333 if (pprperm != null) {
8334 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8335 == PERMISSION_GRANTED) {
8338 allowDefaultRead = false;
8343 final String ppwperm = pp.getWritePermission();
8344 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8345 "Checking write perm " + ppwperm + " for " + pp.getPath()
8346 + ": match=" + pp.match(path)
8347 + " check=" + pm.checkUidPermission(ppwperm, uid));
8348 if (ppwperm != null) {
8349 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8350 == PERMISSION_GRANTED) {
8353 allowDefaultWrite = false;
8361 // grant unprotected <provider> read/write, if not blocked by
8362 // <path-permission> above
8363 if (allowDefaultRead) readMet = true;
8364 if (allowDefaultWrite) writeMet = true;
8366 } catch (RemoteException e) {
8370 return readMet && writeMet;
8373 public boolean isAppStartModeDisabled(int uid, String packageName) {
8374 synchronized (this) {
8375 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8376 == ActivityManager.APP_START_MODE_DISABLED;
8380 // Unified app-op and target sdk check
8381 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8382 // Apps that target O+ are always subject to background check
8383 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8384 if (DEBUG_BACKGROUND_CHECK) {
8385 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8387 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8389 // ...and legacy apps get an AppOp check
8390 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8392 if (DEBUG_BACKGROUND_CHECK) {
8393 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8396 case AppOpsManager.MODE_ALLOWED:
8397 return ActivityManager.APP_START_MODE_NORMAL;
8398 case AppOpsManager.MODE_IGNORED:
8399 return ActivityManager.APP_START_MODE_DELAYED;
8401 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8405 // Service launch is available to apps with run-in-background exemptions but
8406 // some other background operations are not. If we're doing a check
8407 // of service-launch policy, allow those callers to proceed unrestricted.
8408 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8410 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8411 if (DEBUG_BACKGROUND_CHECK) {
8412 Slog.i(TAG, "App " + uid + "/" + packageName
8413 + " is persistent; not restricted in background");
8415 return ActivityManager.APP_START_MODE_NORMAL;
8418 // Non-persistent but background whitelisted?
8419 if (uidOnBackgroundWhitelist(uid)) {
8420 if (DEBUG_BACKGROUND_CHECK) {
8421 Slog.i(TAG, "App " + uid + "/" + packageName
8422 + " on background whitelist; not restricted in background");
8424 return ActivityManager.APP_START_MODE_NORMAL;
8427 // Is this app on the battery whitelist?
8428 if (isOnDeviceIdleWhitelistLocked(uid)) {
8429 if (DEBUG_BACKGROUND_CHECK) {
8430 Slog.i(TAG, "App " + uid + "/" + packageName
8431 + " on idle whitelist; not restricted in background");
8433 return ActivityManager.APP_START_MODE_NORMAL;
8436 // None of the service-policy criteria apply, so we apply the common criteria
8437 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8440 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8441 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8442 UidRecord uidRec = mActiveUids.get(uid);
8443 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8444 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8445 + (uidRec != null ? uidRec.idle : false));
8446 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8448 if (uidRec == null) {
8449 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8450 UserHandle.getUserId(uid), packageName);
8452 ephemeral = uidRec.ephemeral;
8456 // We are hard-core about ephemeral apps not running in the background.
8457 return ActivityManager.APP_START_MODE_DISABLED;
8460 // The caller is only interested in whether app starts are completely
8461 // disabled for the given package (that is, it is an instant app). So
8462 // we don't need to go further, which is all just seeing if we should
8463 // apply a "delayed" mode for a regular app.
8464 return ActivityManager.APP_START_MODE_NORMAL;
8466 final int startMode = (alwaysRestrict)
8467 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8468 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8470 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8471 + " pkg=" + packageName + " startMode=" + startMode
8472 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8473 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8474 // This is an old app that has been forced into a "compatible as possible"
8475 // mode of background check. To increase compatibility, we will allow other
8476 // foreground apps to cause its services to start.
8477 if (callingPid >= 0) {
8479 synchronized (mPidsSelfLocked) {
8480 proc = mPidsSelfLocked.get(callingPid);
8483 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8484 // Whoever is instigating this is in the foreground, so we will allow it
8486 return ActivityManager.APP_START_MODE_NORMAL;
8493 return ActivityManager.APP_START_MODE_NORMAL;
8496 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8497 final int appId = UserHandle.getAppId(uid);
8498 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8499 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8500 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8503 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8504 ProviderInfo pi = null;
8505 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8510 pi = AppGlobals.getPackageManager().resolveContentProvider(
8511 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8513 } catch (RemoteException ex) {
8519 void grantEphemeralAccessLocked(int userId, Intent intent,
8520 int targetAppId, int ephemeralAppId) {
8521 getPackageManagerInternalLocked().
8522 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8525 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8526 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8527 if (targetUris != null) {
8528 return targetUris.get(grantUri);
8533 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8534 String targetPkg, int targetUid, GrantUri grantUri) {
8535 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8536 if (targetUris == null) {
8537 targetUris = Maps.newArrayMap();
8538 mGrantedUriPermissions.put(targetUid, targetUris);
8541 UriPermission perm = targetUris.get(grantUri);
8543 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8544 targetUris.put(grantUri, perm);
8550 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8551 final int modeFlags) {
8552 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8553 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8554 : UriPermission.STRENGTH_OWNED;
8556 // Root gets to do everything.
8561 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8562 if (perms == null) return false;
8564 // First look for exact match
8565 final UriPermission exactPerm = perms.get(grantUri);
8566 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8570 // No exact match, look for prefixes
8571 final int N = perms.size();
8572 for (int i = 0; i < N; i++) {
8573 final UriPermission perm = perms.valueAt(i);
8574 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8575 && perm.getStrength(modeFlags) >= minStrength) {
8584 * @param uri This uri must NOT contain an embedded userId.
8585 * @param userId The userId in which the uri is to be resolved.
8588 public int checkUriPermission(Uri uri, int pid, int uid,
8589 final int modeFlags, int userId, IBinder callerToken) {
8590 enforceNotIsolatedCaller("checkUriPermission");
8592 // Another redirected-binder-call permissions check as in
8593 // {@link checkPermissionWithToken}.
8594 Identity tlsIdentity = sCallerIdentity.get();
8595 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8596 uid = tlsIdentity.uid;
8597 pid = tlsIdentity.pid;
8600 // Our own process gets to do everything.
8601 if (pid == MY_PID) {
8602 return PackageManager.PERMISSION_GRANTED;
8604 synchronized (this) {
8605 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8606 ? PackageManager.PERMISSION_GRANTED
8607 : PackageManager.PERMISSION_DENIED;
8612 * Check if the targetPkg can be granted permission to access uri by
8613 * the callingUid using the given modeFlags. Throws a security exception
8614 * if callingUid is not allowed to do this. Returns the uid of the target
8615 * if the URI permission grant should be performed; returns -1 if it is not
8616 * needed (for example targetPkg already has permission to access the URI).
8617 * If you already know the uid of the target, you can supply it in
8618 * lastTargetUid else set that to -1.
8620 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8621 final int modeFlags, int lastTargetUid) {
8622 if (!Intent.isAccessUriMode(modeFlags)) {
8626 if (targetPkg != null) {
8627 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8628 "Checking grant " + targetPkg + " permission to " + grantUri);
8631 final IPackageManager pm = AppGlobals.getPackageManager();
8633 // If this is not a content: uri, we can't do anything with it.
8634 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8635 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8636 "Can't grant URI permission for non-content URI: " + grantUri);
8640 // Bail early if system is trying to hand out permissions directly; it
8641 // must always grant permissions on behalf of someone explicit.
8642 final int callingAppId = UserHandle.getAppId(callingUid);
8643 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8644 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8645 // Exempted authority for cropping user photos in Settings app
8647 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8648 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8653 final String authority = grantUri.uri.getAuthority();
8654 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8655 MATCH_DEBUG_TRIAGED_MISSING);
8657 Slog.w(TAG, "No content provider found for permission check: " +
8658 grantUri.uri.toSafeString());
8662 int targetUid = lastTargetUid;
8663 if (targetUid < 0 && targetPkg != null) {
8665 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8666 UserHandle.getUserId(callingUid));
8667 if (targetUid < 0) {
8668 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8669 "Can't grant URI permission no uid for: " + targetPkg);
8672 } catch (RemoteException ex) {
8677 // Figure out the value returned when access is allowed
8678 final int allowedResult;
8679 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8680 // If we're extending a persistable grant, then we need to return
8681 // "targetUid" so that we always create a grant data structure to
8682 // support take/release APIs
8683 allowedResult = targetUid;
8685 // Otherwise, we can return "-1" to indicate that no grant data
8686 // structures need to be created
8690 if (targetUid >= 0) {
8691 // First... does the target actually need this permission?
8692 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8693 // No need to grant the target this permission.
8694 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8695 "Target " + targetPkg + " already has full permission to " + grantUri);
8696 return allowedResult;
8699 // First... there is no target package, so can anyone access it?
8700 boolean allowed = pi.exported;
8701 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8702 if (pi.readPermission != null) {
8706 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8707 if (pi.writePermission != null) {
8712 return allowedResult;
8716 /* There is a special cross user grant if:
8717 * - The target is on another user.
8718 * - Apps on the current user can access the uri without any uid permissions.
8719 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8720 * grant uri permissions.
8722 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8723 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8724 modeFlags, false /*without considering the uid permissions*/);
8726 // Second... is the provider allowing granting of URI permissions?
8727 if (!specialCrossUserGrant) {
8728 if (!pi.grantUriPermissions) {
8729 throw new SecurityException("Provider " + pi.packageName
8731 + " does not allow granting of Uri permissions (uri "
8734 if (pi.uriPermissionPatterns != null) {
8735 final int N = pi.uriPermissionPatterns.length;
8736 boolean allowed = false;
8737 for (int i=0; i<N; i++) {
8738 if (pi.uriPermissionPatterns[i] != null
8739 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8745 throw new SecurityException("Provider " + pi.packageName
8747 + " does not allow granting of permission to path of Uri "
8753 // Third... does the caller itself have permission to access
8755 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8756 // Require they hold a strong enough Uri permission
8757 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8758 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8759 throw new SecurityException(
8760 "UID " + callingUid + " does not have permission to " + grantUri
8761 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8762 + "or related APIs");
8764 throw new SecurityException(
8765 "UID " + callingUid + " does not have permission to " + grantUri);
8773 * @param uri This uri must NOT contain an embedded userId.
8774 * @param userId The userId in which the uri is to be resolved.
8777 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8778 final int modeFlags, int userId) {
8779 enforceNotIsolatedCaller("checkGrantUriPermission");
8780 synchronized(this) {
8781 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8782 new GrantUri(userId, uri, false), modeFlags, -1);
8786 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8787 final int modeFlags, UriPermissionOwner owner) {
8788 if (!Intent.isAccessUriMode(modeFlags)) {
8792 // So here we are: the caller has the assumed permission
8793 // to the uri, and the target doesn't. Let's now give this to
8796 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8797 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8799 final String authority = grantUri.uri.getAuthority();
8800 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8801 MATCH_DEBUG_TRIAGED_MISSING);
8803 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8807 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8808 grantUri.prefix = true;
8810 final UriPermission perm = findOrCreateUriPermissionLocked(
8811 pi.packageName, targetPkg, targetUid, grantUri);
8812 perm.grantModes(modeFlags, owner);
8815 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8816 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8817 if (targetPkg == null) {
8818 throw new NullPointerException("targetPkg");
8821 final IPackageManager pm = AppGlobals.getPackageManager();
8823 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8824 } catch (RemoteException ex) {
8828 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8830 if (targetUid < 0) {
8834 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8838 static class NeededUriGrants extends ArrayList<GrantUri> {
8839 final String targetPkg;
8840 final int targetUid;
8843 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8844 this.targetPkg = targetPkg;
8845 this.targetUid = targetUid;
8851 * Like checkGrantUriPermissionLocked, but takes an Intent.
8853 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8854 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8855 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8856 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8857 + " clip=" + (intent != null ? intent.getClipData() : null)
8858 + " from " + intent + "; flags=0x"
8859 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8861 if (targetPkg == null) {
8862 throw new NullPointerException("targetPkg");
8865 if (intent == null) {
8868 Uri data = intent.getData();
8869 ClipData clip = intent.getClipData();
8870 if (data == null && clip == null) {
8873 // Default userId for uris in the intent (if they don't specify it themselves)
8874 int contentUserHint = intent.getContentUserHint();
8875 if (contentUserHint == UserHandle.USER_CURRENT) {
8876 contentUserHint = UserHandle.getUserId(callingUid);
8878 final IPackageManager pm = AppGlobals.getPackageManager();
8880 if (needed != null) {
8881 targetUid = needed.targetUid;
8884 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8886 } catch (RemoteException ex) {
8889 if (targetUid < 0) {
8890 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8891 "Can't grant URI permission no uid for: " + targetPkg
8892 + " on user " + targetUserId);
8897 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8898 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8900 if (targetUid > 0) {
8901 if (needed == null) {
8902 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8904 needed.add(grantUri);
8908 for (int i=0; i<clip.getItemCount(); i++) {
8909 Uri uri = clip.getItemAt(i).getUri();
8911 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8912 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8914 if (targetUid > 0) {
8915 if (needed == null) {
8916 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8918 needed.add(grantUri);
8921 Intent clipIntent = clip.getItemAt(i).getIntent();
8922 if (clipIntent != null) {
8923 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8924 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8925 if (newNeeded != null) {
8937 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8939 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8940 UriPermissionOwner owner) {
8941 if (needed != null) {
8942 for (int i=0; i<needed.size(); i++) {
8943 GrantUri grantUri = needed.get(i);
8944 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8945 grantUri, needed.flags, owner);
8950 void grantUriPermissionFromIntentLocked(int callingUid,
8951 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8952 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8953 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8954 if (needed == null) {
8958 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8962 * @param uri This uri must NOT contain an embedded userId.
8963 * @param userId The userId in which the uri is to be resolved.
8966 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8967 final int modeFlags, int userId) {
8968 enforceNotIsolatedCaller("grantUriPermission");
8969 GrantUri grantUri = new GrantUri(userId, uri, false);
8970 synchronized(this) {
8971 final ProcessRecord r = getRecordForAppLocked(caller);
8973 throw new SecurityException("Unable to find app for caller "
8975 + " when granting permission to uri " + grantUri);
8977 if (targetPkg == null) {
8978 throw new IllegalArgumentException("null target");
8980 if (grantUri == null) {
8981 throw new IllegalArgumentException("null uri");
8984 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8985 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8986 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8987 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8989 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8990 UserHandle.getUserId(r.uid));
8994 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8995 if (perm.modeFlags == 0) {
8996 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8998 if (perms != null) {
8999 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9000 "Removing " + perm.targetUid + " permission to " + perm.uri);
9002 perms.remove(perm.uri);
9003 if (perms.isEmpty()) {
9004 mGrantedUriPermissions.remove(perm.targetUid);
9010 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9011 final int modeFlags) {
9012 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9013 "Revoking all granted permissions to " + grantUri);
9015 final IPackageManager pm = AppGlobals.getPackageManager();
9016 final String authority = grantUri.uri.getAuthority();
9017 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9018 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9020 Slog.w(TAG, "No content provider found for permission revoke: "
9021 + grantUri.toSafeString());
9025 // Does the caller have this permission on the URI?
9026 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9027 // If they don't have direct access to the URI, then revoke any
9028 // ownerless URI permissions that have been granted to them.
9029 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9030 if (perms != null) {
9031 boolean persistChanged = false;
9032 for (int i = perms.size()-1; i >= 0; i--) {
9033 final UriPermission perm = perms.valueAt(i);
9034 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9037 if (perm.uri.sourceUserId == grantUri.sourceUserId
9038 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9039 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9040 "Revoking non-owned " + perm.targetUid
9041 + " permission to " + perm.uri);
9042 persistChanged |= perm.revokeModes(
9043 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9044 if (perm.modeFlags == 0) {
9049 if (perms.isEmpty()) {
9050 mGrantedUriPermissions.remove(callingUid);
9052 if (persistChanged) {
9053 schedulePersistUriGrants();
9059 boolean persistChanged = false;
9061 // Go through all of the permissions and remove any that match.
9062 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9063 final int targetUid = mGrantedUriPermissions.keyAt(i);
9064 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9066 for (int j = perms.size()-1; j >= 0; j--) {
9067 final UriPermission perm = perms.valueAt(j);
9068 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9071 if (perm.uri.sourceUserId == grantUri.sourceUserId
9072 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9073 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9074 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9075 persistChanged |= perm.revokeModes(
9076 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9077 targetPackage == null);
9078 if (perm.modeFlags == 0) {
9084 if (perms.isEmpty()) {
9085 mGrantedUriPermissions.removeAt(i);
9089 if (persistChanged) {
9090 schedulePersistUriGrants();
9095 * @param uri This uri must NOT contain an embedded userId.
9096 * @param userId The userId in which the uri is to be resolved.
9099 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9100 final int modeFlags, int userId) {
9101 enforceNotIsolatedCaller("revokeUriPermission");
9102 synchronized(this) {
9103 final ProcessRecord r = getRecordForAppLocked(caller);
9105 throw new SecurityException("Unable to find app for caller "
9107 + " when revoking permission to uri " + uri);
9110 Slog.w(TAG, "revokeUriPermission: null uri");
9114 if (!Intent.isAccessUriMode(modeFlags)) {
9118 final String authority = uri.getAuthority();
9119 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9120 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9122 Slog.w(TAG, "No content provider found for permission revoke: "
9123 + uri.toSafeString());
9127 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9133 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9136 * @param packageName Package name to match, or {@code null} to apply to all
9138 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9140 * @param persistable If persistable grants should be removed.
9142 private void removeUriPermissionsForPackageLocked(
9143 String packageName, int userHandle, boolean persistable) {
9144 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9145 throw new IllegalArgumentException("Must narrow by either package or user");
9148 boolean persistChanged = false;
9150 int N = mGrantedUriPermissions.size();
9151 for (int i = 0; i < N; i++) {
9152 final int targetUid = mGrantedUriPermissions.keyAt(i);
9153 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9155 // Only inspect grants matching user
9156 if (userHandle == UserHandle.USER_ALL
9157 || userHandle == UserHandle.getUserId(targetUid)) {
9158 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9159 final UriPermission perm = it.next();
9161 // Only inspect grants matching package
9162 if (packageName == null || perm.sourcePkg.equals(packageName)
9163 || perm.targetPkg.equals(packageName)) {
9164 // Hacky solution as part of fixing a security bug; ignore
9165 // grants associated with DownloadManager so we don't have
9166 // to immediately launch it to regrant the permissions
9167 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9168 && !persistable) continue;
9170 persistChanged |= perm.revokeModes(persistable
9171 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9173 // Only remove when no modes remain; any persisted grants
9174 // will keep this alive.
9175 if (perm.modeFlags == 0) {
9181 if (perms.isEmpty()) {
9182 mGrantedUriPermissions.remove(targetUid);
9189 if (persistChanged) {
9190 schedulePersistUriGrants();
9195 public IBinder newUriPermissionOwner(String name) {
9196 enforceNotIsolatedCaller("newUriPermissionOwner");
9197 synchronized(this) {
9198 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9199 return owner.getExternalTokenLocked();
9204 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9205 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9206 synchronized(this) {
9207 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9209 throw new IllegalArgumentException("Activity does not exist; token="
9212 return r.getUriPermissionsLocked().getExternalTokenLocked();
9216 * @param uri This uri must NOT contain an embedded userId.
9217 * @param sourceUserId The userId in which the uri is to be resolved.
9218 * @param targetUserId The userId of the app that receives the grant.
9221 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9222 final int modeFlags, int sourceUserId, int targetUserId) {
9223 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9224 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9225 "grantUriPermissionFromOwner", null);
9226 synchronized(this) {
9227 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9228 if (owner == null) {
9229 throw new IllegalArgumentException("Unknown owner: " + token);
9231 if (fromUid != Binder.getCallingUid()) {
9232 if (Binder.getCallingUid() != myUid()) {
9233 // Only system code can grant URI permissions on behalf
9235 throw new SecurityException("nice try");
9238 if (targetPkg == null) {
9239 throw new IllegalArgumentException("null target");
9242 throw new IllegalArgumentException("null uri");
9245 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9246 modeFlags, owner, targetUserId);
9251 * @param uri This uri must NOT contain an embedded userId.
9252 * @param userId The userId in which the uri is to be resolved.
9255 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9256 synchronized(this) {
9257 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9258 if (owner == null) {
9259 throw new IllegalArgumentException("Unknown owner: " + token);
9263 owner.removeUriPermissionsLocked(mode);
9265 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9266 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9271 private void schedulePersistUriGrants() {
9272 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9273 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9274 10 * DateUtils.SECOND_IN_MILLIS);
9278 private void writeGrantedUriPermissions() {
9279 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9281 // Snapshot permissions so we can persist without lock
9282 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9283 synchronized (this) {
9284 final int size = mGrantedUriPermissions.size();
9285 for (int i = 0; i < size; i++) {
9286 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9287 for (UriPermission perm : perms.values()) {
9288 if (perm.persistedModeFlags != 0) {
9289 persist.add(perm.snapshot());
9295 FileOutputStream fos = null;
9297 fos = mGrantFile.startWrite();
9299 XmlSerializer out = new FastXmlSerializer();
9300 out.setOutput(fos, StandardCharsets.UTF_8.name());
9301 out.startDocument(null, true);
9302 out.startTag(null, TAG_URI_GRANTS);
9303 for (UriPermission.Snapshot perm : persist) {
9304 out.startTag(null, TAG_URI_GRANT);
9305 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9306 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9307 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9308 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9309 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9310 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9311 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9312 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9313 out.endTag(null, TAG_URI_GRANT);
9315 out.endTag(null, TAG_URI_GRANTS);
9318 mGrantFile.finishWrite(fos);
9319 } catch (IOException e) {
9321 mGrantFile.failWrite(fos);
9326 private void readGrantedUriPermissionsLocked() {
9327 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9329 final long now = System.currentTimeMillis();
9331 FileInputStream fis = null;
9333 fis = mGrantFile.openRead();
9334 final XmlPullParser in = Xml.newPullParser();
9335 in.setInput(fis, StandardCharsets.UTF_8.name());
9338 while ((type = in.next()) != END_DOCUMENT) {
9339 final String tag = in.getName();
9340 if (type == START_TAG) {
9341 if (TAG_URI_GRANT.equals(tag)) {
9342 final int sourceUserId;
9343 final int targetUserId;
9344 final int userHandle = readIntAttribute(in,
9345 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9346 if (userHandle != UserHandle.USER_NULL) {
9347 // For backwards compatibility.
9348 sourceUserId = userHandle;
9349 targetUserId = userHandle;
9351 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9352 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9354 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9355 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9356 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9357 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9358 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9359 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9361 // Sanity check that provider still belongs to source package
9362 // Both direct boot aware and unaware packages are fine as we
9363 // will do filtering at query time to avoid multiple parsing.
9364 final ProviderInfo pi = getProviderInfoLocked(
9365 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9366 | MATCH_DIRECT_BOOT_UNAWARE);
9367 if (pi != null && sourcePkg.equals(pi.packageName)) {
9370 targetUid = AppGlobals.getPackageManager().getPackageUid(
9371 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9372 } catch (RemoteException e) {
9374 if (targetUid != -1) {
9375 final UriPermission perm = findOrCreateUriPermissionLocked(
9376 sourcePkg, targetPkg, targetUid,
9377 new GrantUri(sourceUserId, uri, prefix));
9378 perm.initPersistedModes(modeFlags, createdTime);
9381 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9382 + " but instead found " + pi);
9387 } catch (FileNotFoundException e) {
9388 // Missing grants is okay
9389 } catch (IOException e) {
9390 Slog.wtf(TAG, "Failed reading Uri grants", e);
9391 } catch (XmlPullParserException e) {
9392 Slog.wtf(TAG, "Failed reading Uri grants", e);
9394 IoUtils.closeQuietly(fis);
9399 * @param uri This uri must NOT contain an embedded userId.
9400 * @param userId The userId in which the uri is to be resolved.
9403 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9404 enforceNotIsolatedCaller("takePersistableUriPermission");
9406 Preconditions.checkFlagsArgument(modeFlags,
9407 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9409 synchronized (this) {
9410 final int callingUid = Binder.getCallingUid();
9411 boolean persistChanged = false;
9412 GrantUri grantUri = new GrantUri(userId, uri, false);
9414 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9415 new GrantUri(userId, uri, false));
9416 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9417 new GrantUri(userId, uri, true));
9419 final boolean exactValid = (exactPerm != null)
9420 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9421 final boolean prefixValid = (prefixPerm != null)
9422 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9424 if (!(exactValid || prefixValid)) {
9425 throw new SecurityException("No persistable permission grants found for UID "
9426 + callingUid + " and Uri " + grantUri.toSafeString());
9430 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9433 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9436 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9438 if (persistChanged) {
9439 schedulePersistUriGrants();
9445 * @param uri This uri must NOT contain an embedded userId.
9446 * @param userId The userId in which the uri is to be resolved.
9449 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9450 enforceNotIsolatedCaller("releasePersistableUriPermission");
9452 Preconditions.checkFlagsArgument(modeFlags,
9453 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9455 synchronized (this) {
9456 final int callingUid = Binder.getCallingUid();
9457 boolean persistChanged = false;
9459 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9460 new GrantUri(userId, uri, false));
9461 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9462 new GrantUri(userId, uri, true));
9463 if (exactPerm == null && prefixPerm == null) {
9464 throw new SecurityException("No permission grants found for UID " + callingUid
9465 + " and Uri " + uri.toSafeString());
9468 if (exactPerm != null) {
9469 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9470 removeUriPermissionIfNeededLocked(exactPerm);
9472 if (prefixPerm != null) {
9473 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9474 removeUriPermissionIfNeededLocked(prefixPerm);
9477 if (persistChanged) {
9478 schedulePersistUriGrants();
9484 * Prune any older {@link UriPermission} for the given UID until outstanding
9485 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9487 * @return if any mutations occured that require persisting.
9489 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9490 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9491 if (perms == null) return false;
9492 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9494 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9495 for (UriPermission perm : perms.values()) {
9496 if (perm.persistedModeFlags != 0) {
9497 persisted.add(perm);
9501 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9502 if (trimCount <= 0) return false;
9504 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9505 for (int i = 0; i < trimCount; i++) {
9506 final UriPermission perm = persisted.get(i);
9508 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9509 "Trimming grant created at " + perm.persistedCreateTime);
9511 perm.releasePersistableModes(~0);
9512 removeUriPermissionIfNeededLocked(perm);
9519 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9520 String packageName, boolean incoming) {
9521 enforceNotIsolatedCaller("getPersistedUriPermissions");
9522 Preconditions.checkNotNull(packageName, "packageName");
9524 final int callingUid = Binder.getCallingUid();
9525 final int callingUserId = UserHandle.getUserId(callingUid);
9526 final IPackageManager pm = AppGlobals.getPackageManager();
9528 final int packageUid = pm.getPackageUid(packageName,
9529 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9530 if (packageUid != callingUid) {
9531 throw new SecurityException(
9532 "Package " + packageName + " does not belong to calling UID " + callingUid);
9534 } catch (RemoteException e) {
9535 throw new SecurityException("Failed to verify package name ownership");
9538 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9539 synchronized (this) {
9541 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9543 if (perms == null) {
9544 Slog.w(TAG, "No permission grants found for " + packageName);
9546 for (UriPermission perm : perms.values()) {
9547 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9548 result.add(perm.buildPersistedPublicApiObject());
9553 final int size = mGrantedUriPermissions.size();
9554 for (int i = 0; i < size; i++) {
9555 final ArrayMap<GrantUri, UriPermission> perms =
9556 mGrantedUriPermissions.valueAt(i);
9557 for (UriPermission perm : perms.values()) {
9558 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9559 result.add(perm.buildPersistedPublicApiObject());
9565 return new ParceledListSlice<android.content.UriPermission>(result);
9569 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9570 String packageName, int userId) {
9571 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9572 "getGrantedUriPermissions");
9574 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9575 synchronized (this) {
9576 final int size = mGrantedUriPermissions.size();
9577 for (int i = 0; i < size; i++) {
9578 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9579 for (UriPermission perm : perms.values()) {
9580 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9581 && perm.persistedModeFlags != 0) {
9582 result.add(perm.buildPersistedPublicApiObject());
9587 return new ParceledListSlice<android.content.UriPermission>(result);
9591 public void clearGrantedUriPermissions(String packageName, int userId) {
9592 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9593 "clearGrantedUriPermissions");
9594 removeUriPermissionsForPackageLocked(packageName, userId, true);
9598 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9599 synchronized (this) {
9601 who != null ? getRecordForAppLocked(who) : null;
9602 if (app == null) return;
9604 Message msg = Message.obtain();
9605 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9607 msg.arg1 = waiting ? 1 : 0;
9608 mUiHandler.sendMessage(msg);
9613 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9614 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9615 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9616 outInfo.availMem = getFreeMemory();
9617 outInfo.totalMem = getTotalMemory();
9618 outInfo.threshold = homeAppMem;
9619 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9620 outInfo.hiddenAppThreshold = cachedAppMem;
9621 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9622 ProcessList.SERVICE_ADJ);
9623 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9624 ProcessList.VISIBLE_APP_ADJ);
9625 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9626 ProcessList.FOREGROUND_APP_ADJ);
9629 // =========================================================
9631 // =========================================================
9634 public List<IBinder> getAppTasks(String callingPackage) {
9635 int callingUid = Binder.getCallingUid();
9636 long ident = Binder.clearCallingIdentity();
9638 synchronized(this) {
9639 ArrayList<IBinder> list = new ArrayList<IBinder>();
9641 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9643 final int N = mRecentTasks.size();
9644 for (int i = 0; i < N; i++) {
9645 TaskRecord tr = mRecentTasks.get(i);
9646 // Skip tasks that do not match the caller. We don't need to verify
9647 // callingPackage, because we are also limiting to callingUid and know
9648 // that will limit to the correct security sandbox.
9649 if (tr.effectiveUid != callingUid) {
9652 Intent intent = tr.getBaseIntent();
9653 if (intent == null ||
9654 !callingPackage.equals(intent.getComponent().getPackageName())) {
9657 ActivityManager.RecentTaskInfo taskInfo =
9658 createRecentTaskInfoFromTaskRecord(tr);
9659 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9660 list.add(taskImpl.asBinder());
9663 Binder.restoreCallingIdentity(ident);
9670 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9671 final int callingUid = Binder.getCallingUid();
9672 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9674 synchronized(this) {
9675 if (DEBUG_ALL) Slog.v(
9676 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9678 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9681 // TODO: Improve with MRU list from all ActivityStacks.
9682 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9689 * Creates a new RecentTaskInfo from a TaskRecord.
9691 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9692 // Update the task description to reflect any changes in the task stack
9693 tr.updateTaskDescription();
9695 // Compose the recent task info
9696 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9697 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9698 rti.persistentId = tr.taskId;
9699 rti.baseIntent = new Intent(tr.getBaseIntent());
9700 rti.origActivity = tr.origActivity;
9701 rti.realActivity = tr.realActivity;
9702 rti.description = tr.lastDescription;
9703 rti.stackId = tr.getStackId();
9704 rti.userId = tr.userId;
9705 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9706 rti.firstActiveTime = tr.firstActiveTime;
9707 rti.lastActiveTime = tr.lastActiveTime;
9708 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9709 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9710 rti.numActivities = 0;
9711 if (tr.mBounds != null) {
9712 rti.bounds = new Rect(tr.mBounds);
9714 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9715 rti.resizeMode = tr.mResizeMode;
9717 ActivityRecord base = null;
9718 ActivityRecord top = null;
9721 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9722 tmp = tr.mActivities.get(i);
9723 if (tmp.finishing) {
9727 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9730 rti.numActivities++;
9733 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9734 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9739 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9740 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9741 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9743 if (checkPermission(android.Manifest.permission.GET_TASKS,
9744 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9745 // Temporary compatibility: some existing apps on the system image may
9746 // still be requesting the old permission and not switched to the new
9747 // one; if so, we'll still allow them full access. This means we need
9748 // to see if they are holding the old permission and are a system app.
9750 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9752 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9753 + " is using old GET_TASKS but privileged; allowing");
9755 } catch (RemoteException e) {
9760 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9761 + " does not hold REAL_GET_TASKS; limiting output");
9767 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9769 final int callingUid = Binder.getCallingUid();
9770 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9771 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9773 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9774 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9775 synchronized (this) {
9776 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9778 final boolean detailed = checkCallingPermission(
9779 android.Manifest.permission.GET_DETAILED_TASKS)
9780 == PackageManager.PERMISSION_GRANTED;
9782 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9783 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9784 return ParceledListSlice.emptyList();
9786 mRecentTasks.loadUserRecentsLocked(userId);
9788 final int recentsCount = mRecentTasks.size();
9789 ArrayList<ActivityManager.RecentTaskInfo> res =
9790 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9792 final Set<Integer> includedUsers;
9793 if (includeProfiles) {
9794 includedUsers = mUserController.getProfileIds(userId);
9796 includedUsers = new HashSet<>();
9798 includedUsers.add(Integer.valueOf(userId));
9800 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9801 TaskRecord tr = mRecentTasks.get(i);
9802 // Only add calling user or related users recent tasks
9803 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9804 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9808 if (tr.realActivitySuspended) {
9809 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9813 // Return the entry if desired by the caller. We always return
9814 // the first entry, because callers always expect this to be the
9815 // foreground app. We may filter others if the caller has
9816 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9817 // we should exclude the entry.
9821 || (tr.intent == null)
9822 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9825 // If the caller doesn't have the GET_TASKS permission, then only
9826 // allow them to see a small subset of tasks -- their own and home.
9827 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9828 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9832 final ActivityStack stack = tr.getStack();
9833 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9834 if (stack != null && stack.isHomeOrRecentsStack()) {
9835 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9836 "Skipping, home or recents stack task: " + tr);
9840 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9841 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9842 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9843 "Skipping, top task in docked stack: " + tr);
9847 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9848 if (stack != null && stack.isPinnedStack()) {
9849 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9850 "Skipping, pinned stack task: " + tr);
9854 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9855 // Don't include auto remove tasks that are finished or finishing.
9856 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9857 "Skipping, auto-remove without activity: " + tr);
9860 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9861 && !tr.isAvailable) {
9862 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9863 "Skipping, unavail real act: " + tr);
9867 if (!tr.mUserSetupComplete) {
9868 // Don't include task launched while user is not done setting-up.
9869 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9870 "Skipping, user setup not complete: " + tr);
9874 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9876 rti.baseIntent.replaceExtras((Bundle)null);
9883 return new ParceledListSlice<>(res);
9888 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9889 synchronized (this) {
9890 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9891 "getTaskThumbnail()");
9892 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9893 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9895 return tr.getTaskThumbnailLocked();
9902 public ActivityManager.TaskDescription getTaskDescription(int id) {
9903 synchronized (this) {
9904 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9905 "getTaskDescription()");
9906 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9907 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9909 return tr.lastTaskDescription;
9916 public int addAppTask(IBinder activityToken, Intent intent,
9917 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9918 final int callingUid = Binder.getCallingUid();
9919 final long callingIdent = Binder.clearCallingIdentity();
9922 synchronized (this) {
9923 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9925 throw new IllegalArgumentException("Activity does not exist; token="
9928 ComponentName comp = intent.getComponent();
9930 throw new IllegalArgumentException("Intent " + intent
9931 + " must specify explicit component");
9933 if (thumbnail.getWidth() != mThumbnailWidth
9934 || thumbnail.getHeight() != mThumbnailHeight) {
9935 throw new IllegalArgumentException("Bad thumbnail size: got "
9936 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9937 + mThumbnailWidth + "x" + mThumbnailHeight);
9939 if (intent.getSelector() != null) {
9940 intent.setSelector(null);
9942 if (intent.getSourceBounds() != null) {
9943 intent.setSourceBounds(null);
9945 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9946 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9947 // The caller has added this as an auto-remove task... that makes no
9948 // sense, so turn off auto-remove.
9949 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9952 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9953 mLastAddedTaskActivity = null;
9955 ActivityInfo ainfo = mLastAddedTaskActivity;
9956 if (ainfo == null) {
9957 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9958 comp, 0, UserHandle.getUserId(callingUid));
9959 if (ainfo.applicationInfo.uid != callingUid) {
9960 throw new SecurityException(
9961 "Can't add task for another application: target uid="
9962 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9966 TaskRecord task = new TaskRecord(this,
9967 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9968 ainfo, intent, description, new TaskThumbnailInfo());
9970 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9972 // If this would have caused a trim, then we'll abort because that
9973 // means it would be added at the end of the list but then just removed.
9974 return INVALID_TASK_ID;
9977 final int N = mRecentTasks.size();
9978 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9979 final TaskRecord tr = mRecentTasks.remove(N - 1);
9980 tr.removedFromRecents();
9983 task.inRecents = true;
9984 mRecentTasks.add(task);
9985 r.getStack().addTask(task, false, "addAppTask");
9987 task.setLastThumbnailLocked(thumbnail);
9988 task.freeLastThumbnail();
9992 Binder.restoreCallingIdentity(callingIdent);
9997 public Point getAppTaskThumbnailSize() {
9998 synchronized (this) {
9999 return new Point(mThumbnailWidth, mThumbnailHeight);
10004 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10005 synchronized (this) {
10006 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10008 r.setTaskDescription(td);
10009 final TaskRecord task = r.getTask();
10010 task.updateTaskDescription();
10011 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10017 public void setTaskResizeable(int taskId, int resizeableMode) {
10018 synchronized (this) {
10019 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10020 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10021 if (task == null) {
10022 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10025 task.setResizeMode(resizeableMode);
10030 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10031 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10032 long ident = Binder.clearCallingIdentity();
10034 synchronized (this) {
10035 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10036 if (task == null) {
10037 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10040 // Place the task in the right stack if it isn't there already based on
10041 // the requested bounds.
10042 // The stack transition logic is:
10043 // - a null bounds on a freeform task moves that task to fullscreen
10044 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10045 // that task to freeform
10046 // - otherwise the task is not moved
10047 int stackId = task.getStackId();
10048 if (!StackId.isTaskResizeAllowed(stackId)) {
10049 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10051 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10052 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10053 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10054 stackId = FREEFORM_WORKSPACE_STACK_ID;
10057 // Reparent the task to the right stack if necessary
10058 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10059 if (stackId != task.getStackId()) {
10060 // Defer resume until the task is resized below
10061 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10062 DEFER_RESUME, "resizeTask");
10063 preserveWindow = false;
10066 // After reparenting (which only resizes the task to the stack bounds), resize the
10067 // task to the actual bounds provided
10068 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10071 Binder.restoreCallingIdentity(ident);
10076 public Rect getTaskBounds(int taskId) {
10077 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10078 long ident = Binder.clearCallingIdentity();
10079 Rect rect = new Rect();
10081 synchronized (this) {
10082 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10083 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10084 if (task == null) {
10085 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10088 if (task.getStack() != null) {
10089 // Return the bounds from window manager since it will be adjusted for various
10090 // things like the presense of a docked stack for tasks that aren't resizeable.
10091 task.getWindowContainerBounds(rect);
10093 // Task isn't in window manager yet since it isn't associated with a stack.
10094 // Return the persist value from activity manager
10095 if (task.mBounds != null) {
10096 rect.set(task.mBounds);
10097 } else if (task.mLastNonFullscreenBounds != null) {
10098 rect.set(task.mLastNonFullscreenBounds);
10103 Binder.restoreCallingIdentity(ident);
10109 public void cancelTaskWindowTransition(int taskId) {
10110 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10111 final long ident = Binder.clearCallingIdentity();
10113 synchronized (this) {
10114 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10115 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10116 if (task == null) {
10117 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10120 task.cancelWindowTransition();
10123 Binder.restoreCallingIdentity(ident);
10128 public void cancelTaskThumbnailTransition(int taskId) {
10129 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10130 final long ident = Binder.clearCallingIdentity();
10132 synchronized (this) {
10133 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10134 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10135 if (task == null) {
10136 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10139 task.cancelThumbnailTransition();
10142 Binder.restoreCallingIdentity(ident);
10147 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10148 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10149 final long ident = Binder.clearCallingIdentity();
10151 final TaskRecord task;
10152 synchronized (this) {
10153 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10154 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10155 if (task == null) {
10156 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10160 // Don't call this while holding the lock as this operation might hit the disk.
10161 return task.getSnapshot(reducedResolution);
10163 Binder.restoreCallingIdentity(ident);
10168 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10169 if (userId != UserHandle.getCallingUserId()) {
10170 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10171 "getTaskDescriptionIcon");
10173 final File passedIconFile = new File(filePath);
10174 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10175 passedIconFile.getName());
10176 if (!legitIconFile.getPath().equals(filePath)
10177 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10178 throw new IllegalArgumentException("Bad file path: " + filePath
10179 + " passed for userId " + userId);
10181 return mRecentTasks.getTaskDescriptionIcon(filePath);
10185 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10186 throws RemoteException {
10187 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10188 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10189 activityOptions.getCustomInPlaceResId() == 0) {
10190 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10191 "with valid animation");
10193 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10194 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10195 activityOptions.getCustomInPlaceResId());
10196 mWindowManager.executeAppTransition();
10199 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10200 // Remove all tasks with activities in the specified package from the list of recent tasks
10201 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10202 TaskRecord tr = mRecentTasks.get(i);
10203 if (tr.userId != userId) continue;
10205 ComponentName cn = tr.intent.getComponent();
10206 if (cn != null && cn.getPackageName().equals(packageName)) {
10207 // If the package name matches, remove the task.
10208 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10213 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10216 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10217 TaskRecord tr = mRecentTasks.get(i);
10218 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10222 ComponentName cn = tr.intent.getComponent();
10223 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10224 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10225 if (sameComponent) {
10226 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10232 public void removeStack(int stackId) {
10233 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10234 if (StackId.isHomeOrRecentsStack(stackId)) {
10235 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10238 synchronized (this) {
10239 final long ident = Binder.clearCallingIdentity();
10241 mStackSupervisor.removeStackLocked(stackId);
10243 Binder.restoreCallingIdentity(ident);
10249 public void moveStackToDisplay(int stackId, int displayId) {
10250 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10252 synchronized (this) {
10253 final long ident = Binder.clearCallingIdentity();
10255 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10256 + " to displayId=" + displayId);
10257 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10259 Binder.restoreCallingIdentity(ident);
10265 public boolean removeTask(int taskId) {
10266 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10267 synchronized (this) {
10268 final long ident = Binder.clearCallingIdentity();
10270 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10272 Binder.restoreCallingIdentity(ident);
10278 * TODO: Add mController hook
10281 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10282 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10284 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10285 synchronized(this) {
10286 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10290 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10291 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10293 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10294 Binder.getCallingUid(), -1, -1, "Task to front")) {
10295 ActivityOptions.abort(options);
10298 final long origId = Binder.clearCallingIdentity();
10300 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10301 if (task == null) {
10302 Slog.d(TAG, "Could not find task for id: "+ taskId);
10305 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10306 mStackSupervisor.showLockTaskToast();
10307 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10310 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10311 if (prev != null) {
10312 task.setTaskToReturnTo(prev);
10314 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10315 false /* forceNonResizable */);
10317 final ActivityRecord topActivity = task.getTopActivity();
10318 if (topActivity != null) {
10320 // We are reshowing a task, use a starting window to hide the initial draw delay
10321 // so the transition can start earlier.
10322 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10323 true /* taskSwitch */, fromRecents);
10326 Binder.restoreCallingIdentity(origId);
10328 ActivityOptions.abort(options);
10332 * Attempts to move a task backwards in z-order (the order of activities within the task is
10335 * There are several possible results of this call:
10336 * - if the task is locked, then we will show the lock toast
10337 * - if there is a task behind the provided task, then that task is made visible and resumed as
10338 * this task is moved to the back
10339 * - otherwise, if there are no other tasks in the stack:
10340 * - if this task is in the pinned stack, then we remove the stack completely, which will
10341 * have the effect of moving the task to the top or bottom of the fullscreen stack
10342 * (depending on whether it is visible)
10343 * - otherwise, we simply return home and hide this task
10345 * @param token A reference to the activity we wish to move
10346 * @param nonRoot If false then this only works if the activity is the root
10347 * of a task; if true it will work for any activity in a task.
10348 * @return Returns true if the move completed, false if not.
10351 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10352 enforceNotIsolatedCaller("moveActivityTaskToBack");
10353 synchronized(this) {
10354 final long origId = Binder.clearCallingIdentity();
10356 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10357 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10358 if (task != null) {
10359 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10362 Binder.restoreCallingIdentity(origId);
10369 public void moveTaskBackwards(int task) {
10370 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10371 "moveTaskBackwards()");
10373 synchronized(this) {
10374 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10375 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10378 final long origId = Binder.clearCallingIdentity();
10379 moveTaskBackwardsLocked(task);
10380 Binder.restoreCallingIdentity(origId);
10384 private final void moveTaskBackwardsLocked(int task) {
10385 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10389 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10390 IActivityContainerCallback callback) throws RemoteException {
10391 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10392 synchronized (this) {
10393 if (parentActivityToken == null) {
10394 throw new IllegalArgumentException("parent token must not be null");
10396 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10400 if (callback == null) {
10401 throw new IllegalArgumentException("callback must not be null");
10403 return mStackSupervisor.createVirtualActivityContainer(r, callback);
10408 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10409 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10410 synchronized (this) {
10411 final int stackId = mStackSupervisor.getNextStackId();
10412 final ActivityStack stack =
10413 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10414 if (stack == null) {
10417 return stack.mActivityContainer;
10422 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10423 synchronized (this) {
10424 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10425 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10426 return stack.mActivityContainer.getDisplayId();
10428 return DEFAULT_DISPLAY;
10433 public int getActivityStackId(IBinder token) throws RemoteException {
10434 synchronized (this) {
10435 ActivityStack stack = ActivityRecord.getStackLocked(token);
10436 if (stack == null) {
10437 return INVALID_STACK_ID;
10439 return stack.mStackId;
10444 public void exitFreeformMode(IBinder token) throws RemoteException {
10445 synchronized (this) {
10446 long ident = Binder.clearCallingIdentity();
10448 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10450 throw new IllegalArgumentException(
10451 "exitFreeformMode: No activity record matching token=" + token);
10454 final ActivityStack stack = r.getStack();
10455 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10456 throw new IllegalStateException(
10457 "exitFreeformMode: You can only go fullscreen from freeform.");
10460 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10461 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10462 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10464 Binder.restoreCallingIdentity(ident);
10470 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10471 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10472 if (StackId.isHomeOrRecentsStack(stackId)) {
10473 throw new IllegalArgumentException(
10474 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10476 synchronized (this) {
10477 long ident = Binder.clearCallingIdentity();
10479 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10480 if (task == null) {
10481 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10485 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10486 + " to stackId=" + stackId + " toTop=" + toTop);
10487 if (stackId == DOCKED_STACK_ID) {
10488 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10489 null /* initialBounds */);
10491 task.reparent(stackId, toTop,
10492 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10494 Binder.restoreCallingIdentity(ident);
10500 public void swapDockedAndFullscreenStack() throws RemoteException {
10501 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10502 synchronized (this) {
10503 long ident = Binder.clearCallingIdentity();
10505 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10506 FULLSCREEN_WORKSPACE_STACK_ID);
10507 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10509 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10510 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10512 if (topTask == null || tasks == null || tasks.size() == 0) {
10514 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10518 // TODO: App transition
10519 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10521 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10522 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10523 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10524 final int size = tasks.size();
10525 for (int i = 0; i < size; i++) {
10526 final int id = tasks.get(i).taskId;
10527 if (id == topTask.taskId) {
10531 // Defer the resume until after all the tasks have been moved
10532 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10533 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10534 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10537 // Because we deferred the resume to avoid conflicts with stack switches while
10538 // resuming, we need to do it after all the tasks are moved.
10539 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10540 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10542 mWindowManager.executeAppTransition();
10544 Binder.restoreCallingIdentity(ident);
10550 * Moves the input task to the docked stack.
10552 * @param taskId Id of task to move.
10553 * @param createMode The mode the docked stack should be created in if it doesn't exist
10555 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10557 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10558 * @param toTop If the task and stack should be moved to the top.
10559 * @param animate Whether we should play an animation for the moving the task
10560 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10561 * docked stack. Pass {@code null} to use default bounds.
10564 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10565 Rect initialBounds) {
10566 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10567 synchronized (this) {
10568 long ident = Binder.clearCallingIdentity();
10570 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10571 if (task == null) {
10572 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10576 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10577 + " to createMode=" + createMode + " toTop=" + toTop);
10578 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10580 // Defer resuming until we move the home stack to the front below
10581 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10582 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10583 "moveTaskToDockedStack");
10585 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10589 Binder.restoreCallingIdentity(ident);
10595 * Moves the top activity in the input stackId to the pinned stack.
10597 * @param stackId Id of stack to move the top activity to pinned stack.
10598 * @param bounds Bounds to use for pinned stack.
10600 * @return True if the top activity of the input stack was successfully moved to the pinned
10604 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10605 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10606 synchronized (this) {
10607 if (!mSupportsPictureInPicture) {
10608 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10609 + "Device doesn't support picture-in-picture mode");
10612 long ident = Binder.clearCallingIdentity();
10614 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10616 Binder.restoreCallingIdentity(ident);
10622 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10623 boolean preserveWindows, boolean animate, int animationDuration) {
10624 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10625 long ident = Binder.clearCallingIdentity();
10627 synchronized (this) {
10629 if (stackId == PINNED_STACK_ID) {
10630 final PinnedActivityStack pinnedStack =
10631 mStackSupervisor.getStack(PINNED_STACK_ID);
10632 if (pinnedStack != null) {
10633 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10634 destBounds, animationDuration, false /* fromFullscreen */);
10637 throw new IllegalArgumentException("Stack: " + stackId
10638 + " doesn't support animated resize.");
10641 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10642 null /* tempTaskInsetBounds */, preserveWindows,
10643 allowResizeInDockedMode, !DEFER_RESUME);
10647 Binder.restoreCallingIdentity(ident);
10652 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10653 Rect tempDockedTaskInsetBounds,
10654 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10655 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10656 "resizeDockedStack()");
10657 long ident = Binder.clearCallingIdentity();
10659 synchronized (this) {
10660 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10661 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10665 Binder.restoreCallingIdentity(ident);
10670 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10671 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10672 "resizePinnedStack()");
10673 final long ident = Binder.clearCallingIdentity();
10675 synchronized (this) {
10676 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10679 Binder.restoreCallingIdentity(ident);
10684 * Try to place task to provided position. The final position might be different depending on
10685 * current user and stacks state. The task will be moved to target stack if it's currently in
10689 public void positionTaskInStack(int taskId, int stackId, int position) {
10690 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10691 if (StackId.isHomeOrRecentsStack(stackId)) {
10692 throw new IllegalArgumentException(
10693 "positionTaskInStack: Attempt to change the position of task "
10694 + taskId + " in/to home/recents stack");
10696 synchronized (this) {
10697 long ident = Binder.clearCallingIdentity();
10699 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10700 + taskId + " in stackId=" + stackId + " at position=" + position);
10701 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10702 if (task == null) {
10703 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10707 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10710 // TODO: Have the callers of this API call a separate reparent method if that is
10711 // what they intended to do vs. having this method also do reparenting.
10712 if (task.getStack() == stack) {
10713 // Change position in current stack.
10714 stack.positionChildAt(task, position);
10716 // Reparent to new stack.
10717 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10718 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10721 Binder.restoreCallingIdentity(ident);
10727 public List<StackInfo> getAllStackInfos() {
10728 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10729 long ident = Binder.clearCallingIdentity();
10731 synchronized (this) {
10732 return mStackSupervisor.getAllStackInfosLocked();
10735 Binder.restoreCallingIdentity(ident);
10740 public StackInfo getStackInfo(int stackId) {
10741 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10742 long ident = Binder.clearCallingIdentity();
10744 synchronized (this) {
10745 return mStackSupervisor.getStackInfoLocked(stackId);
10748 Binder.restoreCallingIdentity(ident);
10753 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10754 synchronized(this) {
10755 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10760 public void updateDeviceOwner(String packageName) {
10761 final int callingUid = Binder.getCallingUid();
10762 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10763 throw new SecurityException("updateDeviceOwner called from non-system process");
10765 synchronized (this) {
10766 mDeviceOwnerName = packageName;
10771 public void updateLockTaskPackages(int userId, String[] packages) {
10772 final int callingUid = Binder.getCallingUid();
10773 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10774 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10775 "updateLockTaskPackages()");
10777 synchronized (this) {
10778 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10779 Arrays.toString(packages));
10780 mLockTaskPackages.put(userId, packages);
10781 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10786 void startLockTaskModeLocked(TaskRecord task) {
10787 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10788 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10792 // When a task is locked, dismiss the pinned stack if it exists
10793 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10795 if (pinnedStack != null) {
10796 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10799 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10800 // is initiated by system after the pinning request was shown and locked mode is initiated
10801 // by an authorized app directly
10802 final int callingUid = Binder.getCallingUid();
10803 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10804 long ident = Binder.clearCallingIdentity();
10806 if (!isSystemInitiated) {
10807 task.mLockTaskUid = callingUid;
10808 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10809 // startLockTask() called by app and task mode is lockTaskModeDefault.
10810 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10811 StatusBarManagerInternal statusBarManager =
10812 LocalServices.getService(StatusBarManagerInternal.class);
10813 if (statusBarManager != null) {
10814 statusBarManager.showScreenPinningRequest(task.taskId);
10819 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10820 if (stack == null || task != stack.topTask()) {
10821 throw new IllegalArgumentException("Invalid task, not in foreground");
10824 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10826 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10827 ActivityManager.LOCK_TASK_MODE_PINNED :
10828 ActivityManager.LOCK_TASK_MODE_LOCKED,
10829 "startLockTask", true);
10831 Binder.restoreCallingIdentity(ident);
10836 public void startLockTaskModeById(int taskId) {
10837 synchronized (this) {
10838 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10839 if (task != null) {
10840 startLockTaskModeLocked(task);
10846 public void startLockTaskModeByToken(IBinder token) {
10847 synchronized (this) {
10848 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10852 final TaskRecord task = r.getTask();
10853 if (task != null) {
10854 startLockTaskModeLocked(task);
10860 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10861 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10862 // This makes inner call to look as if it was initiated by system.
10863 long ident = Binder.clearCallingIdentity();
10865 synchronized (this) {
10866 startLockTaskModeById(taskId);
10869 Binder.restoreCallingIdentity(ident);
10874 public void stopLockTaskMode() {
10875 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10876 if (lockTask == null) {
10877 // Our work here is done.
10881 final int callingUid = Binder.getCallingUid();
10882 final int lockTaskUid = lockTask.mLockTaskUid;
10883 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10884 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10888 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10889 // It is possible lockTaskMode was started by the system process because
10890 // android:lockTaskMode is set to a locking value in the application manifest
10891 // instead of the app calling startLockTaskMode. In this case
10892 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10893 // {@link TaskRecord.effectiveUid} instead. Also caller with
10894 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10895 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10896 && callingUid != lockTaskUid
10897 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10898 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10899 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10902 long ident = Binder.clearCallingIdentity();
10904 Log.d(TAG, "stopLockTaskMode");
10906 synchronized (this) {
10907 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10908 "stopLockTask", true);
10910 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10912 tm.showInCallScreen(false);
10915 Binder.restoreCallingIdentity(ident);
10920 * This API should be called by SystemUI only when user perform certain action to dismiss
10921 * lock task mode. We should only dismiss pinned lock task mode in this case.
10924 public void stopSystemLockTaskMode() throws RemoteException {
10925 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10926 stopLockTaskMode();
10928 mStackSupervisor.showLockTaskToast();
10933 public boolean isInLockTaskMode() {
10934 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10938 public int getLockTaskModeState() {
10939 synchronized (this) {
10940 return mStackSupervisor.getLockTaskModeState();
10945 public void showLockTaskEscapeMessage(IBinder token) {
10946 synchronized (this) {
10947 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10951 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
10956 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10957 throws RemoteException {
10958 synchronized (this) {
10959 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10961 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10965 final long origId = Binder.clearCallingIdentity();
10967 r.setDisablePreviewScreenshots(disable);
10969 Binder.restoreCallingIdentity(origId);
10974 // =========================================================
10975 // CONTENT PROVIDERS
10976 // =========================================================
10978 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10979 List<ProviderInfo> providers = null;
10981 providers = AppGlobals.getPackageManager()
10982 .queryContentProviders(app.processName, app.uid,
10983 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10984 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10986 } catch (RemoteException ex) {
10988 if (DEBUG_MU) Slog.v(TAG_MU,
10989 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10990 int userId = app.userId;
10991 if (providers != null) {
10992 int N = providers.size();
10993 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10994 for (int i=0; i<N; i++) {
10995 // TODO: keep logic in sync with installEncryptionUnawareProviders
10997 (ProviderInfo)providers.get(i);
10998 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10999 cpi.name, cpi.flags);
11000 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11001 // This is a singleton provider, but a user besides the
11002 // default user is asking to initialize a process it runs
11003 // in... well, no, it doesn't actually run in this process,
11004 // it runs in the process of the default user. Get rid of it.
11005 providers.remove(i);
11011 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11012 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11014 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11015 mProviderMap.putProviderByClass(comp, cpr);
11017 if (DEBUG_MU) Slog.v(TAG_MU,
11018 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11019 app.pubProviders.put(cpi.name, cpr);
11020 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11021 // Don't add this if it is a platform component that is marked
11022 // to run in multiple processes, because this is actually
11023 // part of the framework so doesn't make sense to track as a
11024 // separate apk in the process.
11025 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11028 notifyPackageUse(cpi.applicationInfo.packageName,
11029 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11036 * Check if the calling UID has a possible chance at accessing the provider
11037 * at the given authority and user.
11039 public String checkContentProviderAccess(String authority, int userId) {
11040 if (userId == UserHandle.USER_ALL) {
11041 mContext.enforceCallingOrSelfPermission(
11042 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11043 userId = UserHandle.getCallingUserId();
11046 ProviderInfo cpi = null;
11048 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11049 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11050 | PackageManager.MATCH_DISABLED_COMPONENTS
11051 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11052 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11054 } catch (RemoteException ignored) {
11057 return "Failed to find provider " + authority + " for user " + userId
11058 + "; expected to find a valid ContentProvider for this authority";
11061 ProcessRecord r = null;
11062 synchronized (mPidsSelfLocked) {
11063 r = mPidsSelfLocked.get(Binder.getCallingPid());
11066 return "Failed to find PID " + Binder.getCallingPid();
11069 synchronized (this) {
11070 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11075 * Check if {@link ProcessRecord} has a possible chance at accessing the
11076 * given {@link ProviderInfo}. Final permission checking is always done
11077 * in {@link ContentProvider}.
11079 private final String checkContentProviderPermissionLocked(
11080 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11081 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11082 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11083 boolean checkedGrants = false;
11085 // Looking for cross-user grants before enforcing the typical cross-users permissions
11086 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11087 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11088 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11091 checkedGrants = true;
11093 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11094 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11095 if (userId != tmpTargetUserId) {
11096 // When we actually went to determine the final targer user ID, this ended
11097 // up different than our initial check for the authority. This is because
11098 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11099 // SELF. So we need to re-check the grants again.
11100 checkedGrants = false;
11103 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11104 cpi.applicationInfo.uid, cpi.exported)
11105 == PackageManager.PERMISSION_GRANTED) {
11108 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11109 cpi.applicationInfo.uid, cpi.exported)
11110 == PackageManager.PERMISSION_GRANTED) {
11114 PathPermission[] pps = cpi.pathPermissions;
11116 int i = pps.length;
11119 PathPermission pp = pps[i];
11120 String pprperm = pp.getReadPermission();
11121 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11122 cpi.applicationInfo.uid, cpi.exported)
11123 == PackageManager.PERMISSION_GRANTED) {
11126 String ppwperm = pp.getWritePermission();
11127 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11128 cpi.applicationInfo.uid, cpi.exported)
11129 == PackageManager.PERMISSION_GRANTED) {
11134 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11138 final String suffix;
11139 if (!cpi.exported) {
11140 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11141 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11142 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11144 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11146 final String msg = "Permission Denial: opening provider " + cpi.name
11147 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11148 + ", uid=" + callingUid + ")" + suffix;
11154 * Returns if the ContentProvider has granted a uri to callingUid
11156 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11157 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11158 if (perms != null) {
11159 for (int i=perms.size()-1; i>=0; i--) {
11160 GrantUri grantUri = perms.keyAt(i);
11161 if (grantUri.sourceUserId == userId || !checkUser) {
11162 if (matchesProvider(grantUri.uri, cpi)) {
11172 * Returns true if the uri authority is one of the authorities specified in the provider.
11174 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11175 String uriAuth = uri.getAuthority();
11176 String cpiAuth = cpi.authority;
11177 if (cpiAuth.indexOf(';') == -1) {
11178 return cpiAuth.equals(uriAuth);
11180 String[] cpiAuths = cpiAuth.split(";");
11181 int length = cpiAuths.length;
11182 for (int i = 0; i < length; i++) {
11183 if (cpiAuths[i].equals(uriAuth)) return true;
11188 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11189 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11191 for (int i=0; i<r.conProviders.size(); i++) {
11192 ContentProviderConnection conn = r.conProviders.get(i);
11193 if (conn.provider == cpr) {
11194 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11195 "Adding provider requested by "
11196 + r.processName + " from process "
11197 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11198 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11200 conn.stableCount++;
11201 conn.numStableIncs++;
11203 conn.unstableCount++;
11204 conn.numUnstableIncs++;
11209 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11211 conn.stableCount = 1;
11212 conn.numStableIncs = 1;
11214 conn.unstableCount = 1;
11215 conn.numUnstableIncs = 1;
11217 cpr.connections.add(conn);
11218 r.conProviders.add(conn);
11219 startAssociationLocked(r.uid, r.processName, r.curProcState,
11220 cpr.uid, cpr.name, cpr.info.processName);
11223 cpr.addExternalProcessHandleLocked(externalProcessToken);
11227 boolean decProviderCountLocked(ContentProviderConnection conn,
11228 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11229 if (conn != null) {
11230 cpr = conn.provider;
11231 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11232 "Removing provider requested by "
11233 + conn.client.processName + " from process "
11234 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11235 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11237 conn.stableCount--;
11239 conn.unstableCount--;
11241 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11242 cpr.connections.remove(conn);
11243 conn.client.conProviders.remove(conn);
11244 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11245 // The client is more important than last activity -- note the time this
11246 // is happening, so we keep the old provider process around a bit as last
11247 // activity to avoid thrashing it.
11248 if (cpr.proc != null) {
11249 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11252 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11257 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11261 private void checkTime(long startTime, String where) {
11262 long now = SystemClock.uptimeMillis();
11263 if ((now-startTime) > 50) {
11264 // If we are taking more than 50ms, log about it.
11265 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11269 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11271 PROC_SPACE_TERM|PROC_PARENS,
11272 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11275 private final long[] mProcessStateStatsLongs = new long[1];
11277 boolean isProcessAliveLocked(ProcessRecord proc) {
11278 if (proc.procStatFile == null) {
11279 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11281 mProcessStateStatsLongs[0] = 0;
11282 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11283 mProcessStateStatsLongs, null)) {
11284 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11287 final long state = mProcessStateStatsLongs[0];
11288 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11290 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11293 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11294 String name, IBinder token, boolean stable, int userId) {
11295 ContentProviderRecord cpr;
11296 ContentProviderConnection conn = null;
11297 ProviderInfo cpi = null;
11299 synchronized(this) {
11300 long startTime = SystemClock.uptimeMillis();
11302 ProcessRecord r = null;
11303 if (caller != null) {
11304 r = getRecordForAppLocked(caller);
11306 throw new SecurityException(
11307 "Unable to find app for caller " + caller
11308 + " (pid=" + Binder.getCallingPid()
11309 + ") when getting content provider " + name);
11313 boolean checkCrossUser = true;
11315 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11317 // First check if this content provider has been published...
11318 cpr = mProviderMap.getProviderByName(name, userId);
11319 // If that didn't work, check if it exists for user 0 and then
11320 // verify that it's a singleton provider before using it.
11321 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11322 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11325 if (isSingleton(cpi.processName, cpi.applicationInfo,
11326 cpi.name, cpi.flags)
11327 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11328 userId = UserHandle.USER_SYSTEM;
11329 checkCrossUser = false;
11337 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11338 if (providerRunning) {
11341 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11342 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11344 throw new SecurityException(msg);
11346 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11348 if (r != null && cpr.canRunHere(r)) {
11349 // This provider has been published or is in the process
11350 // of being published... but it is also allowed to run
11351 // in the caller's process, so don't make a connection
11352 // and just let the caller instantiate its own instance.
11353 ContentProviderHolder holder = cpr.newHolder(null);
11354 // don't give caller the provider object, it needs
11355 // to make its own.
11356 holder.provider = null;
11359 // Don't expose providers between normal apps and instant apps
11361 if (AppGlobals.getPackageManager()
11362 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11365 } catch (RemoteException e) {
11368 final long origId = Binder.clearCallingIdentity();
11370 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11372 // In this case the provider instance already exists, so we can
11373 // return it right away.
11374 conn = incProviderCountLocked(r, cpr, token, stable);
11375 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11376 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11377 // If this is a perceptible app accessing the provider,
11378 // make sure to count it as being accessed and thus
11379 // back up on the LRU list. This is good because
11380 // content providers are often expensive to start.
11381 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11382 updateLruProcessLocked(cpr.proc, false, null);
11383 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11387 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11388 final int verifiedAdj = cpr.proc.verifiedAdj;
11389 boolean success = updateOomAdjLocked(cpr.proc, true);
11390 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11391 // if the process has been successfully adjusted. So to reduce races with
11392 // it, we will check whether the process still exists. Note that this doesn't
11393 // completely get rid of races with LMK killing the process, but should make
11394 // them much smaller.
11395 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11398 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11399 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11400 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11401 // NOTE: there is still a race here where a signal could be
11402 // pending on the process even though we managed to update its
11403 // adj level. Not sure what to do about this, but at least
11404 // the race is now smaller.
11406 // Uh oh... it looks like the provider's process
11407 // has been killed on us. We need to wait for a new
11408 // process to be started, and make sure its death
11409 // doesn't kill our process.
11410 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11411 + " is crashing; detaching " + r);
11412 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11413 checkTime(startTime, "getContentProviderImpl: before appDied");
11414 appDiedLocked(cpr.proc);
11415 checkTime(startTime, "getContentProviderImpl: after appDied");
11417 // This wasn't the last ref our process had on
11418 // the provider... we have now been killed, bail.
11421 providerRunning = false;
11424 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11427 Binder.restoreCallingIdentity(origId);
11430 if (!providerRunning) {
11432 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11433 cpi = AppGlobals.getPackageManager().
11434 resolveContentProvider(name,
11435 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11436 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11437 } catch (RemoteException ex) {
11442 // If the provider is a singleton AND
11443 // (it's a call within the same user || the provider is a
11445 // Then allow connecting to the singleton provider
11446 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11447 cpi.name, cpi.flags)
11448 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11450 userId = UserHandle.USER_SYSTEM;
11452 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11453 checkTime(startTime, "getContentProviderImpl: got app info for user");
11456 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11457 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11459 throw new SecurityException(msg);
11461 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11463 if (!mProcessesReady
11464 && !cpi.processName.equals("system")) {
11465 // If this content provider does not run in the system
11466 // process, and the system is not yet ready to run other
11467 // processes, then fail fast instead of hanging.
11468 throw new IllegalArgumentException(
11469 "Attempt to launch content provider before system ready");
11472 // Make sure that the user who owns this provider is running. If not,
11473 // we don't want to allow it to run.
11474 if (!mUserController.isUserRunningLocked(userId, 0)) {
11475 Slog.w(TAG, "Unable to launch app "
11476 + cpi.applicationInfo.packageName + "/"
11477 + cpi.applicationInfo.uid + " for provider "
11478 + name + ": user " + userId + " is stopped");
11482 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11483 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11484 cpr = mProviderMap.getProviderByClass(comp, userId);
11485 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11486 final boolean firstClass = cpr == null;
11488 final long ident = Binder.clearCallingIdentity();
11490 // If permissions need a review before any of the app components can run,
11491 // we return no provider and launch a review activity if the calling app
11492 // is in the foreground.
11493 if (mPermissionReviewRequired) {
11494 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11500 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11501 ApplicationInfo ai =
11502 AppGlobals.getPackageManager().
11503 getApplicationInfo(
11504 cpi.applicationInfo.packageName,
11505 STOCK_PM_FLAGS, userId);
11506 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11508 Slog.w(TAG, "No package info for content provider "
11512 ai = getAppInfoForUser(ai, userId);
11513 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11514 } catch (RemoteException ex) {
11515 // pm is in same process, this will never happen.
11517 Binder.restoreCallingIdentity(ident);
11521 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11523 if (r != null && cpr.canRunHere(r)) {
11524 // If this is a multiprocess provider, then just return its
11525 // info and allow the caller to instantiate it. Only do
11526 // this if the provider is the same user as the caller's
11527 // process, or can run as root (so can be in any process).
11528 return cpr.newHolder(null);
11531 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11532 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11533 + cpr.info.name + " callers=" + Debug.getCallers(6));
11535 // This is single process, and our app is now connecting to it.
11536 // See if we are already in the process of launching this
11538 final int N = mLaunchingProviders.size();
11540 for (i = 0; i < N; i++) {
11541 if (mLaunchingProviders.get(i) == cpr) {
11546 // If the provider is not already being launched, then get it
11549 final long origId = Binder.clearCallingIdentity();
11552 // Content provider is now in use, its package can't be stopped.
11554 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11555 AppGlobals.getPackageManager().setPackageStoppedState(
11556 cpr.appInfo.packageName, false, userId);
11557 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11558 } catch (RemoteException e) {
11559 } catch (IllegalArgumentException e) {
11560 Slog.w(TAG, "Failed trying to unstop package "
11561 + cpr.appInfo.packageName + ": " + e);
11564 // Use existing process if already started
11565 checkTime(startTime, "getContentProviderImpl: looking for process record");
11566 ProcessRecord proc = getProcessRecordLocked(
11567 cpi.processName, cpr.appInfo.uid, false);
11568 if (proc != null && proc.thread != null && !proc.killed) {
11569 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11570 "Installing in existing process " + proc);
11571 if (!proc.pubProviders.containsKey(cpi.name)) {
11572 checkTime(startTime, "getContentProviderImpl: scheduling install");
11573 proc.pubProviders.put(cpi.name, cpr);
11575 proc.thread.scheduleInstallProvider(cpi);
11576 } catch (RemoteException e) {
11580 checkTime(startTime, "getContentProviderImpl: before start process");
11581 proc = startProcessLocked(cpi.processName,
11582 cpr.appInfo, false, 0, "content provider",
11583 new ComponentName(cpi.applicationInfo.packageName,
11584 cpi.name), false, false, false);
11585 checkTime(startTime, "getContentProviderImpl: after start process");
11586 if (proc == null) {
11587 Slog.w(TAG, "Unable to launch app "
11588 + cpi.applicationInfo.packageName + "/"
11589 + cpi.applicationInfo.uid + " for provider "
11590 + name + ": process is bad");
11594 cpr.launchingApp = proc;
11595 mLaunchingProviders.add(cpr);
11597 Binder.restoreCallingIdentity(origId);
11601 checkTime(startTime, "getContentProviderImpl: updating data structures");
11603 // Make sure the provider is published (the same provider class
11604 // may be published under multiple names).
11606 mProviderMap.putProviderByClass(comp, cpr);
11609 mProviderMap.putProviderByName(name, cpr);
11610 conn = incProviderCountLocked(r, cpr, token, stable);
11611 if (conn != null) {
11612 conn.waiting = true;
11615 checkTime(startTime, "getContentProviderImpl: done!");
11617 grantEphemeralAccessLocked(userId, null /*intent*/,
11618 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11621 // Wait for the provider to be published...
11622 synchronized (cpr) {
11623 while (cpr.provider == null) {
11624 if (cpr.launchingApp == null) {
11625 Slog.w(TAG, "Unable to launch app "
11626 + cpi.applicationInfo.packageName + "/"
11627 + cpi.applicationInfo.uid + " for provider "
11628 + name + ": launching app became null");
11629 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11630 UserHandle.getUserId(cpi.applicationInfo.uid),
11631 cpi.applicationInfo.packageName,
11632 cpi.applicationInfo.uid, name);
11636 if (DEBUG_MU) Slog.v(TAG_MU,
11637 "Waiting to start provider " + cpr
11638 + " launchingApp=" + cpr.launchingApp);
11639 if (conn != null) {
11640 conn.waiting = true;
11643 } catch (InterruptedException ex) {
11645 if (conn != null) {
11646 conn.waiting = false;
11651 return cpr != null ? cpr.newHolder(conn) : null;
11654 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11655 ProcessRecord r, final int userId) {
11656 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11657 cpi.packageName, userId)) {
11659 final boolean callerForeground = r == null || r.setSchedGroup
11660 != ProcessList.SCHED_GROUP_BACKGROUND;
11662 // Show a permission review UI only for starting from a foreground app
11663 if (!callerForeground) {
11664 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11665 + cpi.packageName + " requires a permissions review");
11669 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11670 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11671 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11672 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11674 if (DEBUG_PERMISSIONS_REVIEW) {
11675 Slog.i(TAG, "u" + userId + " Launching permission review "
11676 + "for package " + cpi.packageName);
11679 final UserHandle userHandle = new UserHandle(userId);
11680 mHandler.post(new Runnable() {
11682 public void run() {
11683 mContext.startActivityAsUser(intent, userHandle);
11693 PackageManagerInternal getPackageManagerInternalLocked() {
11694 if (mPackageManagerInt == null) {
11695 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11697 return mPackageManagerInt;
11701 public final ContentProviderHolder getContentProvider(
11702 IApplicationThread caller, String name, int userId, boolean stable) {
11703 enforceNotIsolatedCaller("getContentProvider");
11704 if (caller == null) {
11705 String msg = "null IApplicationThread when getting content provider "
11708 throw new SecurityException(msg);
11710 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11711 // with cross-user grant.
11712 return getContentProviderImpl(caller, name, null, stable, userId);
11715 public ContentProviderHolder getContentProviderExternal(
11716 String name, int userId, IBinder token) {
11717 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11718 "Do not have permission in call getContentProviderExternal()");
11719 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11720 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11721 return getContentProviderExternalUnchecked(name, token, userId);
11724 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11725 IBinder token, int userId) {
11726 return getContentProviderImpl(null, name, token, true, userId);
11730 * Drop a content provider from a ProcessRecord's bookkeeping
11732 public void removeContentProvider(IBinder connection, boolean stable) {
11733 enforceNotIsolatedCaller("removeContentProvider");
11734 long ident = Binder.clearCallingIdentity();
11736 synchronized (this) {
11737 ContentProviderConnection conn;
11739 conn = (ContentProviderConnection)connection;
11740 } catch (ClassCastException e) {
11741 String msg ="removeContentProvider: " + connection
11742 + " not a ContentProviderConnection";
11744 throw new IllegalArgumentException(msg);
11746 if (conn == null) {
11747 throw new NullPointerException("connection is null");
11749 if (decProviderCountLocked(conn, null, null, stable)) {
11750 updateOomAdjLocked();
11754 Binder.restoreCallingIdentity(ident);
11758 public void removeContentProviderExternal(String name, IBinder token) {
11759 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11760 "Do not have permission in call removeContentProviderExternal()");
11761 int userId = UserHandle.getCallingUserId();
11762 long ident = Binder.clearCallingIdentity();
11764 removeContentProviderExternalUnchecked(name, token, userId);
11766 Binder.restoreCallingIdentity(ident);
11770 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11771 synchronized (this) {
11772 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11774 //remove from mProvidersByClass
11775 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11779 //update content provider record entry info
11780 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11781 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11782 if (localCpr.hasExternalProcessHandles()) {
11783 if (localCpr.removeExternalProcessHandleLocked(token)) {
11784 updateOomAdjLocked();
11786 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11787 + " with no external reference for token: "
11791 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11792 + " with no external references.");
11797 public final void publishContentProviders(IApplicationThread caller,
11798 List<ContentProviderHolder> providers) {
11799 if (providers == null) {
11803 enforceNotIsolatedCaller("publishContentProviders");
11804 synchronized (this) {
11805 final ProcessRecord r = getRecordForAppLocked(caller);
11806 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11808 throw new SecurityException(
11809 "Unable to find app for caller " + caller
11810 + " (pid=" + Binder.getCallingPid()
11811 + ") when publishing content providers");
11814 final long origId = Binder.clearCallingIdentity();
11816 final int N = providers.size();
11817 for (int i = 0; i < N; i++) {
11818 ContentProviderHolder src = providers.get(i);
11819 if (src == null || src.info == null || src.provider == null) {
11822 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11823 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11825 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11826 mProviderMap.putProviderByClass(comp, dst);
11827 String names[] = dst.info.authority.split(";");
11828 for (int j = 0; j < names.length; j++) {
11829 mProviderMap.putProviderByName(names[j], dst);
11832 int launchingCount = mLaunchingProviders.size();
11834 boolean wasInLaunchingProviders = false;
11835 for (j = 0; j < launchingCount; j++) {
11836 if (mLaunchingProviders.get(j) == dst) {
11837 mLaunchingProviders.remove(j);
11838 wasInLaunchingProviders = true;
11843 if (wasInLaunchingProviders) {
11844 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11846 synchronized (dst) {
11847 dst.provider = src.provider;
11851 updateOomAdjLocked(r, true);
11852 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11853 src.info.authority);
11857 Binder.restoreCallingIdentity(origId);
11861 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11862 ContentProviderConnection conn;
11864 conn = (ContentProviderConnection)connection;
11865 } catch (ClassCastException e) {
11866 String msg ="refContentProvider: " + connection
11867 + " not a ContentProviderConnection";
11869 throw new IllegalArgumentException(msg);
11871 if (conn == null) {
11872 throw new NullPointerException("connection is null");
11875 synchronized (this) {
11877 conn.numStableIncs += stable;
11879 stable = conn.stableCount + stable;
11881 throw new IllegalStateException("stableCount < 0: " + stable);
11884 if (unstable > 0) {
11885 conn.numUnstableIncs += unstable;
11887 unstable = conn.unstableCount + unstable;
11888 if (unstable < 0) {
11889 throw new IllegalStateException("unstableCount < 0: " + unstable);
11892 if ((stable+unstable) <= 0) {
11893 throw new IllegalStateException("ref counts can't go to zero here: stable="
11894 + stable + " unstable=" + unstable);
11896 conn.stableCount = stable;
11897 conn.unstableCount = unstable;
11902 public void unstableProviderDied(IBinder connection) {
11903 ContentProviderConnection conn;
11905 conn = (ContentProviderConnection)connection;
11906 } catch (ClassCastException e) {
11907 String msg ="refContentProvider: " + connection
11908 + " not a ContentProviderConnection";
11910 throw new IllegalArgumentException(msg);
11912 if (conn == null) {
11913 throw new NullPointerException("connection is null");
11916 // Safely retrieve the content provider associated with the connection.
11917 IContentProvider provider;
11918 synchronized (this) {
11919 provider = conn.provider.provider;
11922 if (provider == null) {
11923 // Um, yeah, we're way ahead of you.
11927 // Make sure the caller is being honest with us.
11928 if (provider.asBinder().pingBinder()) {
11929 // Er, no, still looks good to us.
11930 synchronized (this) {
11931 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11932 + " says " + conn + " died, but we don't agree");
11937 // Well look at that! It's dead!
11938 synchronized (this) {
11939 if (conn.provider.provider != provider) {
11940 // But something changed... good enough.
11944 ProcessRecord proc = conn.provider.proc;
11945 if (proc == null || proc.thread == null) {
11946 // Seems like the process is already cleaned up.
11950 // As far as we're concerned, this is just like receiving a
11951 // death notification... just a bit prematurely.
11952 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11953 + ") early provider death");
11954 final long ident = Binder.clearCallingIdentity();
11956 appDiedLocked(proc);
11958 Binder.restoreCallingIdentity(ident);
11964 public void appNotRespondingViaProvider(IBinder connection) {
11965 enforceCallingPermission(
11966 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11968 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11969 if (conn == null) {
11970 Slog.w(TAG, "ContentProviderConnection is null");
11974 final ProcessRecord host = conn.provider.proc;
11975 if (host == null) {
11976 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11980 mHandler.post(new Runnable() {
11982 public void run() {
11983 mAppErrors.appNotResponding(host, null, null, false,
11984 "ContentProvider not responding");
11989 public final void installSystemProviders() {
11990 List<ProviderInfo> providers;
11991 synchronized (this) {
11992 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
11993 providers = generateApplicationProvidersLocked(app);
11994 if (providers != null) {
11995 for (int i=providers.size()-1; i>=0; i--) {
11996 ProviderInfo pi = (ProviderInfo)providers.get(i);
11997 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11998 Slog.w(TAG, "Not installing system proc provider " + pi.name
11999 + ": not system .apk");
12000 providers.remove(i);
12005 if (providers != null) {
12006 mSystemThread.installSystemProviders(providers);
12009 mConstants.start(mContext.getContentResolver());
12010 mCoreSettingsObserver = new CoreSettingsObserver(this);
12011 mFontScaleSettingObserver = new FontScaleSettingObserver();
12013 // Now that the settings provider is published we can consider sending
12014 // in a rescue party.
12015 RescueParty.onSettingsProviderPublished(mContext);
12017 //mUsageStatsService.monitorPackages();
12020 private void startPersistentApps(int matchFlags) {
12021 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12023 synchronized (this) {
12025 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12026 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12027 for (ApplicationInfo app : apps) {
12028 if (!"android".equals(app.packageName)) {
12029 addAppLocked(app, null, false, null /* ABI override */);
12032 } catch (RemoteException ex) {
12038 * When a user is unlocked, we need to install encryption-unaware providers
12039 * belonging to any running apps.
12041 private void installEncryptionUnawareProviders(int userId) {
12042 // We're only interested in providers that are encryption unaware, and
12043 // we don't care about uninstalled apps, since there's no way they're
12044 // running at this point.
12045 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12047 synchronized (this) {
12048 final int NP = mProcessNames.getMap().size();
12049 for (int ip = 0; ip < NP; ip++) {
12050 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12051 final int NA = apps.size();
12052 for (int ia = 0; ia < NA; ia++) {
12053 final ProcessRecord app = apps.valueAt(ia);
12054 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12056 final int NG = app.pkgList.size();
12057 for (int ig = 0; ig < NG; ig++) {
12059 final String pkgName = app.pkgList.keyAt(ig);
12060 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12061 .getPackageInfo(pkgName, matchFlags, userId);
12062 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12063 for (ProviderInfo pi : pkgInfo.providers) {
12064 // TODO: keep in sync with generateApplicationProvidersLocked
12065 final boolean processMatch = Objects.equals(pi.processName,
12066 app.processName) || pi.multiprocess;
12067 final boolean userMatch = isSingleton(pi.processName,
12068 pi.applicationInfo, pi.name, pi.flags)
12069 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12070 if (processMatch && userMatch) {
12071 Log.v(TAG, "Installing " + pi);
12072 app.thread.scheduleInstallProvider(pi);
12074 Log.v(TAG, "Skipping " + pi);
12078 } catch (RemoteException ignored) {
12087 * Allows apps to retrieve the MIME type of a URI.
12088 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12089 * users, then it does not need permission to access the ContentProvider.
12090 * Either, it needs cross-user uri grants.
12092 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12094 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12095 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12097 public String getProviderMimeType(Uri uri, int userId) {
12098 enforceNotIsolatedCaller("getProviderMimeType");
12099 final String name = uri.getAuthority();
12100 int callingUid = Binder.getCallingUid();
12101 int callingPid = Binder.getCallingPid();
12103 boolean clearedIdentity = false;
12104 synchronized (this) {
12105 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12107 if (canClearIdentity(callingPid, callingUid, userId)) {
12108 clearedIdentity = true;
12109 ident = Binder.clearCallingIdentity();
12111 ContentProviderHolder holder = null;
12113 holder = getContentProviderExternalUnchecked(name, null, userId);
12114 if (holder != null) {
12115 return holder.provider.getType(uri);
12117 } catch (RemoteException e) {
12118 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12120 } catch (Exception e) {
12121 Log.w(TAG, "Exception while determining type of " + uri, e);
12124 // We need to clear the identity to call removeContentProviderExternalUnchecked
12125 if (!clearedIdentity) {
12126 ident = Binder.clearCallingIdentity();
12129 if (holder != null) {
12130 removeContentProviderExternalUnchecked(name, null, userId);
12133 Binder.restoreCallingIdentity(ident);
12140 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12141 if (UserHandle.getUserId(callingUid) == userId) {
12144 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12145 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12146 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12147 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12153 // =========================================================
12154 // GLOBAL MANAGEMENT
12155 // =========================================================
12157 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12158 boolean isolated, int isolatedUid) {
12159 String proc = customProcess != null ? customProcess : info.processName;
12160 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12161 final int userId = UserHandle.getUserId(info.uid);
12162 int uid = info.uid;
12164 if (isolatedUid == 0) {
12165 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12167 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12168 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12169 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12171 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12172 mNextIsolatedProcessUid++;
12173 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12174 // No process for this uid, use it.
12178 if (stepsLeft <= 0) {
12183 // Special case for startIsolatedProcess (internal only), where
12184 // the uid of the isolated process is specified by the caller.
12187 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12189 // Register the isolated UID with this application so BatteryStats knows to
12190 // attribute resource usage to the application.
12192 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12193 // about the process state of the isolated UID *before* it is registered with the
12194 // owning application.
12195 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12197 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12198 if (!mBooted && !mBooting
12199 && userId == UserHandle.USER_SYSTEM
12200 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12201 r.persistent = true;
12202 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12204 addProcessNameLocked(r);
12208 private boolean uidOnBackgroundWhitelist(final int uid) {
12209 final int appId = UserHandle.getAppId(uid);
12210 final int[] whitelist = mBackgroundAppIdWhitelist;
12211 final int N = whitelist.length;
12212 for (int i = 0; i < N; i++) {
12213 if (appId == whitelist[i]) {
12221 public void backgroundWhitelistUid(final int uid) {
12222 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12223 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12226 if (DEBUG_BACKGROUND_CHECK) {
12227 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12229 synchronized (this) {
12230 final int N = mBackgroundAppIdWhitelist.length;
12231 int[] newList = new int[N+1];
12232 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12233 newList[N] = UserHandle.getAppId(uid);
12234 mBackgroundAppIdWhitelist = newList;
12238 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12239 String abiOverride) {
12242 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12249 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12250 updateLruProcessLocked(app, false, null);
12251 updateOomAdjLocked();
12254 // This package really, really can not be stopped.
12256 AppGlobals.getPackageManager().setPackageStoppedState(
12257 info.packageName, false, UserHandle.getUserId(app.uid));
12258 } catch (RemoteException e) {
12259 } catch (IllegalArgumentException e) {
12260 Slog.w(TAG, "Failed trying to unstop package "
12261 + info.packageName + ": " + e);
12264 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12265 app.persistent = true;
12266 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12268 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12269 mPersistentStartingProcesses.add(app);
12270 startProcessLocked(app, "added application",
12271 customProcess != null ? customProcess : app.processName, abiOverride,
12272 null /* entryPoint */, null /* entryPointArgs */);
12278 public void unhandledBack() {
12279 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12280 "unhandledBack()");
12282 synchronized(this) {
12283 final long origId = Binder.clearCallingIdentity();
12285 getFocusedStack().unhandledBackLocked();
12287 Binder.restoreCallingIdentity(origId);
12292 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12293 enforceNotIsolatedCaller("openContentUri");
12294 final int userId = UserHandle.getCallingUserId();
12295 final Uri uri = Uri.parse(uriString);
12296 String name = uri.getAuthority();
12297 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12298 ParcelFileDescriptor pfd = null;
12300 // We record the binder invoker's uid in thread-local storage before
12301 // going to the content provider to open the file. Later, in the code
12302 // that handles all permissions checks, we look for this uid and use
12303 // that rather than the Activity Manager's own uid. The effect is that
12304 // we do the check against the caller's permissions even though it looks
12305 // to the content provider like the Activity Manager itself is making
12307 Binder token = new Binder();
12308 sCallerIdentity.set(new Identity(
12309 token, Binder.getCallingPid(), Binder.getCallingUid()));
12311 pfd = cph.provider.openFile(null, uri, "r", null, token);
12312 } catch (FileNotFoundException e) {
12313 // do nothing; pfd will be returned null
12315 // Ensure that whatever happens, we clean up the identity state
12316 sCallerIdentity.remove();
12317 // Ensure we're done with the provider.
12318 removeContentProviderExternalUnchecked(name, null, userId);
12321 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12326 // Actually is sleeping or shutting down or whatever else in the future
12327 // is an inactive state.
12328 boolean isSleepingOrShuttingDownLocked() {
12329 return isSleepingLocked() || mShuttingDown;
12332 boolean isShuttingDownLocked() {
12333 return mShuttingDown;
12336 boolean isSleepingLocked() {
12340 void onWakefulnessChanged(int wakefulness) {
12341 synchronized(this) {
12342 mWakefulness = wakefulness;
12343 updateSleepIfNeededLocked();
12347 void finishRunningVoiceLocked() {
12348 if (mRunningVoice != null) {
12349 mRunningVoice = null;
12350 mVoiceWakeLock.release();
12351 updateSleepIfNeededLocked();
12355 void startTimeTrackingFocusedActivityLocked() {
12356 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12357 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12358 mCurAppTimeTracker.start(resumedActivity.packageName);
12362 void updateSleepIfNeededLocked() {
12363 final boolean shouldSleep = shouldSleepLocked();
12364 if (mSleeping && !shouldSleep) {
12366 startTimeTrackingFocusedActivityLocked();
12367 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12368 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12369 sendNotifyVrManagerOfSleepState(false);
12370 updateOomAdjLocked();
12371 } else if (!mSleeping && shouldSleep) {
12373 if (mCurAppTimeTracker != null) {
12374 mCurAppTimeTracker.stop();
12376 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12377 mStackSupervisor.goingToSleepLocked();
12378 sendNotifyVrManagerOfSleepState(true);
12379 updateOomAdjLocked();
12381 // Initialize the wake times of all processes.
12382 checkExcessivePowerUsageLocked(false);
12383 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12384 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12385 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12388 // Also update state in a special way for running foreground services UI.
12389 switch (mWakefulness) {
12390 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12391 case PowerManagerInternal.WAKEFULNESS_DREAMING:
12392 case PowerManagerInternal.WAKEFULNESS_DOZING:
12393 mServices.updateScreenStateLocked(false);
12395 case PowerManagerInternal.WAKEFULNESS_AWAKE:
12397 mServices.updateScreenStateLocked(true);
12402 private boolean shouldSleepLocked() {
12403 // Resume applications while running a voice interactor.
12404 if (mRunningVoice != null) {
12408 // TODO: Transform the lock screen state into a sleep token instead.
12409 switch (mWakefulness) {
12410 case PowerManagerInternal.WAKEFULNESS_AWAKE:
12411 case PowerManagerInternal.WAKEFULNESS_DREAMING:
12412 case PowerManagerInternal.WAKEFULNESS_DOZING:
12413 // Pause applications whenever the lock screen is shown or any sleep
12414 // tokens have been acquired.
12415 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12416 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12418 // If we're asleep then pause applications unconditionally.
12423 /** Pokes the task persister. */
12424 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12425 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12429 * Notifies all listeners when the pinned stack animation starts.
12432 public void notifyPinnedStackAnimationStarted() {
12433 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12437 * Notifies all listeners when the pinned stack animation ends.
12440 public void notifyPinnedStackAnimationEnded() {
12441 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12445 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12446 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12450 public boolean shutdown(int timeout) {
12451 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12452 != PackageManager.PERMISSION_GRANTED) {
12453 throw new SecurityException("Requires permission "
12454 + android.Manifest.permission.SHUTDOWN);
12457 boolean timedout = false;
12459 synchronized(this) {
12460 mShuttingDown = true;
12461 updateEventDispatchingLocked();
12462 timedout = mStackSupervisor.shutdownLocked(timeout);
12465 mAppOpsService.shutdown();
12466 if (mUsageStatsService != null) {
12467 mUsageStatsService.prepareShutdown();
12469 mBatteryStatsService.shutdown();
12470 synchronized (this) {
12471 mProcessStats.shutdownLocked();
12472 notifyTaskPersisterLocked(null, true);
12478 public final void activitySlept(IBinder token) {
12479 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12481 final long origId = Binder.clearCallingIdentity();
12483 synchronized (this) {
12484 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12486 mStackSupervisor.activitySleptLocked(r);
12490 Binder.restoreCallingIdentity(origId);
12493 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12494 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12495 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12496 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12497 boolean wasRunningVoice = mRunningVoice != null;
12498 mRunningVoice = session;
12499 if (!wasRunningVoice) {
12500 mVoiceWakeLock.acquire();
12501 updateSleepIfNeededLocked();
12506 private void updateEventDispatchingLocked() {
12507 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12511 public void setLockScreenShown(boolean showing) {
12512 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12513 != PackageManager.PERMISSION_GRANTED) {
12514 throw new SecurityException("Requires permission "
12515 + android.Manifest.permission.DEVICE_POWER);
12518 synchronized(this) {
12519 long ident = Binder.clearCallingIdentity();
12521 mKeyguardController.setKeyguardShown(showing);
12523 Binder.restoreCallingIdentity(ident);
12529 public void notifyLockedProfile(@UserIdInt int userId) {
12531 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12532 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12534 } catch (RemoteException ex) {
12535 throw new SecurityException("Fail to check is caller a privileged app", ex);
12538 synchronized (this) {
12539 final long ident = Binder.clearCallingIdentity();
12541 if (mUserController.shouldConfirmCredentials(userId)) {
12542 if (mKeyguardController.isKeyguardLocked()) {
12543 // Showing launcher to avoid user entering credential twice.
12544 final int currentUserId = mUserController.getCurrentUserIdLocked();
12545 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12547 mStackSupervisor.lockAllProfileTasks(userId);
12550 Binder.restoreCallingIdentity(ident);
12556 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12557 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12558 synchronized (this) {
12559 final long ident = Binder.clearCallingIdentity();
12561 mActivityStarter.startConfirmCredentialIntent(intent, options);
12563 Binder.restoreCallingIdentity(ident);
12569 public void stopAppSwitches() {
12570 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12571 != PackageManager.PERMISSION_GRANTED) {
12572 throw new SecurityException("viewquires permission "
12573 + android.Manifest.permission.STOP_APP_SWITCHES);
12576 synchronized(this) {
12577 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12578 + APP_SWITCH_DELAY_TIME;
12579 mDidAppSwitch = false;
12580 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12581 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12582 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12586 public void resumeAppSwitches() {
12587 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12588 != PackageManager.PERMISSION_GRANTED) {
12589 throw new SecurityException("Requires permission "
12590 + android.Manifest.permission.STOP_APP_SWITCHES);
12593 synchronized(this) {
12594 // Note that we don't execute any pending app switches... we will
12595 // let those wait until either the timeout, or the next start
12596 // activity request.
12597 mAppSwitchesAllowedTime = 0;
12601 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12602 int callingPid, int callingUid, String name) {
12603 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12607 int perm = checkComponentPermission(
12608 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12609 sourceUid, -1, true);
12610 if (perm == PackageManager.PERMISSION_GRANTED) {
12614 // If the actual IPC caller is different from the logical source, then
12615 // also see if they are allowed to control app switches.
12616 if (callingUid != -1 && callingUid != sourceUid) {
12617 perm = checkComponentPermission(
12618 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12619 callingUid, -1, true);
12620 if (perm == PackageManager.PERMISSION_GRANTED) {
12625 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12629 public void setDebugApp(String packageName, boolean waitForDebugger,
12630 boolean persistent) {
12631 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12634 long ident = Binder.clearCallingIdentity();
12636 // Note that this is not really thread safe if there are multiple
12637 // callers into it at the same time, but that's not a situation we
12640 final ContentResolver resolver = mContext.getContentResolver();
12641 Settings.Global.putString(
12642 resolver, Settings.Global.DEBUG_APP,
12644 Settings.Global.putInt(
12645 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12646 waitForDebugger ? 1 : 0);
12649 synchronized (this) {
12651 mOrigDebugApp = mDebugApp;
12652 mOrigWaitForDebugger = mWaitForDebugger;
12654 mDebugApp = packageName;
12655 mWaitForDebugger = waitForDebugger;
12656 mDebugTransient = !persistent;
12657 if (packageName != null) {
12658 forceStopPackageLocked(packageName, -1, false, false, true, true,
12659 false, UserHandle.USER_ALL, "set debug app");
12663 Binder.restoreCallingIdentity(ident);
12667 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12668 synchronized (this) {
12669 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12670 if (!isDebuggable) {
12671 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12672 throw new SecurityException("Process not debuggable: " + app.packageName);
12676 mTrackAllocationApp = processName;
12680 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12681 synchronized (this) {
12682 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12683 if (!isDebuggable) {
12684 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12685 throw new SecurityException("Process not debuggable: " + app.packageName);
12688 mProfileApp = processName;
12689 mProfileFile = profilerInfo.profileFile;
12690 if (mProfileFd != null) {
12692 mProfileFd.close();
12693 } catch (IOException e) {
12697 mProfileFd = profilerInfo.profileFd;
12698 mSamplingInterval = profilerInfo.samplingInterval;
12699 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12700 mStreamingOutput = profilerInfo.streamingOutput;
12705 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12706 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12707 if (!isDebuggable) {
12708 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12709 throw new SecurityException("Process not debuggable: " + app.packageName);
12712 mNativeDebuggingApp = processName;
12716 public void setAlwaysFinish(boolean enabled) {
12717 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12718 "setAlwaysFinish()");
12720 long ident = Binder.clearCallingIdentity();
12722 Settings.Global.putInt(
12723 mContext.getContentResolver(),
12724 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12726 synchronized (this) {
12727 mAlwaysFinishActivities = enabled;
12730 Binder.restoreCallingIdentity(ident);
12735 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12736 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12737 "setActivityController()");
12738 synchronized (this) {
12739 mController = controller;
12740 mControllerIsAMonkey = imAMonkey;
12741 Watchdog.getInstance().setActivityController(controller);
12746 public void setUserIsMonkey(boolean userIsMonkey) {
12747 synchronized (this) {
12748 synchronized (mPidsSelfLocked) {
12749 final int callingPid = Binder.getCallingPid();
12750 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12751 if (proc == null) {
12752 throw new SecurityException("Unknown process: " + callingPid);
12754 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12755 throw new SecurityException("Only an instrumentation process "
12756 + "with a UiAutomation can call setUserIsMonkey");
12759 mUserIsMonkey = userIsMonkey;
12764 public boolean isUserAMonkey() {
12765 synchronized (this) {
12766 // If there is a controller also implies the user is a monkey.
12767 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12772 * @deprecated This method is only used by a few internal components and it will soon be
12773 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12774 * No new code should be calling it.
12778 public void requestBugReport(int bugreportType) {
12779 String extraOptions = null;
12780 switch (bugreportType) {
12781 case ActivityManager.BUGREPORT_OPTION_FULL:
12782 // Default options.
12784 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12785 extraOptions = "bugreportplus";
12787 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12788 extraOptions = "bugreportremote";
12790 case ActivityManager.BUGREPORT_OPTION_WEAR:
12791 extraOptions = "bugreportwear";
12793 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12794 extraOptions = "bugreporttelephony";
12797 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12800 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12801 if (extraOptions != null) {
12802 SystemProperties.set("dumpstate.options", extraOptions);
12804 SystemProperties.set("ctl.start", "bugreport");
12808 * @deprecated This method is only used by a few internal components and it will soon be
12809 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12810 * No new code should be calling it.
12814 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12816 if (!TextUtils.isEmpty(shareTitle)) {
12817 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12818 String errorStr = "shareTitle should be less than " +
12819 MAX_BUGREPORT_TITLE_SIZE + " characters";
12820 throw new IllegalArgumentException(errorStr);
12822 if (!TextUtils.isEmpty(shareDescription)) {
12825 length = shareDescription.getBytes("UTF-8").length;
12826 } catch (UnsupportedEncodingException e) {
12827 String errorStr = "shareDescription: UnsupportedEncodingException";
12828 throw new IllegalArgumentException(errorStr);
12830 if (length > SystemProperties.PROP_VALUE_MAX) {
12831 String errorStr = "shareTitle should be less than " +
12832 SystemProperties.PROP_VALUE_MAX + " bytes";
12833 throw new IllegalArgumentException(errorStr);
12835 SystemProperties.set("dumpstate.options.description", shareDescription);
12838 SystemProperties.set("dumpstate.options.title", shareTitle);
12842 Slog.d(TAG, "Bugreport notification title " + shareTitle
12843 + " description " + shareDescription);
12844 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12847 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12848 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12851 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12852 if (r != null && (r.instr != null || r.usingWrapper)) {
12853 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12855 return KEY_DISPATCHING_TIMEOUT;
12859 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12860 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12861 != PackageManager.PERMISSION_GRANTED) {
12862 throw new SecurityException("Requires permission "
12863 + android.Manifest.permission.FILTER_EVENTS);
12865 ProcessRecord proc;
12867 synchronized (this) {
12868 synchronized (mPidsSelfLocked) {
12869 proc = mPidsSelfLocked.get(pid);
12871 timeout = getInputDispatchingTimeoutLocked(proc);
12874 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12882 * Handle input dispatching timeouts.
12883 * Returns whether input dispatching should be aborted or not.
12885 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12886 final ActivityRecord activity, final ActivityRecord parent,
12887 final boolean aboveSystem, String reason) {
12888 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12889 != PackageManager.PERMISSION_GRANTED) {
12890 throw new SecurityException("Requires permission "
12891 + android.Manifest.permission.FILTER_EVENTS);
12894 final String annotation;
12895 if (reason == null) {
12896 annotation = "Input dispatching timed out";
12898 annotation = "Input dispatching timed out (" + reason + ")";
12901 if (proc != null) {
12902 synchronized (this) {
12903 if (proc.debugging) {
12908 // Give more time since we were dexopting.
12909 mDidDexOpt = false;
12913 if (proc.instr != null) {
12914 Bundle info = new Bundle();
12915 info.putString("shortMsg", "keyDispatchingTimedOut");
12916 info.putString("longMsg", annotation);
12917 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12921 mHandler.post(new Runnable() {
12923 public void run() {
12924 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12933 public Bundle getAssistContextExtras(int requestType) {
12934 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12935 null, null, true /* focused */, true /* newSessionId */,
12936 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12940 synchronized (pae) {
12941 while (!pae.haveResult) {
12944 } catch (InterruptedException e) {
12948 synchronized (this) {
12949 buildAssistBundleLocked(pae, pae.result);
12950 mPendingAssistExtras.remove(pae);
12951 mUiHandler.removeCallbacks(pae);
12957 public boolean isAssistDataAllowedOnCurrentActivity() {
12959 synchronized (this) {
12960 final ActivityStack focusedStack = getFocusedStack();
12961 if (focusedStack == null || focusedStack.isAssistantStack()) {
12965 final ActivityRecord activity = focusedStack.topActivity();
12966 if (activity == null) {
12969 userId = activity.userId;
12971 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12972 Context.DEVICE_POLICY_SERVICE);
12973 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12977 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12978 long ident = Binder.clearCallingIdentity();
12980 synchronized (this) {
12981 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12982 ActivityRecord top = getFocusedStack().topActivity();
12983 if (top != caller) {
12984 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12985 + " is not current top " + top);
12988 if (!top.nowVisible) {
12989 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12990 + " is not visible");
12994 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12997 Binder.restoreCallingIdentity(ident);
13002 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13003 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13004 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13005 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13006 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13010 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13011 IBinder activityToken, int flags) {
13012 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13013 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13014 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13017 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13018 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13019 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13021 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13022 "enqueueAssistContext()");
13024 synchronized (this) {
13025 ActivityRecord activity = getFocusedStack().topActivity();
13026 if (activity == null) {
13027 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13030 if (activity.app == null || activity.app.thread == null) {
13031 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13035 if (activityToken != null) {
13036 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13037 if (activity != caller) {
13038 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13039 + " is not current top " + activity);
13044 activity = ActivityRecord.forTokenLocked(activityToken);
13045 if (activity == null) {
13046 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13047 + " couldn't be found");
13052 PendingAssistExtras pae;
13053 Bundle extras = new Bundle();
13054 if (args != null) {
13055 extras.putAll(args);
13057 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13058 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13060 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13062 pae.isHome = activity.isHomeActivity();
13064 // Increment the sessionId if necessary
13065 if (newSessionId) {
13069 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13070 mViSessionId, flags);
13071 mPendingAssistExtras.add(pae);
13072 mUiHandler.postDelayed(pae, timeout);
13073 } catch (RemoteException e) {
13074 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13081 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13082 IResultReceiver receiver;
13083 synchronized (this) {
13084 mPendingAssistExtras.remove(pae);
13085 receiver = pae.receiver;
13087 if (receiver != null) {
13088 // Caller wants result sent back to them.
13089 Bundle sendBundle = new Bundle();
13090 // At least return the receiver extras
13091 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13092 pae.receiverExtras);
13094 pae.receiver.send(0, sendBundle);
13095 } catch (RemoteException e) {
13100 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13101 if (result != null) {
13102 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13104 if (pae.hint != null) {
13105 pae.extras.putBoolean(pae.hint, true);
13109 /** Called from an app when assist data is ready. */
13111 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13112 AssistContent content, Uri referrer) {
13113 PendingAssistExtras pae = (PendingAssistExtras)token;
13114 synchronized (pae) {
13115 pae.result = extras;
13116 pae.structure = structure;
13117 pae.content = content;
13118 if (referrer != null) {
13119 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13121 if (structure != null) {
13122 structure.setHomeActivity(pae.isHome);
13124 pae.haveResult = true;
13126 if (pae.intent == null && pae.receiver == null) {
13127 // Caller is just waiting for the result.
13131 // We are now ready to launch the assist activity.
13132 IResultReceiver sendReceiver = null;
13133 Bundle sendBundle = null;
13134 synchronized (this) {
13135 buildAssistBundleLocked(pae, extras);
13136 boolean exists = mPendingAssistExtras.remove(pae);
13137 mUiHandler.removeCallbacks(pae);
13142 if ((sendReceiver=pae.receiver) != null) {
13143 // Caller wants result sent back to them.
13144 sendBundle = new Bundle();
13145 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13146 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13147 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13148 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13149 pae.receiverExtras);
13152 if (sendReceiver != null) {
13154 sendReceiver.send(0, sendBundle);
13155 } catch (RemoteException e) {
13160 final long ident = Binder.clearCallingIdentity();
13162 if (TextUtils.equals(pae.intent.getAction(),
13163 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13164 pae.intent.putExtras(pae.extras);
13165 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13167 pae.intent.replaceExtras(pae.extras);
13168 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13169 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13170 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13171 closeSystemDialogs("assist");
13174 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13175 } catch (ActivityNotFoundException e) {
13176 Slog.w(TAG, "No activity to handle assist action.", e);
13180 Binder.restoreCallingIdentity(ident);
13184 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13186 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13187 true /* focused */, true /* newSessionId */, userHandle, args,
13188 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13191 public void registerProcessObserver(IProcessObserver observer) {
13192 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13193 "registerProcessObserver()");
13194 synchronized (this) {
13195 mProcessObservers.register(observer);
13200 public void unregisterProcessObserver(IProcessObserver observer) {
13201 synchronized (this) {
13202 mProcessObservers.unregister(observer);
13207 public int getUidProcessState(int uid, String callingPackage) {
13208 if (!hasUsageStatsPermission(callingPackage)) {
13209 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13210 "getUidProcessState");
13213 synchronized (this) {
13214 UidRecord uidRec = mActiveUids.get(uid);
13215 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13220 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13221 String callingPackage) {
13222 if (!hasUsageStatsPermission(callingPackage)) {
13223 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13224 "registerUidObserver");
13226 synchronized (this) {
13227 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13228 callingPackage, which, cutpoint));
13233 public void unregisterUidObserver(IUidObserver observer) {
13234 synchronized (this) {
13235 mUidObservers.unregister(observer);
13240 public boolean convertFromTranslucent(IBinder token) {
13241 final long origId = Binder.clearCallingIdentity();
13243 synchronized (this) {
13244 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13248 final boolean translucentChanged = r.changeWindowTranslucency(true);
13249 if (translucentChanged) {
13250 r.getStack().releaseBackgroundResources(r);
13251 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13253 mWindowManager.setAppFullscreen(token, true);
13254 return translucentChanged;
13257 Binder.restoreCallingIdentity(origId);
13262 public boolean convertToTranslucent(IBinder token, Bundle options) {
13263 final long origId = Binder.clearCallingIdentity();
13265 synchronized (this) {
13266 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13270 final TaskRecord task = r.getTask();
13271 int index = task.mActivities.lastIndexOf(r);
13273 ActivityRecord under = task.mActivities.get(index - 1);
13274 under.returningOptions = ActivityOptions.fromBundle(options);
13276 final boolean translucentChanged = r.changeWindowTranslucency(false);
13277 if (translucentChanged) {
13278 r.getStack().convertActivityToTranslucent(r);
13280 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13281 mWindowManager.setAppFullscreen(token, false);
13282 return translucentChanged;
13285 Binder.restoreCallingIdentity(origId);
13290 public boolean requestVisibleBehind(IBinder token, boolean visible) {
13291 final long origId = Binder.clearCallingIdentity();
13293 synchronized (this) {
13294 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13296 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13301 Binder.restoreCallingIdentity(origId);
13306 public boolean isBackgroundVisibleBehind(IBinder token) {
13307 final long origId = Binder.clearCallingIdentity();
13309 synchronized (this) {
13310 final ActivityStack stack = ActivityRecord.getStackLocked(token);
13311 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13312 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13313 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13317 Binder.restoreCallingIdentity(origId);
13322 public Bundle getActivityOptions(IBinder token) {
13323 final long origId = Binder.clearCallingIdentity();
13325 synchronized (this) {
13326 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13328 final ActivityOptions activityOptions = r.pendingOptions;
13329 r.pendingOptions = null;
13330 return activityOptions == null ? null : activityOptions.toBundle();
13335 Binder.restoreCallingIdentity(origId);
13340 public void setImmersive(IBinder token, boolean immersive) {
13341 synchronized(this) {
13342 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13344 throw new IllegalArgumentException();
13346 r.immersive = immersive;
13348 // update associated state if we're frontmost
13349 if (r == mStackSupervisor.getResumedActivityLocked()) {
13350 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13351 applyUpdateLockStateLocked(r);
13357 public boolean isImmersive(IBinder token) {
13358 synchronized (this) {
13359 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13361 throw new IllegalArgumentException();
13363 return r.immersive;
13368 public void setVrThread(int tid) {
13369 enforceSystemHasVrFeature();
13370 synchronized (this) {
13371 synchronized (mPidsSelfLocked) {
13372 final int pid = Binder.getCallingPid();
13373 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13374 mVrController.setVrThreadLocked(tid, pid, proc);
13380 public void setPersistentVrThread(int tid) {
13381 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13382 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13383 + Binder.getCallingPid()
13384 + ", uid=" + Binder.getCallingUid()
13385 + " requires " + permission.RESTRICTED_VR_ACCESS;
13387 throw new SecurityException(msg);
13389 enforceSystemHasVrFeature();
13390 synchronized (this) {
13391 synchronized (mPidsSelfLocked) {
13392 final int pid = Binder.getCallingPid();
13393 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13394 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13400 * Schedule the given thread a normal scheduling priority.
13402 * @param newTid the tid of the thread to adjust the scheduling of.
13403 * @param suppressLogs {@code true} if any error logging should be disabled.
13405 * @return {@code true} if this succeeded.
13407 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13409 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13411 } catch (IllegalArgumentException e) {
13412 if (!suppressLogs) {
13413 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13420 * Schedule the given thread an FIFO scheduling priority.
13422 * @param newTid the tid of the thread to adjust the scheduling of.
13423 * @param suppressLogs {@code true} if any error logging should be disabled.
13425 * @return {@code true} if this succeeded.
13427 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13429 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13431 } catch (IllegalArgumentException e) {
13432 if (!suppressLogs) {
13433 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13440 * Check that we have the features required for VR-related API calls, and throw an exception if
13443 private void enforceSystemHasVrFeature() {
13444 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13445 throw new UnsupportedOperationException("VR mode not supported on this device!");
13450 public void setRenderThread(int tid) {
13451 synchronized (this) {
13452 ProcessRecord proc;
13453 int pid = Binder.getCallingPid();
13454 if (pid == Process.myPid()) {
13455 demoteSystemServerRenderThread(tid);
13458 synchronized (mPidsSelfLocked) {
13459 proc = mPidsSelfLocked.get(pid);
13460 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13461 // ensure the tid belongs to the process
13462 if (!isThreadInProcess(pid, tid)) {
13463 throw new IllegalArgumentException(
13464 "Render thread does not belong to process");
13466 proc.renderThreadTid = tid;
13467 if (DEBUG_OOM_ADJ) {
13468 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13470 // promote to FIFO now
13471 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13472 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13473 if (mUseFifoUiScheduling) {
13474 setThreadScheduler(proc.renderThreadTid,
13475 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13477 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13481 if (DEBUG_OOM_ADJ) {
13482 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13483 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13484 mUseFifoUiScheduling);
13492 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13493 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13495 * @param tid the tid of the RenderThread
13497 private void demoteSystemServerRenderThread(int tid) {
13498 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13502 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13503 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13504 throw new UnsupportedOperationException("VR mode not supported on this device!");
13507 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13510 synchronized (this) {
13511 r = ActivityRecord.isInStackLocked(token);
13515 throw new IllegalArgumentException();
13519 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13520 VrManagerInternal.NO_ERROR) {
13524 synchronized(this) {
13525 r.requestedVrComponent = (enabled) ? packageName : null;
13527 // Update associated state if this activity is currently focused
13528 if (r == mStackSupervisor.getResumedActivityLocked()) {
13529 applyUpdateVrModeLocked(r);
13536 public boolean isVrModePackageEnabled(ComponentName packageName) {
13537 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13538 throw new UnsupportedOperationException("VR mode not supported on this device!");
13541 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13543 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13544 VrManagerInternal.NO_ERROR;
13547 public boolean isTopActivityImmersive() {
13548 enforceNotIsolatedCaller("startActivity");
13549 synchronized (this) {
13550 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13551 return (r != null) ? r.immersive : false;
13556 * @return whether the system should disable UI modes incompatible with VR mode.
13558 boolean shouldDisableNonVrUiLocked() {
13559 return mVrController.shouldDisableNonVrUiLocked();
13563 public boolean isTopOfTask(IBinder token) {
13564 synchronized (this) {
13565 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13567 throw new IllegalArgumentException();
13569 return r.getTask().getTopActivity() == r;
13574 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13575 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13576 String msg = "Permission Denial: setHasTopUi() from pid="
13577 + Binder.getCallingPid()
13578 + ", uid=" + Binder.getCallingUid()
13579 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13581 throw new SecurityException(msg);
13583 final int pid = Binder.getCallingPid();
13584 final long origId = Binder.clearCallingIdentity();
13586 synchronized (this) {
13587 boolean changed = false;
13589 synchronized (mPidsSelfLocked) {
13590 pr = mPidsSelfLocked.get(pid);
13592 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13595 if (pr.hasTopUi != hasTopUi) {
13596 if (DEBUG_OOM_ADJ) {
13597 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13599 pr.hasTopUi = hasTopUi;
13604 updateOomAdjLocked(pr, true);
13608 Binder.restoreCallingIdentity(origId);
13612 public final void enterSafeMode() {
13613 synchronized(this) {
13614 // It only makes sense to do this before the system is ready
13615 // and started launching other packages.
13616 if (!mSystemReady) {
13618 AppGlobals.getPackageManager().enterSafeMode();
13619 } catch (RemoteException e) {
13627 public final void showSafeModeOverlay() {
13628 View v = LayoutInflater.from(mContext).inflate(
13629 com.android.internal.R.layout.safe_mode, null);
13630 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13631 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13632 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13633 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13634 lp.gravity = Gravity.BOTTOM | Gravity.START;
13635 lp.format = v.getBackground().getOpacity();
13636 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13637 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13638 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13639 ((WindowManager)mContext.getSystemService(
13640 Context.WINDOW_SERVICE)).addView(v, lp);
13643 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13644 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13647 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13648 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13649 synchronized (stats) {
13650 if (mBatteryStatsService.isOnBattery()) {
13651 mBatteryStatsService.enforceCallingPermission();
13652 int MY_UID = Binder.getCallingUid();
13654 if (sender == null) {
13657 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13659 BatteryStatsImpl.Uid.Pkg pkg =
13660 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13661 sourcePkg != null ? sourcePkg : rec.key.packageName);
13662 pkg.noteWakeupAlarmLocked(tag);
13667 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13668 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13671 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13672 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13673 synchronized (stats) {
13674 mBatteryStatsService.enforceCallingPermission();
13675 int MY_UID = Binder.getCallingUid();
13677 if (sender == null) {
13680 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13682 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13686 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13687 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13690 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13691 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13692 synchronized (stats) {
13693 mBatteryStatsService.enforceCallingPermission();
13694 int MY_UID = Binder.getCallingUid();
13696 if (sender == null) {
13699 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13701 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13705 public boolean killPids(int[] pids, String pReason, boolean secure) {
13706 if (Binder.getCallingUid() != SYSTEM_UID) {
13707 throw new SecurityException("killPids only available to the system");
13709 String reason = (pReason == null) ? "Unknown" : pReason;
13710 // XXX Note: don't acquire main activity lock here, because the window
13711 // manager calls in with its locks held.
13713 boolean killed = false;
13714 synchronized (mPidsSelfLocked) {
13716 for (int i=0; i<pids.length; i++) {
13717 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13718 if (proc != null) {
13719 int type = proc.setAdj;
13720 if (type > worstType) {
13726 // If the worst oom_adj is somewhere in the cached proc LRU range,
13727 // then constrain it so we will kill all cached procs.
13728 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13729 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13730 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13733 // If this is not a secure call, don't let it kill processes that
13735 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13736 worstType = ProcessList.SERVICE_ADJ;
13739 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13740 for (int i=0; i<pids.length; i++) {
13741 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13742 if (proc == null) {
13745 int adj = proc.setAdj;
13746 if (adj >= worstType && !proc.killedByAm) {
13747 proc.kill(reason, true);
13756 public void killUid(int appId, int userId, String reason) {
13757 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13758 synchronized (this) {
13759 final long identity = Binder.clearCallingIdentity();
13761 killPackageProcessesLocked(null, appId, userId,
13762 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13763 reason != null ? reason : "kill uid");
13765 Binder.restoreCallingIdentity(identity);
13771 public boolean killProcessesBelowForeground(String reason) {
13772 if (Binder.getCallingUid() != SYSTEM_UID) {
13773 throw new SecurityException("killProcessesBelowForeground() only available to system");
13776 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13779 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13780 if (Binder.getCallingUid() != SYSTEM_UID) {
13781 throw new SecurityException("killProcessesBelowAdj() only available to system");
13784 boolean killed = false;
13785 synchronized (mPidsSelfLocked) {
13786 final int size = mPidsSelfLocked.size();
13787 for (int i = 0; i < size; i++) {
13788 final int pid = mPidsSelfLocked.keyAt(i);
13789 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13790 if (proc == null) continue;
13792 final int adj = proc.setAdj;
13793 if (adj > belowAdj && !proc.killedByAm) {
13794 proc.kill(reason, true);
13803 public void hang(final IBinder who, boolean allowRestart) {
13804 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13805 != PackageManager.PERMISSION_GRANTED) {
13806 throw new SecurityException("Requires permission "
13807 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13810 final IBinder.DeathRecipient death = new DeathRecipient() {
13812 public void binderDied() {
13813 synchronized (this) {
13820 who.linkToDeath(death, 0);
13821 } catch (RemoteException e) {
13822 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13826 synchronized (this) {
13827 Watchdog.getInstance().setAllowRestart(allowRestart);
13828 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13829 synchronized (death) {
13830 while (who.isBinderAlive()) {
13833 } catch (InterruptedException e) {
13837 Watchdog.getInstance().setAllowRestart(true);
13842 public void restart() {
13843 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13844 != PackageManager.PERMISSION_GRANTED) {
13845 throw new SecurityException("Requires permission "
13846 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13849 Log.i(TAG, "Sending shutdown broadcast...");
13851 BroadcastReceiver br = new BroadcastReceiver() {
13852 @Override public void onReceive(Context context, Intent intent) {
13853 // Now the broadcast is done, finish up the low-level shutdown.
13854 Log.i(TAG, "Shutting down activity manager...");
13856 Log.i(TAG, "Shutdown complete, restarting!");
13857 killProcess(myPid());
13862 // First send the high-level shut down broadcast.
13863 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13864 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13865 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13866 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13867 mContext.sendOrderedBroadcastAsUser(intent,
13868 UserHandle.ALL, null, br, mHandler, 0, null, null);
13870 br.onReceive(mContext, intent);
13873 private long getLowRamTimeSinceIdle(long now) {
13874 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13878 public void performIdleMaintenance() {
13879 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13880 != PackageManager.PERMISSION_GRANTED) {
13881 throw new SecurityException("Requires permission "
13882 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13885 synchronized (this) {
13886 final long now = SystemClock.uptimeMillis();
13887 final long timeSinceLastIdle = now - mLastIdleTime;
13888 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13889 mLastIdleTime = now;
13890 mLowRamTimeSinceLastIdle = 0;
13891 if (mLowRamStartTime != 0) {
13892 mLowRamStartTime = now;
13895 StringBuilder sb = new StringBuilder(128);
13896 sb.append("Idle maintenance over ");
13897 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13898 sb.append(" low RAM for ");
13899 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13900 Slog.i(TAG, sb.toString());
13902 // If at least 1/3 of our time since the last idle period has been spent
13903 // with RAM low, then we want to kill processes.
13904 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13906 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13907 ProcessRecord proc = mLruProcesses.get(i);
13908 if (proc.notCachedSinceIdle) {
13909 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13910 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13911 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13912 if (doKilling && proc.initialIdlePss != 0
13913 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13914 sb = new StringBuilder(128);
13916 sb.append(proc.processName);
13917 sb.append(" in idle maint: pss=");
13918 sb.append(proc.lastPss);
13919 sb.append(", swapPss=");
13920 sb.append(proc.lastSwapPss);
13921 sb.append(", initialPss=");
13922 sb.append(proc.initialIdlePss);
13923 sb.append(", period=");
13924 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13925 sb.append(", lowRamPeriod=");
13926 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13927 Slog.wtfQuiet(TAG, sb.toString());
13928 proc.kill("idle maint (pss " + proc.lastPss
13929 + " from " + proc.initialIdlePss + ")", true);
13932 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13933 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13934 proc.notCachedSinceIdle = true;
13935 proc.initialIdlePss = 0;
13936 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13937 mTestPssMode, isSleepingLocked(), now);
13941 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13942 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13947 public void sendIdleJobTrigger() {
13948 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13949 != PackageManager.PERMISSION_GRANTED) {
13950 throw new SecurityException("Requires permission "
13951 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13954 final long ident = Binder.clearCallingIdentity();
13956 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13957 .setPackage("android")
13958 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13959 broadcastIntent(null, intent, null, null, 0, null, null, null,
13960 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13962 Binder.restoreCallingIdentity(ident);
13966 private void retrieveSettings() {
13967 final ContentResolver resolver = mContext.getContentResolver();
13968 final boolean freeformWindowManagement =
13969 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13970 || Settings.Global.getInt(
13971 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13972 final boolean supportsPictureInPicture =
13973 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13975 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
13976 final boolean supportsSplitScreenMultiWindow =
13977 ActivityManager.supportsSplitScreenMultiWindow(mContext);
13978 final boolean supportsMultiDisplay = mContext.getPackageManager()
13979 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
13980 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13981 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13982 final boolean alwaysFinishActivities =
13983 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13984 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13985 final boolean forceResizable = Settings.Global.getInt(
13986 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13987 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13988 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13989 final boolean supportsLeanbackOnly =
13990 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13992 // Transfer any global setting for forcing RTL layout, into a System Property
13993 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13995 final Configuration configuration = new Configuration();
13996 Settings.System.getConfiguration(resolver, configuration);
13998 // This will take care of setting the correct layout direction flags
13999 configuration.setLayoutDirection(configuration.locale);
14002 synchronized (this) {
14003 mDebugApp = mOrigDebugApp = debugApp;
14004 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14005 mAlwaysFinishActivities = alwaysFinishActivities;
14006 mSupportsLeanbackOnly = supportsLeanbackOnly;
14007 mForceResizableActivities = forceResizable;
14008 final boolean multiWindowFormEnabled = freeformWindowManagement
14009 || supportsSplitScreenMultiWindow
14010 || supportsPictureInPicture
14011 || supportsMultiDisplay;
14012 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14013 mSupportsMultiWindow = true;
14014 mSupportsFreeformWindowManagement = freeformWindowManagement;
14015 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14016 mSupportsPictureInPicture = supportsPictureInPicture;
14017 mSupportsMultiDisplay = supportsMultiDisplay;
14019 mSupportsMultiWindow = false;
14020 mSupportsFreeformWindowManagement = false;
14021 mSupportsSplitScreenMultiWindow = false;
14022 mSupportsPictureInPicture = false;
14023 mSupportsMultiDisplay = false;
14025 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14026 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14027 // This happens before any activities are started, so we can change global configuration
14029 updateConfigurationLocked(configuration, null, true);
14030 final Configuration globalConfig = getGlobalConfiguration();
14031 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14033 // Load resources only after the current configuration has been set.
14034 final Resources res = mContext.getResources();
14035 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14036 mThumbnailWidth = res.getDimensionPixelSize(
14037 com.android.internal.R.dimen.thumbnail_width);
14038 mThumbnailHeight = res.getDimensionPixelSize(
14039 com.android.internal.R.dimen.thumbnail_height);
14040 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14041 com.android.internal.R.string.config_appsNotReportingCrashes));
14042 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14043 com.android.internal.R.bool.config_customUserSwitchUi);
14044 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14045 mFullscreenThumbnailScale = (float) res
14046 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14047 (float) globalConfig.screenWidthDp;
14049 mFullscreenThumbnailScale = res.getFraction(
14050 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14052 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14056 public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14057 traceLog.traceBegin("PhaseActivityManagerReady");
14058 synchronized(this) {
14059 if (mSystemReady) {
14060 // If we're done calling all the receivers, run the next "boot phase" passed in
14061 // by the SystemServer
14062 if (goingCallback != null) {
14063 goingCallback.run();
14068 mLocalDeviceIdleController
14069 = LocalServices.getService(DeviceIdleController.LocalService.class);
14070 mAssistUtils = new AssistUtils(mContext);
14071 mVrController.onSystemReady();
14072 // Make sure we have the current profile info, since it is needed for security checks.
14073 mUserController.onSystemReady();
14074 mRecentTasks.onSystemReadyLocked();
14075 mAppOpsService.systemReady();
14076 mSystemReady = true;
14079 ArrayList<ProcessRecord> procsToKill = null;
14080 synchronized(mPidsSelfLocked) {
14081 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14082 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14083 if (!isAllowedWhileBooting(proc.info)){
14084 if (procsToKill == null) {
14085 procsToKill = new ArrayList<ProcessRecord>();
14087 procsToKill.add(proc);
14092 synchronized(this) {
14093 if (procsToKill != null) {
14094 for (int i=procsToKill.size()-1; i>=0; i--) {
14095 ProcessRecord proc = procsToKill.get(i);
14096 Slog.i(TAG, "Removing system update proc: " + proc);
14097 removeProcessLocked(proc, true, false, "system update done");
14101 // Now that we have cleaned up any update processes, we
14102 // are ready to start launching real processes and know that
14103 // we won't trample on them any more.
14104 mProcessesReady = true;
14107 Slog.i(TAG, "System now ready");
14108 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14109 SystemClock.uptimeMillis());
14111 synchronized(this) {
14112 // Make sure we have no pre-ready processes sitting around.
14114 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14115 ResolveInfo ri = mContext.getPackageManager()
14116 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14118 CharSequence errorMsg = null;
14120 ActivityInfo ai = ri.activityInfo;
14121 ApplicationInfo app = ai.applicationInfo;
14122 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14123 mTopAction = Intent.ACTION_FACTORY_TEST;
14125 mTopComponent = new ComponentName(app.packageName,
14128 errorMsg = mContext.getResources().getText(
14129 com.android.internal.R.string.factorytest_not_system);
14132 errorMsg = mContext.getResources().getText(
14133 com.android.internal.R.string.factorytest_no_action);
14135 if (errorMsg != null) {
14138 mTopComponent = null;
14139 Message msg = Message.obtain();
14140 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14141 msg.getData().putCharSequence("msg", errorMsg);
14142 mUiHandler.sendMessage(msg);
14147 retrieveSettings();
14148 final int currentUserId;
14149 synchronized (this) {
14150 currentUserId = mUserController.getCurrentUserIdLocked();
14151 readGrantedUriPermissionsLocked();
14154 if (goingCallback != null) goingCallback.run();
14155 traceLog.traceBegin("ActivityManagerStartApps");
14156 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14157 Integer.toString(currentUserId), currentUserId);
14158 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14159 Integer.toString(currentUserId), currentUserId);
14160 mSystemServiceManager.startUser(currentUserId);
14162 synchronized (this) {
14163 // Only start up encryption-aware persistent apps; once user is
14164 // unlocked we'll come back around and start unaware apps
14165 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14167 // Start up initial activity.
14169 // Enable home activity for system user, so that the system can always boot. We don't
14170 // do this when the system user is not setup since the setup wizard should be the one
14171 // to handle home activity in this case.
14172 if (UserManager.isSplitSystemUser() &&
14173 Settings.Secure.getInt(mContext.getContentResolver(),
14174 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14175 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14177 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14178 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14179 UserHandle.USER_SYSTEM);
14180 } catch (RemoteException e) {
14181 throw e.rethrowAsRuntimeException();
14184 startHomeActivityLocked(currentUserId, "systemReady");
14187 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14188 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14189 + " data partition or your device will be unstable.");
14190 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14192 } catch (RemoteException e) {
14195 if (!Build.isBuildConsistent()) {
14196 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14197 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14200 long ident = Binder.clearCallingIdentity();
14202 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14203 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14204 | Intent.FLAG_RECEIVER_FOREGROUND);
14205 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14206 broadcastIntentLocked(null, null, intent,
14207 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14208 null, false, false, MY_PID, SYSTEM_UID,
14210 intent = new Intent(Intent.ACTION_USER_STARTING);
14211 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14212 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14213 broadcastIntentLocked(null, null, intent,
14214 null, new IIntentReceiver.Stub() {
14216 public void performReceive(Intent intent, int resultCode, String data,
14217 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14218 throws RemoteException {
14221 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14222 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14223 } catch (Throwable t) {
14224 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14226 Binder.restoreCallingIdentity(ident);
14228 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14229 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14230 traceLog.traceEnd(); // ActivityManagerStartApps
14231 traceLog.traceEnd(); // PhaseActivityManagerReady
14235 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14236 synchronized (this) {
14237 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14241 void skipCurrentReceiverLocked(ProcessRecord app) {
14242 for (BroadcastQueue queue : mBroadcastQueues) {
14243 queue.skipCurrentReceiverLocked(app);
14248 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14249 * The application process will exit immediately after this call returns.
14250 * @param app object of the crashing app, null for the system server
14251 * @param crashInfo describing the exception
14253 public void handleApplicationCrash(IBinder app,
14254 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14255 ProcessRecord r = findAppProcess(app, "Crash");
14256 final String processName = app == null ? "system_server"
14257 : (r == null ? "unknown" : r.processName);
14259 handleApplicationCrashInner("crash", r, processName, crashInfo);
14262 /* Native crash reporting uses this inner version because it needs to be somewhat
14263 * decoupled from the AM-managed cleanup lifecycle
14265 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14266 ApplicationErrorReport.CrashInfo crashInfo) {
14267 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14268 UserHandle.getUserId(Binder.getCallingUid()), processName,
14269 r == null ? -1 : r.info.flags,
14270 crashInfo.exceptionClassName,
14271 crashInfo.exceptionMessage,
14272 crashInfo.throwFileName,
14273 crashInfo.throwLineNumber);
14275 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14277 mAppErrors.crashApplication(r, crashInfo);
14280 public void handleApplicationStrictModeViolation(
14283 StrictMode.ViolationInfo info) {
14284 ProcessRecord r = findAppProcess(app, "StrictMode");
14289 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14290 Integer stackFingerprint = info.hashCode();
14291 boolean logIt = true;
14292 synchronized (mAlreadyLoggedViolatedStacks) {
14293 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14295 // TODO: sub-sample into EventLog for these, with
14296 // the info.durationMillis? Then we'd get
14297 // the relative pain numbers, without logging all
14298 // the stack traces repeatedly. We'd want to do
14299 // likewise in the client code, which also does
14300 // dup suppression, before the Binder call.
14302 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14303 mAlreadyLoggedViolatedStacks.clear();
14305 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14309 logStrictModeViolationToDropBox(r, info);
14313 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14314 AppErrorResult result = new AppErrorResult();
14315 synchronized (this) {
14316 final long origId = Binder.clearCallingIdentity();
14318 Message msg = Message.obtain();
14319 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14320 HashMap<String, Object> data = new HashMap<String, Object>();
14321 data.put("result", result);
14322 data.put("app", r);
14323 data.put("violationMask", violationMask);
14324 data.put("info", info);
14326 mUiHandler.sendMessage(msg);
14328 Binder.restoreCallingIdentity(origId);
14330 int res = result.get();
14331 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14335 // Depending on the policy in effect, there could be a bunch of
14336 // these in quick succession so we try to batch these together to
14337 // minimize disk writes, number of dropbox entries, and maximize
14338 // compression, by having more fewer, larger records.
14339 private void logStrictModeViolationToDropBox(
14340 ProcessRecord process,
14341 StrictMode.ViolationInfo info) {
14342 if (info == null) {
14345 final boolean isSystemApp = process == null ||
14346 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14347 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14348 final String processName = process == null ? "unknown" : process.processName;
14349 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14350 final DropBoxManager dbox = (DropBoxManager)
14351 mContext.getSystemService(Context.DROPBOX_SERVICE);
14353 // Exit early if the dropbox isn't configured to accept this report type.
14354 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14356 boolean bufferWasEmpty;
14357 boolean needsFlush;
14358 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14359 synchronized (sb) {
14360 bufferWasEmpty = sb.length() == 0;
14361 appendDropBoxProcessHeaders(process, processName, sb);
14362 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14363 sb.append("System-App: ").append(isSystemApp).append("\n");
14364 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14365 if (info.violationNumThisLoop != 0) {
14366 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14368 if (info.numAnimationsRunning != 0) {
14369 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14371 if (info.broadcastIntentAction != null) {
14372 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14374 if (info.durationMillis != -1) {
14375 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14377 if (info.numInstances != -1) {
14378 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14380 if (info.tags != null) {
14381 for (String tag : info.tags) {
14382 sb.append("Span-Tag: ").append(tag).append("\n");
14386 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14387 sb.append(info.crashInfo.stackTrace);
14390 if (info.message != null) {
14391 sb.append(info.message);
14395 // Only buffer up to ~64k. Various logging bits truncate
14397 needsFlush = (sb.length() > 64 * 1024);
14400 // Flush immediately if the buffer's grown too large, or this
14401 // is a non-system app. Non-system apps are isolated with a
14402 // different tag & policy and not batched.
14404 // Batching is useful during internal testing with
14405 // StrictMode settings turned up high. Without batching,
14406 // thousands of separate files could be created on boot.
14407 if (!isSystemApp || needsFlush) {
14408 new Thread("Error dump: " + dropboxTag) {
14410 public void run() {
14412 synchronized (sb) {
14413 report = sb.toString();
14414 sb.delete(0, sb.length());
14417 if (report.length() != 0) {
14418 dbox.addText(dropboxTag, report);
14425 // System app batching:
14426 if (!bufferWasEmpty) {
14427 // An existing dropbox-writing thread is outstanding, so
14428 // we don't need to start it up. The existing thread will
14429 // catch the buffer appends we just did.
14433 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14434 // (After this point, we shouldn't access AMS internal data structures.)
14435 new Thread("Error dump: " + dropboxTag) {
14437 public void run() {
14438 // 5 second sleep to let stacks arrive and be batched together
14440 Thread.sleep(5000); // 5 seconds
14441 } catch (InterruptedException e) {}
14443 String errorReport;
14444 synchronized (mStrictModeBuffer) {
14445 errorReport = mStrictModeBuffer.toString();
14446 if (errorReport.length() == 0) {
14449 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14450 mStrictModeBuffer.trimToSize();
14452 dbox.addText(dropboxTag, errorReport);
14458 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14459 * @param app object of the crashing app, null for the system server
14460 * @param tag reported by the caller
14461 * @param system whether this wtf is coming from the system
14462 * @param crashInfo describing the context of the error
14463 * @return true if the process should exit immediately (WTF is fatal)
14465 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14466 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14467 final int callingUid = Binder.getCallingUid();
14468 final int callingPid = Binder.getCallingPid();
14471 // If this is coming from the system, we could very well have low-level
14472 // system locks held, so we want to do this all asynchronously. And we
14473 // never want this to become fatal, so there is that too.
14474 mHandler.post(new Runnable() {
14475 @Override public void run() {
14476 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14482 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14485 final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14486 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14487 final boolean isSystem = (r == null) || r.persistent;
14489 if (isFatal && !isSystem) {
14490 mAppErrors.crashApplication(r, crashInfo);
14497 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14498 final ApplicationErrorReport.CrashInfo crashInfo) {
14499 final ProcessRecord r = findAppProcess(app, "WTF");
14500 final String processName = app == null ? "system_server"
14501 : (r == null ? "unknown" : r.processName);
14503 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14504 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14506 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14512 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14513 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14515 private ProcessRecord findAppProcess(IBinder app, String reason) {
14520 synchronized (this) {
14521 final int NP = mProcessNames.getMap().size();
14522 for (int ip=0; ip<NP; ip++) {
14523 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14524 final int NA = apps.size();
14525 for (int ia=0; ia<NA; ia++) {
14526 ProcessRecord p = apps.valueAt(ia);
14527 if (p.thread != null && p.thread.asBinder() == app) {
14533 Slog.w(TAG, "Can't find mystery application for " + reason
14534 + " from pid=" + Binder.getCallingPid()
14535 + " uid=" + Binder.getCallingUid() + ": " + app);
14541 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14542 * to append various headers to the dropbox log text.
14544 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14545 StringBuilder sb) {
14546 // Watchdog thread ends up invoking this function (with
14547 // a null ProcessRecord) to add the stack file to dropbox.
14548 // Do not acquire a lock on this (am) in such cases, as it
14549 // could cause a potential deadlock, if and when watchdog
14550 // is invoked due to unavailability of lock on am and it
14551 // would prevent watchdog from killing system_server.
14552 if (process == null) {
14553 sb.append("Process: ").append(processName).append("\n");
14556 // Note: ProcessRecord 'process' is guarded by the service
14557 // instance. (notably process.pkgList, which could otherwise change
14558 // concurrently during execution of this method)
14559 synchronized (this) {
14560 sb.append("Process: ").append(processName).append("\n");
14561 sb.append("PID: ").append(process.pid).append("\n");
14562 int flags = process.info.flags;
14563 IPackageManager pm = AppGlobals.getPackageManager();
14564 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14565 for (int ip=0; ip<process.pkgList.size(); ip++) {
14566 String pkg = process.pkgList.keyAt(ip);
14567 sb.append("Package: ").append(pkg);
14569 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14571 sb.append(" v").append(pi.versionCode);
14572 if (pi.versionName != null) {
14573 sb.append(" (").append(pi.versionName).append(")");
14576 } catch (RemoteException e) {
14577 Slog.e(TAG, "Error getting package info: " + pkg, e);
14584 private static String processClass(ProcessRecord process) {
14585 if (process == null || process.pid == MY_PID) {
14586 return "system_server";
14587 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14588 return "system_app";
14594 private volatile long mWtfClusterStart;
14595 private volatile int mWtfClusterCount;
14598 * Write a description of an error (crash, WTF, ANR) to the drop box.
14599 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14600 * @param process which caused the error, null means the system server
14601 * @param activity which triggered the error, null if unknown
14602 * @param parent activity related to the error, null if unknown
14603 * @param subject line related to the error, null if absent
14604 * @param report in long form describing the error, null if absent
14605 * @param dataFile text file to include in the report, null if none
14606 * @param crashInfo giving an application stack trace, null if absent
14608 public void addErrorToDropBox(String eventType,
14609 ProcessRecord process, String processName, ActivityRecord activity,
14610 ActivityRecord parent, String subject,
14611 final String report, final File dataFile,
14612 final ApplicationErrorReport.CrashInfo crashInfo) {
14613 // NOTE -- this must never acquire the ActivityManagerService lock,
14614 // otherwise the watchdog may be prevented from resetting the system.
14616 // Bail early if not published yet
14617 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14618 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14620 // Exit early if the dropbox isn't configured to accept this report type.
14621 final String dropboxTag = processClass(process) + "_" + eventType;
14622 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14624 // Rate-limit how often we're willing to do the heavy lifting below to
14625 // collect and record logs; currently 5 logs per 10 second period.
14626 final long now = SystemClock.elapsedRealtime();
14627 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14628 mWtfClusterStart = now;
14629 mWtfClusterCount = 1;
14631 if (mWtfClusterCount++ >= 5) return;
14634 final StringBuilder sb = new StringBuilder(1024);
14635 appendDropBoxProcessHeaders(process, processName, sb);
14636 if (process != null) {
14637 sb.append("Foreground: ")
14638 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14641 if (activity != null) {
14642 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14644 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14645 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14647 if (parent != null && parent != activity) {
14648 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14650 if (subject != null) {
14651 sb.append("Subject: ").append(subject).append("\n");
14653 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14654 if (Debug.isDebuggerConnected()) {
14655 sb.append("Debugger: Connected\n");
14659 // Do the rest in a worker thread to avoid blocking the caller on I/O
14660 // (After this point, we shouldn't access AMS internal data structures.)
14661 Thread worker = new Thread("Error dump: " + dropboxTag) {
14663 public void run() {
14664 if (report != null) {
14668 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14669 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14670 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14671 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14673 if (dataFile != null && maxDataFileSize > 0) {
14675 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14676 "\n\n[[TRUNCATED]]"));
14677 } catch (IOException e) {
14678 Slog.e(TAG, "Error reading " + dataFile, e);
14681 if (crashInfo != null && crashInfo.stackTrace != null) {
14682 sb.append(crashInfo.stackTrace);
14688 // Merge several logcat streams, and take the last N lines
14689 InputStreamReader input = null;
14691 java.lang.Process logcat = new ProcessBuilder(
14692 "/system/bin/timeout", "-k", "15s", "10s",
14693 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14694 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14695 .redirectErrorStream(true).start();
14697 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14698 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14699 input = new InputStreamReader(logcat.getInputStream());
14702 char[] buf = new char[8192];
14703 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14704 } catch (IOException e) {
14705 Slog.e(TAG, "Error running logcat", e);
14707 if (input != null) try { input.close(); } catch (IOException e) {}
14711 dbox.addText(dropboxTag, sb.toString());
14715 if (process == null) {
14716 // If process is null, we are being called from some internal code
14717 // and may be about to die -- run this synchronously.
14725 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14726 enforceNotIsolatedCaller("getProcessesInErrorState");
14727 // assume our apps are happy - lazy create the list
14728 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14730 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14731 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14732 int userId = UserHandle.getUserId(Binder.getCallingUid());
14734 synchronized (this) {
14736 // iterate across all processes
14737 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14738 ProcessRecord app = mLruProcesses.get(i);
14739 if (!allUsers && app.userId != userId) {
14742 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14743 // This one's in trouble, so we'll generate a report for it
14744 // crashes are higher priority (in case there's a crash *and* an anr)
14745 ActivityManager.ProcessErrorStateInfo report = null;
14746 if (app.crashing) {
14747 report = app.crashingReport;
14748 } else if (app.notResponding) {
14749 report = app.notRespondingReport;
14752 if (report != null) {
14753 if (errList == null) {
14754 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14756 errList.add(report);
14758 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14759 " crashing = " + app.crashing +
14760 " notResponding = " + app.notResponding);
14769 static int procStateToImportance(int procState, int memAdj,
14770 ActivityManager.RunningAppProcessInfo currApp,
14771 int clientTargetSdk) {
14772 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14773 procState, clientTargetSdk);
14774 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14775 currApp.lru = memAdj;
14782 private void fillInProcMemInfo(ProcessRecord app,
14783 ActivityManager.RunningAppProcessInfo outInfo,
14784 int clientTargetSdk) {
14785 outInfo.pid = app.pid;
14786 outInfo.uid = app.info.uid;
14787 if (mHeavyWeightProcess == app) {
14788 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14790 if (app.persistent) {
14791 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14793 if (app.activities.size() > 0) {
14794 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14796 outInfo.lastTrimLevel = app.trimMemoryLevel;
14797 int adj = app.curAdj;
14798 int procState = app.curProcState;
14799 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14800 outInfo.importanceReasonCode = app.adjTypeCode;
14801 outInfo.processState = app.curProcState;
14805 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14806 enforceNotIsolatedCaller("getRunningAppProcesses");
14808 final int callingUid = Binder.getCallingUid();
14809 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14811 // Lazy instantiation of list
14812 List<ActivityManager.RunningAppProcessInfo> runList = null;
14813 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14814 callingUid) == PackageManager.PERMISSION_GRANTED;
14815 final int userId = UserHandle.getUserId(callingUid);
14816 final boolean allUids = isGetTasksAllowed(
14817 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14819 synchronized (this) {
14820 // Iterate across all processes
14821 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14822 ProcessRecord app = mLruProcesses.get(i);
14823 if ((!allUsers && app.userId != userId)
14824 || (!allUids && app.uid != callingUid)) {
14827 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14828 // Generate process state info for running application
14829 ActivityManager.RunningAppProcessInfo currApp =
14830 new ActivityManager.RunningAppProcessInfo(app.processName,
14831 app.pid, app.getPackageList());
14832 fillInProcMemInfo(app, currApp, clientTargetSdk);
14833 if (app.adjSource instanceof ProcessRecord) {
14834 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14835 currApp.importanceReasonImportance =
14836 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14837 app.adjSourceProcState);
14838 } else if (app.adjSource instanceof ActivityRecord) {
14839 ActivityRecord r = (ActivityRecord)app.adjSource;
14840 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14842 if (app.adjTarget instanceof ComponentName) {
14843 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14845 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14846 // + " lru=" + currApp.lru);
14847 if (runList == null) {
14848 runList = new ArrayList<>();
14850 runList.add(currApp);
14858 public List<ApplicationInfo> getRunningExternalApplications() {
14859 enforceNotIsolatedCaller("getRunningExternalApplications");
14860 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14861 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14862 if (runningApps != null && runningApps.size() > 0) {
14863 Set<String> extList = new HashSet<String>();
14864 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14865 if (app.pkgList != null) {
14866 for (String pkg : app.pkgList) {
14871 IPackageManager pm = AppGlobals.getPackageManager();
14872 for (String pkg : extList) {
14874 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14875 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14878 } catch (RemoteException e) {
14886 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14887 enforceNotIsolatedCaller("getMyMemoryState");
14889 final int callingUid = Binder.getCallingUid();
14890 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14892 synchronized (this) {
14893 ProcessRecord proc;
14894 synchronized (mPidsSelfLocked) {
14895 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14897 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14902 public int getMemoryTrimLevel() {
14903 enforceNotIsolatedCaller("getMyMemoryState");
14904 synchronized (this) {
14905 return mLastMemoryLevel;
14910 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14911 FileDescriptor err, String[] args, ShellCallback callback,
14912 ResultReceiver resultReceiver) {
14913 (new ActivityManagerShellCommand(this, false)).exec(
14914 this, in, out, err, args, callback, resultReceiver);
14918 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14919 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14921 boolean dumpAll = false;
14922 boolean dumpClient = false;
14923 boolean dumpCheckin = false;
14924 boolean dumpCheckinFormat = false;
14925 boolean dumpVisibleStacksOnly = false;
14926 boolean dumpFocusedStackOnly = false;
14927 String dumpPackage = null;
14930 while (opti < args.length) {
14931 String opt = args[opti];
14932 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14936 if ("-a".equals(opt)) {
14938 } else if ("-c".equals(opt)) {
14940 } else if ("-v".equals(opt)) {
14941 dumpVisibleStacksOnly = true;
14942 } else if ("-f".equals(opt)) {
14943 dumpFocusedStackOnly = true;
14944 } else if ("-p".equals(opt)) {
14945 if (opti < args.length) {
14946 dumpPackage = args[opti];
14949 pw.println("Error: -p option requires package argument");
14953 } else if ("--checkin".equals(opt)) {
14954 dumpCheckin = dumpCheckinFormat = true;
14955 } else if ("-C".equals(opt)) {
14956 dumpCheckinFormat = true;
14957 } else if ("-h".equals(opt)) {
14958 ActivityManagerShellCommand.dumpHelp(pw, true);
14961 pw.println("Unknown argument: " + opt + "; use -h for help");
14965 long origId = Binder.clearCallingIdentity();
14966 boolean more = false;
14967 // Is the caller requesting to dump a particular piece of data?
14968 if (opti < args.length) {
14969 String cmd = args[opti];
14971 if ("activities".equals(cmd) || "a".equals(cmd)) {
14972 synchronized (this) {
14973 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14975 } else if ("lastanr".equals(cmd)) {
14976 synchronized (this) {
14977 dumpLastANRLocked(pw);
14979 } else if ("starter".equals(cmd)) {
14980 synchronized (this) {
14981 dumpActivityStarterLocked(pw);
14983 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14984 synchronized (this) {
14985 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14987 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14990 if (opti >= args.length) {
14992 newArgs = EMPTY_STRING_ARRAY;
14994 dumpPackage = args[opti];
14996 newArgs = new String[args.length - opti];
14997 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14998 args.length - opti);
15000 synchronized (this) {
15001 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15003 } else if ("broadcast-stats".equals(cmd)) {
15006 if (opti >= args.length) {
15008 newArgs = EMPTY_STRING_ARRAY;
15010 dumpPackage = args[opti];
15012 newArgs = new String[args.length - opti];
15013 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15014 args.length - opti);
15016 synchronized (this) {
15017 if (dumpCheckinFormat) {
15018 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15021 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15024 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15027 if (opti >= args.length) {
15029 newArgs = EMPTY_STRING_ARRAY;
15031 dumpPackage = args[opti];
15033 newArgs = new String[args.length - opti];
15034 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15035 args.length - opti);
15037 synchronized (this) {
15038 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15040 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15043 if (opti >= args.length) {
15045 newArgs = EMPTY_STRING_ARRAY;
15047 dumpPackage = args[opti];
15049 newArgs = new String[args.length - opti];
15050 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15051 args.length - opti);
15053 synchronized (this) {
15054 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15056 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15057 synchronized (this) {
15058 dumpOomLocked(fd, pw, args, opti, true);
15060 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15061 synchronized (this) {
15062 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15064 } else if ("provider".equals(cmd)) {
15067 if (opti >= args.length) {
15069 newArgs = EMPTY_STRING_ARRAY;
15073 newArgs = new String[args.length - opti];
15074 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15076 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15077 pw.println("No providers match: " + name);
15078 pw.println("Use -h for help.");
15080 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15081 synchronized (this) {
15082 dumpProvidersLocked(fd, pw, args, opti, true, null);
15084 } else if ("service".equals(cmd)) {
15087 if (opti >= args.length) {
15089 newArgs = EMPTY_STRING_ARRAY;
15093 newArgs = new String[args.length - opti];
15094 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15095 args.length - opti);
15097 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15098 pw.println("No services match: " + name);
15099 pw.println("Use -h for help.");
15101 } else if ("package".equals(cmd)) {
15103 if (opti >= args.length) {
15104 pw.println("package: no package name specified");
15105 pw.println("Use -h for help.");
15107 dumpPackage = args[opti];
15109 newArgs = new String[args.length - opti];
15110 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15111 args.length - opti);
15116 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15117 synchronized (this) {
15118 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15120 } else if ("settings".equals(cmd)) {
15121 synchronized (this) {
15122 mConstants.dump(pw);
15124 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15126 ActiveServices.ServiceDumper dumper;
15127 synchronized (this) {
15128 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15131 dumper.dumpWithClient();
15133 synchronized (this) {
15134 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15135 dumpPackage).dumpLocked();
15138 } else if ("locks".equals(cmd)) {
15139 LockGuard.dump(fd, pw, args);
15141 // Dumping a single activity?
15142 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15143 dumpFocusedStackOnly)) {
15144 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15145 int res = shell.exec(this, null, fd, null, args, null,
15146 new ResultReceiver(null));
15148 pw.println("Bad activity command, or no activities match: " + cmd);
15149 pw.println("Use -h for help.");
15154 Binder.restoreCallingIdentity(origId);
15159 // No piece of data specified, dump everything.
15160 if (dumpCheckinFormat) {
15161 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15162 } else if (dumpClient) {
15163 ActiveServices.ServiceDumper sdumper;
15164 synchronized (this) {
15165 mConstants.dump(pw);
15168 pw.println("-------------------------------------------------------------------------------");
15170 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15173 pw.println("-------------------------------------------------------------------------------");
15175 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15178 pw.println("-------------------------------------------------------------------------------");
15180 if (dumpAll || dumpPackage != null) {
15181 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15184 pw.println("-------------------------------------------------------------------------------");
15187 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15190 pw.println("-------------------------------------------------------------------------------");
15192 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15195 pw.println("-------------------------------------------------------------------------------");
15197 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15200 sdumper.dumpWithClient();
15202 synchronized (this) {
15204 pw.println("-------------------------------------------------------------------------------");
15206 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15209 pw.println("-------------------------------------------------------------------------------");
15211 dumpLastANRLocked(pw);
15214 pw.println("-------------------------------------------------------------------------------");
15216 dumpActivityStarterLocked(pw);
15219 pw.println("-------------------------------------------------------------------------------");
15221 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15222 if (mAssociations.size() > 0) {
15225 pw.println("-------------------------------------------------------------------------------");
15227 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15231 pw.println("-------------------------------------------------------------------------------");
15233 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15237 synchronized (this) {
15238 mConstants.dump(pw);
15241 pw.println("-------------------------------------------------------------------------------");
15243 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15246 pw.println("-------------------------------------------------------------------------------");
15248 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15251 pw.println("-------------------------------------------------------------------------------");
15253 if (dumpAll || dumpPackage != null) {
15254 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15257 pw.println("-------------------------------------------------------------------------------");
15260 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15263 pw.println("-------------------------------------------------------------------------------");
15265 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15268 pw.println("-------------------------------------------------------------------------------");
15270 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15274 pw.println("-------------------------------------------------------------------------------");
15276 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15279 pw.println("-------------------------------------------------------------------------------");
15281 dumpLastANRLocked(pw);
15284 pw.println("-------------------------------------------------------------------------------");
15286 dumpActivityStarterLocked(pw);
15289 pw.println("-------------------------------------------------------------------------------");
15291 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15292 if (mAssociations.size() > 0) {
15295 pw.println("-------------------------------------------------------------------------------");
15297 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15301 pw.println("-------------------------------------------------------------------------------");
15303 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15306 Binder.restoreCallingIdentity(origId);
15309 private void dumpLastANRLocked(PrintWriter pw) {
15310 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
15311 if (mLastANRState == null) {
15312 pw.println(" <no ANR has occurred since boot>");
15314 pw.println(mLastANRState);
15318 private void dumpActivityStarterLocked(PrintWriter pw) {
15319 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
15320 mActivityStarter.dump(pw, "");
15323 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15324 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15325 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15326 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15329 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15330 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15331 pw.println(header);
15333 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15335 boolean needSep = printedAnything;
15337 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15338 mStackSupervisor.getResumedActivityLocked(),
15339 dumpPackage, needSep, " ResumedActivity: ");
15341 printedAnything = true;
15345 if (dumpPackage == null) {
15349 printedAnything = true;
15350 mStackSupervisor.dump(pw, " ");
15353 if (!printedAnything) {
15354 pw.println(" (nothing)");
15358 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15359 int opti, boolean dumpAll, String dumpPackage) {
15360 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15362 boolean printedAnything = false;
15364 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15365 boolean printedHeader = false;
15367 final int N = mRecentTasks.size();
15368 for (int i=0; i<N; i++) {
15369 TaskRecord tr = mRecentTasks.get(i);
15370 if (dumpPackage != null) {
15371 if (tr.realActivity == null ||
15372 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15376 if (!printedHeader) {
15377 pw.println(" Recent tasks:");
15378 printedHeader = true;
15379 printedAnything = true;
15381 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15384 mRecentTasks.get(i).dump(pw, " ");
15389 if (!printedAnything) {
15390 pw.println(" (nothing)");
15394 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15395 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15396 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15399 if (dumpPackage != null) {
15400 IPackageManager pm = AppGlobals.getPackageManager();
15402 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15403 } catch (RemoteException e) {
15407 boolean printedAnything = false;
15409 final long now = SystemClock.uptimeMillis();
15411 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15412 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15413 = mAssociations.valueAt(i1);
15414 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15415 SparseArray<ArrayMap<String, Association>> sourceUids
15416 = targetComponents.valueAt(i2);
15417 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15418 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15419 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15420 Association ass = sourceProcesses.valueAt(i4);
15421 if (dumpPackage != null) {
15422 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15423 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15427 printedAnything = true;
15429 pw.print(ass.mTargetProcess);
15431 UserHandle.formatUid(pw, ass.mTargetUid);
15433 pw.print(ass.mSourceProcess);
15435 UserHandle.formatUid(pw, ass.mSourceUid);
15438 pw.print(ass.mTargetComponent.flattenToShortString());
15441 long dur = ass.mTime;
15442 if (ass.mNesting > 0) {
15443 dur += now - ass.mStartTime;
15445 TimeUtils.formatDuration(dur, pw);
15447 pw.print(ass.mCount);
15448 pw.print(" times)");
15450 for (int i=0; i<ass.mStateTimes.length; i++) {
15451 long amt = ass.mStateTimes[i];
15452 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15453 amt += now - ass.mLastStateUptime;
15457 pw.print(ProcessList.makeProcStateString(
15458 i + ActivityManager.MIN_PROCESS_STATE));
15460 TimeUtils.formatDuration(amt, pw);
15461 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15467 if (ass.mNesting > 0) {
15468 pw.print(" Currently active: ");
15469 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15478 if (!printedAnything) {
15479 pw.println(" (nothing)");
15483 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15484 String header, boolean needSep) {
15485 boolean printed = false;
15486 int whichAppId = -1;
15487 if (dumpPackage != null) {
15489 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15491 whichAppId = UserHandle.getAppId(info.uid);
15492 } catch (NameNotFoundException e) {
15493 e.printStackTrace();
15496 for (int i=0; i<uids.size(); i++) {
15497 UidRecord uidRec = uids.valueAt(i);
15498 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15507 pw.println(header);
15510 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15511 pw.print(": "); pw.println(uidRec);
15516 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15517 int opti, boolean dumpAll, String dumpPackage) {
15518 boolean needSep = false;
15519 boolean printedAnything = false;
15522 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15525 final int NP = mProcessNames.getMap().size();
15526 for (int ip=0; ip<NP; ip++) {
15527 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15528 final int NA = procs.size();
15529 for (int ia=0; ia<NA; ia++) {
15530 ProcessRecord r = procs.valueAt(ia);
15531 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15535 pw.println(" All known processes:");
15537 printedAnything = true;
15539 pw.print(r.persistent ? " *PERS*" : " *APP*");
15540 pw.print(" UID "); pw.print(procs.keyAt(ia));
15541 pw.print(" "); pw.println(r);
15543 if (r.persistent) {
15550 if (mIsolatedProcesses.size() > 0) {
15551 boolean printed = false;
15552 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15553 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15554 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15561 pw.println(" Isolated process list (sorted by uid):");
15562 printedAnything = true;
15566 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15571 if (mActiveInstrumentation.size() > 0) {
15572 boolean printed = false;
15573 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15574 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15575 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15576 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15583 pw.println(" Active instrumentation:");
15584 printedAnything = true;
15588 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15594 if (mActiveUids.size() > 0) {
15595 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15596 printedAnything = needSep = true;
15600 if (mValidateUids.size() > 0) {
15601 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15602 printedAnything = needSep = true;
15607 if (mLruProcesses.size() > 0) {
15611 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15612 pw.print(" total, non-act at ");
15613 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15614 pw.print(", non-svc at ");
15615 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15617 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15619 printedAnything = true;
15622 if (dumpAll || dumpPackage != null) {
15623 synchronized (mPidsSelfLocked) {
15624 boolean printed = false;
15625 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15626 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15627 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15631 if (needSep) pw.println();
15633 pw.println(" PID mappings:");
15635 printedAnything = true;
15637 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15638 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15643 if (mImportantProcesses.size() > 0) {
15644 synchronized (mPidsSelfLocked) {
15645 boolean printed = false;
15646 for (int i = 0; i< mImportantProcesses.size(); i++) {
15647 ProcessRecord r = mPidsSelfLocked.get(
15648 mImportantProcesses.valueAt(i).pid);
15649 if (dumpPackage != null && (r == null
15650 || !r.pkgList.containsKey(dumpPackage))) {
15654 if (needSep) pw.println();
15656 pw.println(" Foreground Processes:");
15658 printedAnything = true;
15660 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15661 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15666 if (mPersistentStartingProcesses.size() > 0) {
15667 if (needSep) pw.println();
15669 printedAnything = true;
15670 pw.println(" Persisent processes that are starting:");
15671 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15672 "Starting Norm", "Restarting PERS", dumpPackage);
15675 if (mRemovedProcesses.size() > 0) {
15676 if (needSep) pw.println();
15678 printedAnything = true;
15679 pw.println(" Processes that are being removed:");
15680 dumpProcessList(pw, this, mRemovedProcesses, " ",
15681 "Removed Norm", "Removed PERS", dumpPackage);
15684 if (mProcessesOnHold.size() > 0) {
15685 if (needSep) pw.println();
15687 printedAnything = true;
15688 pw.println(" Processes that are on old until the system is ready:");
15689 dumpProcessList(pw, this, mProcessesOnHold, " ",
15690 "OnHold Norm", "OnHold PERS", dumpPackage);
15693 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15695 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15697 printedAnything = true;
15700 if (dumpPackage == null) {
15703 mUserController.dump(pw, dumpAll);
15705 if (mHomeProcess != null && (dumpPackage == null
15706 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15711 pw.println(" mHomeProcess: " + mHomeProcess);
15713 if (mPreviousProcess != null && (dumpPackage == null
15714 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15719 pw.println(" mPreviousProcess: " + mPreviousProcess);
15722 StringBuilder sb = new StringBuilder(128);
15723 sb.append(" mPreviousProcessVisibleTime: ");
15724 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15727 if (mHeavyWeightProcess != null && (dumpPackage == null
15728 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15733 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15735 if (dumpPackage == null) {
15736 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15737 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15740 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15741 if (mCompatModePackages.getPackages().size() > 0) {
15742 boolean printed = false;
15743 for (Map.Entry<String, Integer> entry
15744 : mCompatModePackages.getPackages().entrySet()) {
15745 String pkg = entry.getKey();
15746 int mode = entry.getValue();
15747 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15751 pw.println(" mScreenCompatPackages:");
15754 pw.print(" "); pw.print(pkg); pw.print(": ");
15755 pw.print(mode); pw.println();
15758 final int NI = mUidObservers.getRegisteredCallbackCount();
15759 boolean printed = false;
15760 for (int i=0; i<NI; i++) {
15761 final UidObserverRegistration reg = (UidObserverRegistration)
15762 mUidObservers.getRegisteredCallbackCookie(i);
15763 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15765 pw.println(" mUidObservers:");
15768 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15769 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15770 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15773 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15776 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15779 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15780 pw.print(" STATE");
15781 pw.print(" (cut="); pw.print(reg.cutpoint);
15785 if (reg.lastProcStates != null) {
15786 final int NJ = reg.lastProcStates.size();
15787 for (int j=0; j<NJ; j++) {
15788 pw.print(" Last ");
15789 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15790 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15795 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15796 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15797 if (mPendingTempWhitelist.size() > 0) {
15798 pw.println(" mPendingTempWhitelist:");
15799 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15800 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15802 UserHandle.formatUid(pw, ptw.targetUid);
15804 TimeUtils.formatDuration(ptw.duration, pw);
15806 pw.println(ptw.tag);
15810 if (dumpPackage == null) {
15811 pw.println(" mWakefulness="
15812 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15813 pw.println(" mSleepTokens=" + mSleepTokens);
15814 pw.println(" mSleeping=" + mSleeping);
15815 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15816 if (mRunningVoice != null) {
15817 pw.println(" mRunningVoice=" + mRunningVoice);
15818 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15821 pw.println(" mVrController=" + mVrController);
15822 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15823 || mOrigWaitForDebugger) {
15824 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15825 || dumpPackage.equals(mOrigDebugApp)) {
15830 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15831 + " mDebugTransient=" + mDebugTransient
15832 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15835 if (mCurAppTimeTracker != null) {
15836 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15838 if (mMemWatchProcesses.getMap().size() > 0) {
15839 pw.println(" Mem watch processes:");
15840 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15841 = mMemWatchProcesses.getMap();
15842 for (int i=0; i<procs.size(); i++) {
15843 final String proc = procs.keyAt(i);
15844 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15845 for (int j=0; j<uids.size(); j++) {
15850 StringBuilder sb = new StringBuilder();
15851 sb.append(" ").append(proc).append('/');
15852 UserHandle.formatUid(sb, uids.keyAt(j));
15853 Pair<Long, String> val = uids.valueAt(j);
15854 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15855 if (val.second != null) {
15856 sb.append(", report to ").append(val.second);
15858 pw.println(sb.toString());
15861 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15862 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15863 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15864 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15866 if (mTrackAllocationApp != null) {
15867 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15872 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15875 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15876 || mProfileFd != null) {
15877 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15882 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15883 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15884 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15885 + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15886 pw.println(" mProfileType=" + mProfileType);
15889 if (mNativeDebuggingApp != null) {
15890 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15895 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
15898 if (dumpPackage == null) {
15899 if (mAlwaysFinishActivities) {
15900 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15902 if (mController != null) {
15903 pw.println(" mController=" + mController
15904 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15907 pw.println(" Total persistent processes: " + numPers);
15908 pw.println(" mProcessesReady=" + mProcessesReady
15909 + " mSystemReady=" + mSystemReady
15910 + " mBooted=" + mBooted
15911 + " mFactoryTest=" + mFactoryTest);
15912 pw.println(" mBooting=" + mBooting
15913 + " mCallFinishBooting=" + mCallFinishBooting
15914 + " mBootAnimationComplete=" + mBootAnimationComplete);
15915 pw.print(" mLastPowerCheckRealtime=");
15916 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15918 pw.print(" mLastPowerCheckUptime=");
15919 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15921 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15922 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15923 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15924 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
15925 + " (" + mLruProcesses.size() + " total)"
15926 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15927 + " mNumServiceProcs=" + mNumServiceProcs
15928 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15929 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
15930 + " mLastMemoryLevel=" + mLastMemoryLevel
15931 + " mLastNumProcesses=" + mLastNumProcesses);
15932 long now = SystemClock.uptimeMillis();
15933 pw.print(" mLastIdleTime=");
15934 TimeUtils.formatDuration(now, mLastIdleTime, pw);
15935 pw.print(" mLowRamSinceLastIdle=");
15936 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15941 if (!printedAnything) {
15942 pw.println(" (nothing)");
15946 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15947 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15948 if (mProcessesToGc.size() > 0) {
15949 boolean printed = false;
15950 long now = SystemClock.uptimeMillis();
15951 for (int i=0; i<mProcessesToGc.size(); i++) {
15952 ProcessRecord proc = mProcessesToGc.get(i);
15953 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15957 if (needSep) pw.println();
15959 pw.println(" Processes that are waiting to GC:");
15962 pw.print(" Process "); pw.println(proc);
15963 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
15964 pw.print(", last gced=");
15965 pw.print(now-proc.lastRequestedGc);
15966 pw.print(" ms ago, last lowMem=");
15967 pw.print(now-proc.lastLowMemory);
15968 pw.println(" ms ago");
15975 void printOomLevel(PrintWriter pw, String name, int adj) {
15979 if (adj < 10) pw.print(' ');
15981 if (adj > -10) pw.print(' ');
15987 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15991 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15992 int opti, boolean dumpAll) {
15993 boolean needSep = false;
15995 if (mLruProcesses.size() > 0) {
15996 if (needSep) pw.println();
15998 pw.println(" OOM levels:");
15999 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16000 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16001 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16002 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16003 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16004 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16005 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16006 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16007 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16008 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16009 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16010 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16011 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16012 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16014 if (needSep) pw.println();
16015 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16016 pw.print(" total, non-act at ");
16017 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16018 pw.print(", non-svc at ");
16019 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16021 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16025 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16028 pw.println(" mHomeProcess: " + mHomeProcess);
16029 pw.println(" mPreviousProcess: " + mPreviousProcess);
16030 if (mHeavyWeightProcess != null) {
16031 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16038 * There are three ways to call this:
16039 * - no provider specified: dump all the providers
16040 * - a flattened component name that matched an existing provider was specified as the
16041 * first arg: dump that one provider
16042 * - the first arg isn't the flattened component name of an existing provider:
16043 * dump all providers whose component contains the first arg as a substring
16045 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16046 int opti, boolean dumpAll) {
16047 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16050 static class ItemMatcher {
16051 ArrayList<ComponentName> components;
16052 ArrayList<String> strings;
16053 ArrayList<Integer> objects;
16060 void build(String name) {
16061 ComponentName componentName = ComponentName.unflattenFromString(name);
16062 if (componentName != null) {
16063 if (components == null) {
16064 components = new ArrayList<ComponentName>();
16066 components.add(componentName);
16070 // Not a '/' separated full component name; maybe an object ID?
16072 objectId = Integer.parseInt(name, 16);
16073 if (objects == null) {
16074 objects = new ArrayList<Integer>();
16076 objects.add(objectId);
16078 } catch (RuntimeException e) {
16079 // Not an integer; just do string match.
16080 if (strings == null) {
16081 strings = new ArrayList<String>();
16089 int build(String[] args, int opti) {
16090 for (; opti<args.length; opti++) {
16091 String name = args[opti];
16092 if ("--".equals(name)) {
16100 boolean match(Object object, ComponentName comp) {
16104 if (components != null) {
16105 for (int i=0; i<components.size(); i++) {
16106 if (components.get(i).equals(comp)) {
16111 if (objects != null) {
16112 for (int i=0; i<objects.size(); i++) {
16113 if (System.identityHashCode(object) == objects.get(i)) {
16118 if (strings != null) {
16119 String flat = comp.flattenToString();
16120 for (int i=0; i<strings.size(); i++) {
16121 if (flat.contains(strings.get(i))) {
16131 * There are three things that cmd can be:
16132 * - a flattened component name that matches an existing activity
16133 * - the cmd arg isn't the flattened component name of an existing activity:
16134 * dump all activity whose component contains the cmd as a substring
16135 * - A hex number of the ActivityRecord object instance.
16137 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16138 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16140 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16141 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16142 ArrayList<ActivityRecord> activities;
16144 synchronized (this) {
16145 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16146 dumpFocusedStackOnly);
16149 if (activities.size() <= 0) {
16153 String[] newArgs = new String[args.length - opti];
16154 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16156 TaskRecord lastTask = null;
16157 boolean needSep = false;
16158 for (int i=activities.size()-1; i>=0; i--) {
16159 ActivityRecord r = activities.get(i);
16164 synchronized (this) {
16165 final TaskRecord task = r.getTask();
16166 if (lastTask != task) {
16168 pw.print("TASK "); pw.print(lastTask.affinity);
16169 pw.print(" id="); pw.print(lastTask.taskId);
16170 pw.print(" userId="); pw.println(lastTask.userId);
16172 lastTask.dump(pw, " ");
16176 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16182 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16183 * there is a thread associated with the activity.
16185 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16186 final ActivityRecord r, String[] args, boolean dumpAll) {
16187 String innerPrefix = prefix + " ";
16188 synchronized (this) {
16189 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16190 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16192 if (r.app != null) pw.println(r.app.pid);
16193 else pw.println("(not running)");
16195 r.dump(pw, innerPrefix);
16198 if (r.app != null && r.app.thread != null) {
16199 // flush anything that is already in the PrintWriter since the thread is going
16200 // to write to the file descriptor directly
16203 TransferPipe tp = new TransferPipe();
16205 r.app.thread.dumpActivity(tp.getWriteFd(),
16206 r.appToken, innerPrefix, args);
16211 } catch (IOException e) {
16212 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16213 } catch (RemoteException e) {
16214 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16219 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16220 int opti, boolean dumpAll, String dumpPackage) {
16221 boolean needSep = false;
16222 boolean onlyHistory = false;
16223 boolean printedAnything = false;
16225 if ("history".equals(dumpPackage)) {
16226 if (opti < args.length && "-s".equals(args[opti])) {
16229 onlyHistory = true;
16230 dumpPackage = null;
16233 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16234 if (!onlyHistory && dumpAll) {
16235 if (mRegisteredReceivers.size() > 0) {
16236 boolean printed = false;
16237 Iterator it = mRegisteredReceivers.values().iterator();
16238 while (it.hasNext()) {
16239 ReceiverList r = (ReceiverList)it.next();
16240 if (dumpPackage != null && (r.app == null ||
16241 !dumpPackage.equals(r.app.info.packageName))) {
16245 pw.println(" Registered Receivers:");
16248 printedAnything = true;
16250 pw.print(" * "); pw.println(r);
16255 if (mReceiverResolver.dump(pw, needSep ?
16256 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16257 " ", dumpPackage, false, false)) {
16259 printedAnything = true;
16263 for (BroadcastQueue q : mBroadcastQueues) {
16264 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16265 printedAnything |= needSep;
16270 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16271 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16276 printedAnything = true;
16277 pw.print(" Sticky broadcasts for user ");
16278 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16279 StringBuilder sb = new StringBuilder(128);
16280 for (Map.Entry<String, ArrayList<Intent>> ent
16281 : mStickyBroadcasts.valueAt(user).entrySet()) {
16282 pw.print(" * Sticky action "); pw.print(ent.getKey());
16285 ArrayList<Intent> intents = ent.getValue();
16286 final int N = intents.size();
16287 for (int i=0; i<N; i++) {
16289 sb.append(" Intent: ");
16290 intents.get(i).toShortString(sb, false, true, false, false);
16291 pw.println(sb.toString());
16292 Bundle bundle = intents.get(i).getExtras();
16293 if (bundle != null) {
16295 pw.println(bundle.toString());
16305 if (!onlyHistory && dumpAll) {
16307 for (BroadcastQueue queue : mBroadcastQueues) {
16308 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16309 + queue.mBroadcastsScheduled);
16311 pw.println(" mHandler:");
16312 mHandler.dump(new PrintWriterPrinter(pw), " ");
16314 printedAnything = true;
16317 if (!printedAnything) {
16318 pw.println(" (nothing)");
16322 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16323 int opti, boolean dumpAll, String dumpPackage) {
16324 if (mCurBroadcastStats == null) {
16328 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16329 final long now = SystemClock.elapsedRealtime();
16330 if (mLastBroadcastStats != null) {
16331 pw.print(" Last stats (from ");
16332 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16334 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16336 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16337 - mLastBroadcastStats.mStartUptime, pw);
16338 pw.println(" uptime):");
16339 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16340 pw.println(" (nothing)");
16344 pw.print(" Current stats (from ");
16345 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16346 pw.print(" to now, ");
16347 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16348 - mCurBroadcastStats.mStartUptime, pw);
16349 pw.println(" uptime):");
16350 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16351 pw.println(" (nothing)");
16355 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16356 int opti, boolean fullCheckin, String dumpPackage) {
16357 if (mCurBroadcastStats == null) {
16361 if (mLastBroadcastStats != null) {
16362 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16364 mLastBroadcastStats = null;
16368 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16370 mCurBroadcastStats = null;
16374 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16375 int opti, boolean dumpAll, String dumpPackage) {
16377 boolean printedAnything = false;
16379 ItemMatcher matcher = new ItemMatcher();
16380 matcher.build(args, opti);
16382 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16384 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16385 printedAnything |= needSep;
16387 if (mLaunchingProviders.size() > 0) {
16388 boolean printed = false;
16389 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16390 ContentProviderRecord r = mLaunchingProviders.get(i);
16391 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16395 if (needSep) pw.println();
16397 pw.println(" Launching content providers:");
16399 printedAnything = true;
16401 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16406 if (!printedAnything) {
16407 pw.println(" (nothing)");
16411 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16412 int opti, boolean dumpAll, String dumpPackage) {
16413 boolean needSep = false;
16414 boolean printedAnything = false;
16416 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16418 if (mGrantedUriPermissions.size() > 0) {
16419 boolean printed = false;
16421 if (dumpPackage != null) {
16423 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16424 MATCH_ANY_USER, 0);
16425 } catch (NameNotFoundException e) {
16429 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16430 int uid = mGrantedUriPermissions.keyAt(i);
16431 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16434 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16436 if (needSep) pw.println();
16438 pw.println(" Granted Uri Permissions:");
16440 printedAnything = true;
16442 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16443 for (UriPermission perm : perms.values()) {
16444 pw.print(" "); pw.println(perm);
16446 perm.dump(pw, " ");
16452 if (!printedAnything) {
16453 pw.println(" (nothing)");
16457 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16458 int opti, boolean dumpAll, String dumpPackage) {
16459 boolean printed = false;
16461 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16463 if (mIntentSenderRecords.size() > 0) {
16464 // Organize these by package name, so they are easier to read.
16465 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16466 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16467 final Iterator<WeakReference<PendingIntentRecord>> it
16468 = mIntentSenderRecords.values().iterator();
16469 while (it.hasNext()) {
16470 WeakReference<PendingIntentRecord> ref = it.next();
16471 PendingIntentRecord rec = ref != null ? ref.get() : null;
16476 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16479 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16480 if (list == null) {
16481 list = new ArrayList<>();
16482 byPackage.put(rec.key.packageName, list);
16486 for (int i = 0; i < byPackage.size(); i++) {
16487 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16489 pw.print(" * "); pw.print(byPackage.keyAt(i));
16490 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16491 for (int j = 0; j < intents.size(); j++) {
16492 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16494 intents.get(j).dump(pw, " ");
16498 if (weakRefs.size() > 0) {
16500 pw.println(" * WEAK REFS:");
16501 for (int i = 0; i < weakRefs.size(); i++) {
16502 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16508 pw.println(" (nothing)");
16512 private static final int dumpProcessList(PrintWriter pw,
16513 ActivityManagerService service, List list,
16514 String prefix, String normalLabel, String persistentLabel,
16515 String dumpPackage) {
16517 final int N = list.size()-1;
16518 for (int i=N; i>=0; i--) {
16519 ProcessRecord r = (ProcessRecord)list.get(i);
16520 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16523 pw.println(String.format("%s%s #%2d: %s",
16524 prefix, (r.persistent ? persistentLabel : normalLabel),
16526 if (r.persistent) {
16533 private static final boolean dumpProcessOomList(PrintWriter pw,
16534 ActivityManagerService service, List<ProcessRecord> origList,
16535 String prefix, String normalLabel, String persistentLabel,
16536 boolean inclDetails, String dumpPackage) {
16538 ArrayList<Pair<ProcessRecord, Integer>> list
16539 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16540 for (int i=0; i<origList.size(); i++) {
16541 ProcessRecord r = origList.get(i);
16542 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16545 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16548 if (list.size() <= 0) {
16552 Comparator<Pair<ProcessRecord, Integer>> comparator
16553 = new Comparator<Pair<ProcessRecord, Integer>>() {
16555 public int compare(Pair<ProcessRecord, Integer> object1,
16556 Pair<ProcessRecord, Integer> object2) {
16557 if (object1.first.setAdj != object2.first.setAdj) {
16558 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16560 if (object1.first.setProcState != object2.first.setProcState) {
16561 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16563 if (object1.second.intValue() != object2.second.intValue()) {
16564 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16570 Collections.sort(list, comparator);
16572 final long curRealtime = SystemClock.elapsedRealtime();
16573 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16574 final long curUptime = SystemClock.uptimeMillis();
16575 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16577 for (int i=list.size()-1; i>=0; i--) {
16578 ProcessRecord r = list.get(i).first;
16579 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16581 switch (r.setSchedGroup) {
16582 case ProcessList.SCHED_GROUP_BACKGROUND:
16585 case ProcessList.SCHED_GROUP_DEFAULT:
16588 case ProcessList.SCHED_GROUP_TOP_APP:
16596 if (r.foregroundActivities) {
16598 } else if (r.foregroundServices) {
16603 String procState = ProcessList.makeProcStateString(r.curProcState);
16605 pw.print(r.persistent ? persistentLabel : normalLabel);
16607 int num = (origList.size()-1)-list.get(i).second;
16608 if (num < 10) pw.print(' ');
16613 pw.print(schedGroup);
16615 pw.print(foreground);
16617 pw.print(procState);
16619 if (r.trimMemoryLevel < 10) pw.print(' ');
16620 pw.print(r.trimMemoryLevel);
16622 pw.print(r.toShortString());
16624 pw.print(r.adjType);
16626 if (r.adjSource != null || r.adjTarget != null) {
16629 if (r.adjTarget instanceof ComponentName) {
16630 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16631 } else if (r.adjTarget != null) {
16632 pw.print(r.adjTarget.toString());
16634 pw.print("{null}");
16637 if (r.adjSource instanceof ProcessRecord) {
16639 pw.print(((ProcessRecord)r.adjSource).toShortString());
16641 } else if (r.adjSource != null) {
16642 pw.println(r.adjSource.toString());
16644 pw.println("{null}");
16650 pw.print("oom: max="); pw.print(r.maxAdj);
16651 pw.print(" curRaw="); pw.print(r.curRawAdj);
16652 pw.print(" setRaw="); pw.print(r.setRawAdj);
16653 pw.print(" cur="); pw.print(r.curAdj);
16654 pw.print(" set="); pw.println(r.setAdj);
16657 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16658 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16659 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16660 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16661 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16665 pw.print("cached="); pw.print(r.cached);
16666 pw.print(" empty="); pw.print(r.empty);
16667 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16669 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16670 if (r.lastWakeTime != 0) {
16672 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16673 synchronized (stats) {
16674 wtime = stats.getProcessWakeTime(r.info.uid,
16675 r.pid, curRealtime);
16677 long timeUsed = wtime - r.lastWakeTime;
16680 pw.print("keep awake over ");
16681 TimeUtils.formatDuration(realtimeSince, pw);
16682 pw.print(" used ");
16683 TimeUtils.formatDuration(timeUsed, pw);
16685 pw.print((timeUsed*100)/realtimeSince);
16688 if (r.lastCpuTime != 0) {
16689 long timeUsed = r.curCpuTime - r.lastCpuTime;
16692 pw.print("run cpu over ");
16693 TimeUtils.formatDuration(uptimeSince, pw);
16694 pw.print(" used ");
16695 TimeUtils.formatDuration(timeUsed, pw);
16697 pw.print((timeUsed*100)/uptimeSince);
16706 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16708 ArrayList<ProcessRecord> procs;
16709 synchronized (this) {
16710 if (args != null && args.length > start
16711 && args[start].charAt(0) != '-') {
16712 procs = new ArrayList<ProcessRecord>();
16715 pid = Integer.parseInt(args[start]);
16716 } catch (NumberFormatException e) {
16718 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16719 ProcessRecord proc = mLruProcesses.get(i);
16720 if (proc.pid == pid) {
16722 } else if (allPkgs && proc.pkgList != null
16723 && proc.pkgList.containsKey(args[start])) {
16725 } else if (proc.processName.equals(args[start])) {
16729 if (procs.size() <= 0) {
16733 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16739 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16740 PrintWriter pw, String[] args) {
16741 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16742 if (procs == null) {
16743 pw.println("No process found for: " + args[0]);
16747 long uptime = SystemClock.uptimeMillis();
16748 long realtime = SystemClock.elapsedRealtime();
16749 pw.println("Applications Graphics Acceleration Info:");
16750 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16752 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16753 ProcessRecord r = procs.get(i);
16754 if (r.thread != null) {
16755 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16758 TransferPipe tp = new TransferPipe();
16760 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16765 } catch (IOException e) {
16766 pw.println("Failure while dumping the app: " + r);
16768 } catch (RemoteException e) {
16769 pw.println("Got a RemoteException while dumping the app " + r);
16776 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16777 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16778 if (procs == null) {
16779 pw.println("No process found for: " + args[0]);
16783 pw.println("Applications Database Info:");
16785 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16786 ProcessRecord r = procs.get(i);
16787 if (r.thread != null) {
16788 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16791 TransferPipe tp = new TransferPipe();
16793 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16798 } catch (IOException e) {
16799 pw.println("Failure while dumping the app: " + r);
16801 } catch (RemoteException e) {
16802 pw.println("Got a RemoteException while dumping the app " + r);
16809 final static class MemItem {
16810 final boolean isProc;
16811 final String label;
16812 final String shortLabel;
16814 final long swapPss;
16816 final boolean hasActivities;
16817 ArrayList<MemItem> subitems;
16819 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16820 boolean _hasActivities) {
16823 shortLabel = _shortLabel;
16825 swapPss = _swapPss;
16827 hasActivities = _hasActivities;
16830 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16833 shortLabel = _shortLabel;
16835 swapPss = _swapPss;
16837 hasActivities = false;
16841 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16842 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16843 if (sort && !isCompact) {
16844 Collections.sort(items, new Comparator<MemItem>() {
16846 public int compare(MemItem lhs, MemItem rhs) {
16847 if (lhs.pss < rhs.pss) {
16849 } else if (lhs.pss > rhs.pss) {
16857 for (int i=0; i<items.size(); i++) {
16858 MemItem mi = items.get(i);
16861 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16862 mi.label, stringifyKBSize(mi.swapPss));
16864 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16866 } else if (mi.isProc) {
16867 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16868 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16869 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16870 pw.println(mi.hasActivities ? ",a" : ",e");
16872 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16873 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16875 if (mi.subitems != null) {
16876 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16877 true, isCompact, dumpSwapPss);
16882 // These are in KB.
16883 static final long[] DUMP_MEM_BUCKETS = new long[] {
16884 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16885 120*1024, 160*1024, 200*1024,
16886 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16887 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16890 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16891 boolean stackLike) {
16892 int start = label.lastIndexOf('.');
16893 if (start >= 0) start++;
16895 int end = label.length();
16896 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16897 if (DUMP_MEM_BUCKETS[i] >= memKB) {
16898 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16899 out.append(bucket);
16900 out.append(stackLike ? "MB." : "MB ");
16901 out.append(label, start, end);
16905 out.append(memKB/1024);
16906 out.append(stackLike ? "MB." : "MB ");
16907 out.append(label, start, end);
16910 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16911 ProcessList.NATIVE_ADJ,
16912 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16913 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16914 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16915 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16916 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16917 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16919 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16921 "System", "Persistent", "Persistent Service", "Foreground",
16922 "Visible", "Perceptible",
16923 "Heavy Weight", "Backup",
16924 "A Services", "Home",
16925 "Previous", "B Services", "Cached"
16927 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16929 "sys", "pers", "persvc", "fore",
16932 "servicea", "home",
16933 "prev", "serviceb", "cached"
16936 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16937 long realtime, boolean isCheckinRequest, boolean isCompact) {
16939 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16941 if (isCheckinRequest || isCompact) {
16942 // short checkin version
16943 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16945 pw.println("Applications Memory Usage (in Kilobytes):");
16946 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16950 private static final int KSM_SHARED = 0;
16951 private static final int KSM_SHARING = 1;
16952 private static final int KSM_UNSHARED = 2;
16953 private static final int KSM_VOLATILE = 3;
16955 private final long[] getKsmInfo() {
16956 long[] longOut = new long[4];
16957 final int[] SINGLE_LONG_FORMAT = new int[] {
16958 PROC_SPACE_TERM| PROC_OUT_LONG
16960 long[] longTmp = new long[1];
16961 readProcFile("/sys/kernel/mm/ksm/pages_shared",
16962 SINGLE_LONG_FORMAT, null, longTmp, null);
16963 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16965 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16966 SINGLE_LONG_FORMAT, null, longTmp, null);
16967 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16969 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16970 SINGLE_LONG_FORMAT, null, longTmp, null);
16971 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16973 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16974 SINGLE_LONG_FORMAT, null, longTmp, null);
16975 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16979 private static String stringifySize(long size, int order) {
16980 Locale locale = Locale.US;
16983 return String.format(locale, "%,13d", size);
16985 return String.format(locale, "%,9dK", size / 1024);
16987 return String.format(locale, "%,5dM", size / 1024 / 1024);
16988 case 1024 * 1024 * 1024:
16989 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16991 throw new IllegalArgumentException("Invalid size order");
16995 private static String stringifyKBSize(long size) {
16996 return stringifySize(size * 1024, 1024);
16999 // Update this version number in case you change the 'compact' format
17000 private static final int MEMINFO_COMPACT_VERSION = 1;
17002 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17003 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17004 boolean dumpDetails = false;
17005 boolean dumpFullDetails = false;
17006 boolean dumpDalvik = false;
17007 boolean dumpSummaryOnly = false;
17008 boolean dumpUnreachable = false;
17009 boolean oomOnly = false;
17010 boolean isCompact = false;
17011 boolean localOnly = false;
17012 boolean packages = false;
17013 boolean isCheckinRequest = false;
17014 boolean dumpSwapPss = false;
17017 while (opti < args.length) {
17018 String opt = args[opti];
17019 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17023 if ("-a".equals(opt)) {
17024 dumpDetails = true;
17025 dumpFullDetails = true;
17027 dumpSwapPss = true;
17028 } else if ("-d".equals(opt)) {
17030 } else if ("-c".equals(opt)) {
17032 } else if ("-s".equals(opt)) {
17033 dumpDetails = true;
17034 dumpSummaryOnly = true;
17035 } else if ("-S".equals(opt)) {
17036 dumpSwapPss = true;
17037 } else if ("--unreachable".equals(opt)) {
17038 dumpUnreachable = true;
17039 } else if ("--oom".equals(opt)) {
17041 } else if ("--local".equals(opt)) {
17043 } else if ("--package".equals(opt)) {
17045 } else if ("--checkin".equals(opt)) {
17046 isCheckinRequest = true;
17048 } else if ("-h".equals(opt)) {
17049 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17050 pw.println(" -a: include all available information for each process.");
17051 pw.println(" -d: include dalvik details.");
17052 pw.println(" -c: dump in a compact machine-parseable representation.");
17053 pw.println(" -s: dump only summary of application memory usage.");
17054 pw.println(" -S: dump also SwapPss.");
17055 pw.println(" --oom: only show processes organized by oom adj.");
17056 pw.println(" --local: only collect details locally, don't call process.");
17057 pw.println(" --package: interpret process arg as package, dumping all");
17058 pw.println(" processes that have loaded that package.");
17059 pw.println(" --checkin: dump data for a checkin");
17060 pw.println("If [process] is specified it can be the name or ");
17061 pw.println("pid of a specific process to dump.");
17064 pw.println("Unknown argument: " + opt + "; use -h for help");
17068 long uptime = SystemClock.uptimeMillis();
17069 long realtime = SystemClock.elapsedRealtime();
17070 final long[] tmpLong = new long[1];
17072 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17073 if (procs == null) {
17074 // No Java processes. Maybe they want to print a native process.
17075 if (args != null && args.length > opti
17076 && args[opti].charAt(0) != '-') {
17077 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17078 = new ArrayList<ProcessCpuTracker.Stats>();
17079 updateCpuStatsNow();
17082 findPid = Integer.parseInt(args[opti]);
17083 } catch (NumberFormatException e) {
17085 synchronized (mProcessCpuTracker) {
17086 final int N = mProcessCpuTracker.countStats();
17087 for (int i=0; i<N; i++) {
17088 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17089 if (st.pid == findPid || (st.baseName != null
17090 && st.baseName.equals(args[opti]))) {
17091 nativeProcs.add(st);
17095 if (nativeProcs.size() > 0) {
17096 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17098 Debug.MemoryInfo mi = null;
17099 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17100 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17101 final int pid = r.pid;
17102 if (!isCheckinRequest && dumpDetails) {
17103 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17106 mi = new Debug.MemoryInfo();
17108 if (dumpDetails || (!brief && !oomOnly)) {
17109 Debug.getMemoryInfo(pid, mi);
17111 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17112 mi.dalvikPrivateDirty = (int)tmpLong[0];
17114 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17115 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17116 if (isCheckinRequest) {
17123 pw.println("No process found for: " + args[opti]);
17127 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17128 dumpDetails = true;
17131 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17133 String[] innerArgs = new String[args.length-opti];
17134 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17136 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17137 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17138 long nativePss = 0;
17139 long nativeSwapPss = 0;
17140 long dalvikPss = 0;
17141 long dalvikSwapPss = 0;
17142 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17144 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17147 long otherSwapPss = 0;
17148 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17149 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17151 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17152 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17153 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17154 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17157 long totalSwapPss = 0;
17158 long cachedPss = 0;
17159 long cachedSwapPss = 0;
17160 boolean hasSwapPss = false;
17162 Debug.MemoryInfo mi = null;
17163 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17164 final ProcessRecord r = procs.get(i);
17165 final IApplicationThread thread;
17168 final boolean hasActivities;
17169 synchronized (this) {
17172 oomAdj = r.getSetAdjWithServices();
17173 hasActivities = r.activities.size() > 0;
17175 if (thread != null) {
17176 if (!isCheckinRequest && dumpDetails) {
17177 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17180 mi = new Debug.MemoryInfo();
17182 if (dumpDetails || (!brief && !oomOnly)) {
17183 Debug.getMemoryInfo(pid, mi);
17184 hasSwapPss = mi.hasSwappedOutPss;
17186 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17187 mi.dalvikPrivateDirty = (int)tmpLong[0];
17191 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17192 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17193 if (isCheckinRequest) {
17199 TransferPipe tp = new TransferPipe();
17201 thread.dumpMemInfo(tp.getWriteFd(),
17202 mi, isCheckinRequest, dumpFullDetails,
17203 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17208 } catch (IOException e) {
17209 if (!isCheckinRequest) {
17210 pw.println("Got IoException!");
17213 } catch (RemoteException e) {
17214 if (!isCheckinRequest) {
17215 pw.println("Got RemoteException!");
17222 final long myTotalPss = mi.getTotalPss();
17223 final long myTotalUss = mi.getTotalUss();
17224 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17226 synchronized (this) {
17227 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17228 // Record this for posterity if the process has been stable.
17229 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17233 if (!isCheckinRequest && mi != null) {
17234 totalPss += myTotalPss;
17235 totalSwapPss += myTotalSwapPss;
17236 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17237 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17238 myTotalSwapPss, pid, hasActivities);
17239 procMems.add(pssItem);
17240 procMemsMap.put(pid, pssItem);
17242 nativePss += mi.nativePss;
17243 nativeSwapPss += mi.nativeSwappedOutPss;
17244 dalvikPss += mi.dalvikPss;
17245 dalvikSwapPss += mi.dalvikSwappedOutPss;
17246 for (int j=0; j<dalvikSubitemPss.length; j++) {
17247 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17248 dalvikSubitemSwapPss[j] +=
17249 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17251 otherPss += mi.otherPss;
17252 otherSwapPss += mi.otherSwappedOutPss;
17253 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17254 long mem = mi.getOtherPss(j);
17257 mem = mi.getOtherSwappedOutPss(j);
17258 miscSwapPss[j] += mem;
17259 otherSwapPss -= mem;
17262 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17263 cachedPss += myTotalPss;
17264 cachedSwapPss += myTotalSwapPss;
17267 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17268 if (oomIndex == (oomPss.length - 1)
17269 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17270 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17271 oomPss[oomIndex] += myTotalPss;
17272 oomSwapPss[oomIndex] += myTotalSwapPss;
17273 if (oomProcs[oomIndex] == null) {
17274 oomProcs[oomIndex] = new ArrayList<MemItem>();
17276 oomProcs[oomIndex].add(pssItem);
17284 long nativeProcTotalPss = 0;
17286 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17287 // If we are showing aggregations, also look for native processes to
17288 // include so that our aggregations are more accurate.
17289 updateCpuStatsNow();
17291 synchronized (mProcessCpuTracker) {
17292 final int N = mProcessCpuTracker.countStats();
17293 for (int i=0; i<N; i++) {
17294 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17295 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17297 mi = new Debug.MemoryInfo();
17299 if (!brief && !oomOnly) {
17300 Debug.getMemoryInfo(st.pid, mi);
17302 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17303 mi.nativePrivateDirty = (int)tmpLong[0];
17306 final long myTotalPss = mi.getTotalPss();
17307 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17308 totalPss += myTotalPss;
17309 nativeProcTotalPss += myTotalPss;
17311 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17312 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17313 procMems.add(pssItem);
17315 nativePss += mi.nativePss;
17316 nativeSwapPss += mi.nativeSwappedOutPss;
17317 dalvikPss += mi.dalvikPss;
17318 dalvikSwapPss += mi.dalvikSwappedOutPss;
17319 for (int j=0; j<dalvikSubitemPss.length; j++) {
17320 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17321 dalvikSubitemSwapPss[j] +=
17322 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17324 otherPss += mi.otherPss;
17325 otherSwapPss += mi.otherSwappedOutPss;
17326 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17327 long mem = mi.getOtherPss(j);
17330 mem = mi.getOtherSwappedOutPss(j);
17331 miscSwapPss[j] += mem;
17332 otherSwapPss -= mem;
17334 oomPss[0] += myTotalPss;
17335 oomSwapPss[0] += myTotalSwapPss;
17336 if (oomProcs[0] == null) {
17337 oomProcs[0] = new ArrayList<MemItem>();
17339 oomProcs[0].add(pssItem);
17344 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17346 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17347 final MemItem dalvikItem =
17348 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17349 if (dalvikSubitemPss.length > 0) {
17350 dalvikItem.subitems = new ArrayList<MemItem>();
17351 for (int j=0; j<dalvikSubitemPss.length; j++) {
17352 final String name = Debug.MemoryInfo.getOtherLabel(
17353 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17354 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17355 dalvikSubitemSwapPss[j], j));
17358 catMems.add(dalvikItem);
17359 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17360 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17361 String label = Debug.MemoryInfo.getOtherLabel(j);
17362 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17365 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17366 for (int j=0; j<oomPss.length; j++) {
17367 if (oomPss[j] != 0) {
17368 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17369 : DUMP_MEM_OOM_LABEL[j];
17370 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17371 DUMP_MEM_OOM_ADJ[j]);
17372 item.subitems = oomProcs[j];
17377 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17378 if (!brief && !oomOnly && !isCompact) {
17380 pw.println("Total PSS by process:");
17381 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17385 pw.println("Total PSS by OOM adjustment:");
17387 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17388 if (!brief && !oomOnly) {
17389 PrintWriter out = categoryPw != null ? categoryPw : pw;
17392 out.println("Total PSS by category:");
17394 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17399 MemInfoReader memInfo = new MemInfoReader();
17400 memInfo.readMemInfo();
17401 if (nativeProcTotalPss > 0) {
17402 synchronized (this) {
17403 final long cachedKb = memInfo.getCachedSizeKb();
17404 final long freeKb = memInfo.getFreeSizeKb();
17405 final long zramKb = memInfo.getZramTotalSizeKb();
17406 final long kernelKb = memInfo.getKernelUsedSizeKb();
17407 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17408 kernelKb*1024, nativeProcTotalPss*1024);
17409 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17410 nativeProcTotalPss);
17415 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17416 pw.print(" (status ");
17417 switch (mLastMemoryLevel) {
17418 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17419 pw.println("normal)");
17421 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17422 pw.println("moderate)");
17424 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17425 pw.println("low)");
17427 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17428 pw.println("critical)");
17431 pw.print(mLastMemoryLevel);
17435 pw.print(" Free RAM: ");
17436 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17437 + memInfo.getFreeSizeKb()));
17439 pw.print(stringifyKBSize(cachedPss));
17440 pw.print(" cached pss + ");
17441 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17442 pw.print(" cached kernel + ");
17443 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17444 pw.println(" free)");
17446 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17447 pw.print(cachedPss + memInfo.getCachedSizeKb()
17448 + memInfo.getFreeSizeKb()); pw.print(",");
17449 pw.println(totalPss - cachedPss);
17452 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17453 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17454 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17456 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17457 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17458 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17459 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17460 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17462 pw.print("lostram,"); pw.println(lostRAM);
17465 if (memInfo.getZramTotalSizeKb() != 0) {
17467 pw.print(" ZRAM: ");
17468 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17469 pw.print(" physical used for ");
17470 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17471 - memInfo.getSwapFreeSizeKb()));
17472 pw.print(" in swap (");
17473 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17474 pw.println(" total swap)");
17476 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17477 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17478 pw.println(memInfo.getSwapFreeSizeKb());
17481 final long[] ksm = getKsmInfo();
17483 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17484 || ksm[KSM_VOLATILE] != 0) {
17485 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17486 pw.print(" saved from shared ");
17487 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17488 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17489 pw.print(" unshared; ");
17490 pw.print(stringifyKBSize(
17491 ksm[KSM_VOLATILE])); pw.println(" volatile");
17493 pw.print(" Tuning: ");
17494 pw.print(ActivityManager.staticGetMemoryClass());
17495 pw.print(" (large ");
17496 pw.print(ActivityManager.staticGetLargeMemoryClass());
17497 pw.print("), oom ");
17498 pw.print(stringifySize(
17499 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17500 pw.print(", restore limit ");
17501 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17502 if (ActivityManager.isLowRamDeviceStatic()) {
17503 pw.print(" (low-ram)");
17505 if (ActivityManager.isHighEndGfx()) {
17506 pw.print(" (high-end-gfx)");
17510 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17511 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17512 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17513 pw.print("tuning,");
17514 pw.print(ActivityManager.staticGetMemoryClass());
17516 pw.print(ActivityManager.staticGetLargeMemoryClass());
17518 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17519 if (ActivityManager.isLowRamDeviceStatic()) {
17520 pw.print(",low-ram");
17522 if (ActivityManager.isHighEndGfx()) {
17523 pw.print(",high-end-gfx");
17531 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17532 long memtrack, String name) {
17534 sb.append(ProcessList.makeOomAdjString(oomAdj));
17536 sb.append(ProcessList.makeProcStateString(procState));
17538 ProcessList.appendRamKb(sb, pss);
17541 if (memtrack > 0) {
17543 sb.append(stringifyKBSize(memtrack));
17544 sb.append(" memtrack)");
17548 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17549 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17550 sb.append(" (pid ");
17553 sb.append(mi.adjType);
17555 if (mi.adjReason != null) {
17557 sb.append(mi.adjReason);
17562 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17563 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17564 for (int i=0, N=memInfos.size(); i<N; i++) {
17565 ProcessMemInfo mi = memInfos.get(i);
17566 infoMap.put(mi.pid, mi);
17568 updateCpuStatsNow();
17569 long[] memtrackTmp = new long[1];
17570 final List<ProcessCpuTracker.Stats> stats;
17571 // Get a list of Stats that have vsize > 0
17572 synchronized (mProcessCpuTracker) {
17573 stats = mProcessCpuTracker.getStats((st) -> {
17574 return st.vsize > 0;
17577 final int statsCount = stats.size();
17578 for (int i = 0; i < statsCount; i++) {
17579 ProcessCpuTracker.Stats st = stats.get(i);
17580 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17582 if (infoMap.indexOfKey(st.pid) < 0) {
17583 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17584 ProcessList.NATIVE_ADJ, -1, "native", null);
17586 mi.memtrack = memtrackTmp[0];
17593 long totalMemtrack = 0;
17594 for (int i=0, N=memInfos.size(); i<N; i++) {
17595 ProcessMemInfo mi = memInfos.get(i);
17597 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17598 mi.memtrack = memtrackTmp[0];
17600 totalPss += mi.pss;
17601 totalMemtrack += mi.memtrack;
17603 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17604 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17605 if (lhs.oomAdj != rhs.oomAdj) {
17606 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17608 if (lhs.pss != rhs.pss) {
17609 return lhs.pss < rhs.pss ? 1 : -1;
17615 StringBuilder tag = new StringBuilder(128);
17616 StringBuilder stack = new StringBuilder(128);
17617 tag.append("Low on memory -- ");
17618 appendMemBucket(tag, totalPss, "total", false);
17619 appendMemBucket(stack, totalPss, "total", true);
17621 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17622 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17623 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17625 boolean firstLine = true;
17626 int lastOomAdj = Integer.MIN_VALUE;
17627 long extraNativeRam = 0;
17628 long extraNativeMemtrack = 0;
17629 long cachedPss = 0;
17630 for (int i=0, N=memInfos.size(); i<N; i++) {
17631 ProcessMemInfo mi = memInfos.get(i);
17633 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17634 cachedPss += mi.pss;
17637 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17638 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17639 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17640 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17641 if (lastOomAdj != mi.oomAdj) {
17642 lastOomAdj = mi.oomAdj;
17643 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17646 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17651 stack.append("\n\t at ");
17659 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17660 appendMemBucket(tag, mi.pss, mi.name, false);
17662 appendMemBucket(stack, mi.pss, mi.name, true);
17663 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17664 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17666 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17667 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17668 stack.append(DUMP_MEM_OOM_LABEL[k]);
17670 stack.append(DUMP_MEM_OOM_ADJ[k]);
17677 appendMemInfo(fullNativeBuilder, mi);
17678 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17679 // The short form only has native processes that are >= 512K.
17680 if (mi.pss >= 512) {
17681 appendMemInfo(shortNativeBuilder, mi);
17683 extraNativeRam += mi.pss;
17684 extraNativeMemtrack += mi.memtrack;
17687 // Short form has all other details, but if we have collected RAM
17688 // from smaller native processes let's dump a summary of that.
17689 if (extraNativeRam > 0) {
17690 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17691 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17692 shortNativeBuilder.append('\n');
17693 extraNativeRam = 0;
17695 appendMemInfo(fullJavaBuilder, mi);
17699 fullJavaBuilder.append(" ");
17700 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17701 fullJavaBuilder.append(": TOTAL");
17702 if (totalMemtrack > 0) {
17703 fullJavaBuilder.append(" (");
17704 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17705 fullJavaBuilder.append(" memtrack)");
17708 fullJavaBuilder.append("\n");
17710 MemInfoReader memInfo = new MemInfoReader();
17711 memInfo.readMemInfo();
17712 final long[] infos = memInfo.getRawInfo();
17714 StringBuilder memInfoBuilder = new StringBuilder(1024);
17715 Debug.getMemInfo(infos);
17716 memInfoBuilder.append(" MemInfo: ");
17717 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17718 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17719 memInfoBuilder.append(stringifyKBSize(
17720 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17721 memInfoBuilder.append(stringifyKBSize(
17722 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17723 memInfoBuilder.append(stringifyKBSize(
17724 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17725 memInfoBuilder.append(" ");
17726 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17727 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17728 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17729 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17730 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17731 memInfoBuilder.append(" ZRAM: ");
17732 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17733 memInfoBuilder.append(" RAM, ");
17734 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17735 memInfoBuilder.append(" swap total, ");
17736 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17737 memInfoBuilder.append(" swap free\n");
17739 final long[] ksm = getKsmInfo();
17740 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17741 || ksm[KSM_VOLATILE] != 0) {
17742 memInfoBuilder.append(" KSM: ");
17743 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17744 memInfoBuilder.append(" saved from shared ");
17745 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17746 memInfoBuilder.append("\n ");
17747 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17748 memInfoBuilder.append(" unshared; ");
17749 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17750 memInfoBuilder.append(" volatile\n");
17752 memInfoBuilder.append(" Free RAM: ");
17753 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17754 + memInfo.getFreeSizeKb()));
17755 memInfoBuilder.append("\n");
17756 memInfoBuilder.append(" Used RAM: ");
17757 memInfoBuilder.append(stringifyKBSize(
17758 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17759 memInfoBuilder.append("\n");
17760 memInfoBuilder.append(" Lost RAM: ");
17761 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17762 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17763 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17764 memInfoBuilder.append("\n");
17765 Slog.i(TAG, "Low on memory:");
17766 Slog.i(TAG, shortNativeBuilder.toString());
17767 Slog.i(TAG, fullJavaBuilder.toString());
17768 Slog.i(TAG, memInfoBuilder.toString());
17770 StringBuilder dropBuilder = new StringBuilder(1024);
17772 StringWriter oomSw = new StringWriter();
17773 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17774 StringWriter catSw = new StringWriter();
17775 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17776 String[] emptyArgs = new String[] { };
17777 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17779 String oomString = oomSw.toString();
17781 dropBuilder.append("Low on memory:");
17782 dropBuilder.append(stack);
17783 dropBuilder.append('\n');
17784 dropBuilder.append(fullNativeBuilder);
17785 dropBuilder.append(fullJavaBuilder);
17786 dropBuilder.append('\n');
17787 dropBuilder.append(memInfoBuilder);
17788 dropBuilder.append('\n');
17790 dropBuilder.append(oomString);
17791 dropBuilder.append('\n');
17793 StringWriter catSw = new StringWriter();
17794 synchronized (ActivityManagerService.this) {
17795 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17796 String[] emptyArgs = new String[] { };
17798 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17800 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17801 false, null).dumpLocked();
17803 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17806 dropBuilder.append(catSw.toString());
17807 addErrorToDropBox("lowmem", null, "system_server", null,
17808 null, tag.toString(), dropBuilder.toString(), null, null);
17809 //Slog.i(TAG, "Sent to dropbox:");
17810 //Slog.i(TAG, dropBuilder.toString());
17811 synchronized (ActivityManagerService.this) {
17812 long now = SystemClock.uptimeMillis();
17813 if (mLastMemUsageReportTime < now) {
17814 mLastMemUsageReportTime = now;
17820 * Searches array of arguments for the specified string
17821 * @param args array of argument strings
17822 * @param value value to search for
17823 * @return true if the value is contained in the array
17825 private static boolean scanArgs(String[] args, String value) {
17826 if (args != null) {
17827 for (String arg : args) {
17828 if (value.equals(arg)) {
17836 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17837 ContentProviderRecord cpr, boolean always) {
17838 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17840 if (!inLaunching || always) {
17841 synchronized (cpr) {
17842 cpr.launchingApp = null;
17845 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17846 String names[] = cpr.info.authority.split(";");
17847 for (int j = 0; j < names.length; j++) {
17848 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17852 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17853 ContentProviderConnection conn = cpr.connections.get(i);
17854 if (conn.waiting) {
17855 // If this connection is waiting for the provider, then we don't
17856 // need to mess with its process unless we are always removing
17857 // or for some reason the provider is not currently launching.
17858 if (inLaunching && !always) {
17862 ProcessRecord capp = conn.client;
17864 if (conn.stableCount > 0) {
17865 if (!capp.persistent && capp.thread != null
17867 && capp.pid != MY_PID) {
17868 capp.kill("depends on provider "
17869 + cpr.name.flattenToShortString()
17870 + " in dying proc " + (proc != null ? proc.processName : "??")
17871 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17873 } else if (capp.thread != null && conn.provider.provider != null) {
17875 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17876 } catch (RemoteException e) {
17878 // In the protocol here, we don't expect the client to correctly
17879 // clean up this connection, we'll just remove it.
17880 cpr.connections.remove(i);
17881 if (conn.client.conProviders.remove(conn)) {
17882 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17887 if (inLaunching && always) {
17888 mLaunchingProviders.remove(cpr);
17890 return inLaunching;
17894 * Main code for cleaning up a process when it has gone away. This is
17895 * called both as a result of the process dying, or directly when stopping
17896 * a process when running in single process mode.
17898 * @return Returns true if the given process has been restarted, so the
17899 * app that was passed in must remain on the process lists.
17901 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17902 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17904 removeLruProcessLocked(app);
17905 ProcessList.remove(app.pid);
17908 mProcessesToGc.remove(app);
17909 mPendingPssProcesses.remove(app);
17911 // Dismiss any open dialogs.
17912 if (app.crashDialog != null && !app.forceCrashReport) {
17913 app.crashDialog.dismiss();
17914 app.crashDialog = null;
17916 if (app.anrDialog != null) {
17917 app.anrDialog.dismiss();
17918 app.anrDialog = null;
17920 if (app.waitDialog != null) {
17921 app.waitDialog.dismiss();
17922 app.waitDialog = null;
17925 app.crashing = false;
17926 app.notResponding = false;
17928 app.resetPackageList(mProcessStats);
17929 app.unlinkDeathRecipient();
17930 app.makeInactive(mProcessStats);
17931 app.waitingToKill = null;
17932 app.forcingToImportant = null;
17933 updateProcessForegroundLocked(app, false, false);
17934 app.foregroundActivities = false;
17935 app.hasShownUi = false;
17936 app.treatLikeActivity = false;
17937 app.hasAboveClient = false;
17938 app.hasClientActivities = false;
17940 mServices.killServicesLocked(app, allowRestart);
17942 boolean restart = false;
17944 // Remove published content providers.
17945 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17946 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17947 final boolean always = app.bad || !allowRestart;
17948 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17949 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17950 // We left the provider in the launching list, need to
17955 cpr.provider = null;
17958 app.pubProviders.clear();
17960 // Take care of any launching providers waiting for this process.
17961 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17965 // Unregister from connected content providers.
17966 if (!app.conProviders.isEmpty()) {
17967 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17968 ContentProviderConnection conn = app.conProviders.get(i);
17969 conn.provider.connections.remove(conn);
17970 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17971 conn.provider.name);
17973 app.conProviders.clear();
17976 // At this point there may be remaining entries in mLaunchingProviders
17977 // where we were the only one waiting, so they are no longer of use.
17978 // Look for these and clean up if found.
17979 // XXX Commented out for now. Trying to figure out a way to reproduce
17980 // the actual situation to identify what is actually going on.
17982 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17983 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17984 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17985 synchronized (cpr) {
17986 cpr.launchingApp = null;
17993 skipCurrentReceiverLocked(app);
17995 // Unregister any receivers.
17996 for (int i = app.receivers.size() - 1; i >= 0; i--) {
17997 removeReceiverLocked(app.receivers.valueAt(i));
17999 app.receivers.clear();
18001 // If the app is undergoing backup, tell the backup manager about it
18002 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18003 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18004 + mBackupTarget.appInfo + " died during backup");
18005 mHandler.post(new Runnable() {
18009 IBackupManager bm = IBackupManager.Stub.asInterface(
18010 ServiceManager.getService(Context.BACKUP_SERVICE));
18011 bm.agentDisconnected(app.info.packageName);
18012 } catch (RemoteException e) {
18013 // can't happen; backup manager is local
18019 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18020 ProcessChangeItem item = mPendingProcessChanges.get(i);
18021 if (item.pid == app.pid) {
18022 mPendingProcessChanges.remove(i);
18023 mAvailProcessChanges.add(item);
18026 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18027 null).sendToTarget();
18029 // If the caller is restarting this app, then leave it in its
18030 // current lists and let the caller take care of it.
18035 if (!app.persistent || app.isolated) {
18036 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18037 "Removing non-persistent process during cleanup: " + app);
18038 if (!replacingPid) {
18039 removeProcessNameLocked(app.processName, app.uid, app);
18041 if (mHeavyWeightProcess == app) {
18042 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18043 mHeavyWeightProcess.userId, 0));
18044 mHeavyWeightProcess = null;
18046 } else if (!app.removed) {
18047 // This app is persistent, so we need to keep its record around.
18048 // If it is not already on the pending app list, add it there
18049 // and start a new process for it.
18050 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18051 mPersistentStartingProcesses.add(app);
18055 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18056 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18057 mProcessesOnHold.remove(app);
18059 if (app == mHomeProcess) {
18060 mHomeProcess = null;
18062 if (app == mPreviousProcess) {
18063 mPreviousProcess = null;
18066 if (restart && !app.isolated) {
18067 // We have components that still need to be running in the
18068 // process, so re-launch it.
18070 ProcessList.remove(app.pid);
18072 addProcessNameLocked(app);
18073 startProcessLocked(app, "restart", app.processName);
18075 } else if (app.pid > 0 && app.pid != MY_PID) {
18078 synchronized (mPidsSelfLocked) {
18079 mPidsSelfLocked.remove(app.pid);
18080 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18082 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18083 if (app.isolated) {
18084 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18091 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18092 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18093 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18094 if (cpr.launchingApp == app) {
18101 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18102 // Look through the content providers we are waiting to have launched,
18103 // and if any run in this process then either schedule a restart of
18104 // the process or kill the client waiting for it if this process has
18106 boolean restart = false;
18107 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18108 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18109 if (cpr.launchingApp == app) {
18110 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18113 removeDyingProviderLocked(app, cpr, true);
18120 // =========================================================
18122 // =========================================================
18125 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18127 enforceNotIsolatedCaller("getServices");
18129 final int callingUid = Binder.getCallingUid();
18130 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18131 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18132 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18134 synchronized (this) {
18135 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18136 allowed, canInteractAcrossUsers);
18141 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18142 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18143 synchronized (this) {
18144 return mServices.getRunningServiceControlPanelLocked(name);
18149 public ComponentName startService(IApplicationThread caller, Intent service,
18150 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18151 throws TransactionTooLargeException {
18152 enforceNotIsolatedCaller("startService");
18153 // Refuse possible leaked file descriptors
18154 if (service != null && service.hasFileDescriptors() == true) {
18155 throw new IllegalArgumentException("File descriptors passed in Intent");
18158 if (callingPackage == null) {
18159 throw new IllegalArgumentException("callingPackage cannot be null");
18162 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18163 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18164 synchronized(this) {
18165 final int callingPid = Binder.getCallingPid();
18166 final int callingUid = Binder.getCallingUid();
18167 final long origId = Binder.clearCallingIdentity();
18170 res = mServices.startServiceLocked(caller, service,
18171 resolvedType, callingPid, callingUid,
18172 requireForeground, callingPackage, userId);
18174 Binder.restoreCallingIdentity(origId);
18180 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18181 boolean fgRequired, String callingPackage, int userId)
18182 throws TransactionTooLargeException {
18183 synchronized(this) {
18184 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18185 "startServiceInPackage: " + service + " type=" + resolvedType);
18186 final long origId = Binder.clearCallingIdentity();
18189 res = mServices.startServiceLocked(null, service,
18190 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18192 Binder.restoreCallingIdentity(origId);
18199 public int stopService(IApplicationThread caller, Intent service,
18200 String resolvedType, int userId) {
18201 enforceNotIsolatedCaller("stopService");
18202 // Refuse possible leaked file descriptors
18203 if (service != null && service.hasFileDescriptors() == true) {
18204 throw new IllegalArgumentException("File descriptors passed in Intent");
18207 synchronized(this) {
18208 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18213 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18214 enforceNotIsolatedCaller("peekService");
18215 // Refuse possible leaked file descriptors
18216 if (service != null && service.hasFileDescriptors() == true) {
18217 throw new IllegalArgumentException("File descriptors passed in Intent");
18220 if (callingPackage == null) {
18221 throw new IllegalArgumentException("callingPackage cannot be null");
18224 synchronized(this) {
18225 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18230 public boolean stopServiceToken(ComponentName className, IBinder token,
18232 synchronized(this) {
18233 return mServices.stopServiceTokenLocked(className, token, startId);
18238 public void setServiceForeground(ComponentName className, IBinder token,
18239 int id, Notification notification, int flags) {
18240 synchronized(this) {
18241 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18246 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18247 boolean requireFull, String name, String callerPackage) {
18248 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18249 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18252 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18253 String className, int flags) {
18254 boolean result = false;
18255 // For apps that don't have pre-defined UIDs, check for permission
18256 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18257 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18258 if (ActivityManager.checkUidPermission(
18259 INTERACT_ACROSS_USERS,
18260 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18261 ComponentName comp = new ComponentName(aInfo.packageName, className);
18262 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18263 + " requests FLAG_SINGLE_USER, but app does not hold "
18264 + INTERACT_ACROSS_USERS;
18266 throw new SecurityException(msg);
18268 // Permission passed
18271 } else if ("system".equals(componentProcessName)) {
18273 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18274 // Phone app and persistent apps are allowed to export singleuser providers.
18275 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18276 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18278 if (DEBUG_MU) Slog.v(TAG_MU,
18279 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18280 + Integer.toHexString(flags) + ") = " + result);
18285 * Checks to see if the caller is in the same app as the singleton
18286 * component, or the component is in a special app. It allows special apps
18287 * to export singleton components but prevents exporting singleton
18288 * components for regular apps.
18290 boolean isValidSingletonCall(int callingUid, int componentUid) {
18291 int componentAppId = UserHandle.getAppId(componentUid);
18292 return UserHandle.isSameApp(callingUid, componentUid)
18293 || componentAppId == SYSTEM_UID
18294 || componentAppId == PHONE_UID
18295 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18296 == PackageManager.PERMISSION_GRANTED;
18299 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18300 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18301 int userId) throws TransactionTooLargeException {
18302 enforceNotIsolatedCaller("bindService");
18304 // Refuse possible leaked file descriptors
18305 if (service != null && service.hasFileDescriptors() == true) {
18306 throw new IllegalArgumentException("File descriptors passed in Intent");
18309 if (callingPackage == null) {
18310 throw new IllegalArgumentException("callingPackage cannot be null");
18313 synchronized(this) {
18314 return mServices.bindServiceLocked(caller, token, service,
18315 resolvedType, connection, flags, callingPackage, userId);
18319 public boolean unbindService(IServiceConnection connection) {
18320 synchronized (this) {
18321 return mServices.unbindServiceLocked(connection);
18325 public void publishService(IBinder token, Intent intent, IBinder service) {
18326 // Refuse possible leaked file descriptors
18327 if (intent != null && intent.hasFileDescriptors() == true) {
18328 throw new IllegalArgumentException("File descriptors passed in Intent");
18331 synchronized(this) {
18332 if (!(token instanceof ServiceRecord)) {
18333 throw new IllegalArgumentException("Invalid service token");
18335 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18339 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18340 // Refuse possible leaked file descriptors
18341 if (intent != null && intent.hasFileDescriptors() == true) {
18342 throw new IllegalArgumentException("File descriptors passed in Intent");
18345 synchronized(this) {
18346 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18350 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18351 synchronized(this) {
18352 if (!(token instanceof ServiceRecord)) {
18353 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18354 throw new IllegalArgumentException("Invalid service token");
18356 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18360 // =========================================================
18361 // BACKUP AND RESTORE
18362 // =========================================================
18364 // Cause the target app to be launched if necessary and its backup agent
18365 // instantiated. The backup agent will invoke backupAgentCreated() on the
18366 // activity manager to announce its creation.
18367 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18368 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18369 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18371 IPackageManager pm = AppGlobals.getPackageManager();
18372 ApplicationInfo app = null;
18374 app = pm.getApplicationInfo(packageName, 0, userId);
18375 } catch (RemoteException e) {
18376 // can't happen; package manager is process-local
18379 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18386 synchronized(this) {
18387 // !!! TODO: currently no check here that we're already bound
18388 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18389 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18390 synchronized (stats) {
18391 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18394 // Backup agent is now in use, its package can't be stopped.
18396 AppGlobals.getPackageManager().setPackageStoppedState(
18397 app.packageName, false, UserHandle.getUserId(app.uid));
18398 } catch (RemoteException e) {
18399 } catch (IllegalArgumentException e) {
18400 Slog.w(TAG, "Failed trying to unstop package "
18401 + app.packageName + ": " + e);
18404 BackupRecord r = new BackupRecord(ss, app, backupMode);
18405 ComponentName hostingName =
18406 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18407 ? new ComponentName(app.packageName, app.backupAgentName)
18408 : new ComponentName("android", "FullBackupAgent");
18409 // startProcessLocked() returns existing proc's record if it's already running
18410 ProcessRecord proc = startProcessLocked(app.processName, app,
18411 false, 0, "backup", hostingName, false, false, false);
18412 if (proc == null) {
18413 Slog.e(TAG, "Unable to start backup agent process " + r);
18417 // If the app is a regular app (uid >= 10000) and not the system server or phone
18418 // process, etc, then mark it as being in full backup so that certain calls to the
18419 // process can be blocked. This is not reset to false anywhere because we kill the
18420 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18421 if (UserHandle.isApp(app.uid) &&
18422 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18423 proc.inFullBackup = true;
18426 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18427 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18429 mBackupAppName = app.packageName;
18431 // Try not to kill the process during backup
18432 updateOomAdjLocked(proc, true);
18434 // If the process is already attached, schedule the creation of the backup agent now.
18435 // If it is not yet live, this will be done when it attaches to the framework.
18436 if (proc.thread != null) {
18437 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18439 proc.thread.scheduleCreateBackupAgent(app,
18440 compatibilityInfoForPackageLocked(app), backupMode);
18441 } catch (RemoteException e) {
18442 // Will time out on the backup manager side
18445 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18447 // Invariants: at this point, the target app process exists and the application
18448 // is either already running or in the process of coming up. mBackupTarget and
18449 // mBackupAppName describe the app, so that when it binds back to the AM we
18450 // know that it's scheduled for a backup-agent operation.
18453 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18454 if (oldBackupUid != -1) {
18455 js.removeBackingUpUid(oldBackupUid);
18457 if (newBackupUid != -1) {
18458 js.addBackingUpUid(newBackupUid);
18465 public void clearPendingBackup() {
18466 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18467 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18469 synchronized (this) {
18470 mBackupTarget = null;
18471 mBackupAppName = null;
18474 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18475 js.clearAllBackingUpUids();
18478 // A backup agent has just come up
18479 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18480 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18483 synchronized(this) {
18484 if (!agentPackageName.equals(mBackupAppName)) {
18485 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18490 long oldIdent = Binder.clearCallingIdentity();
18492 IBackupManager bm = IBackupManager.Stub.asInterface(
18493 ServiceManager.getService(Context.BACKUP_SERVICE));
18494 bm.agentConnected(agentPackageName, agent);
18495 } catch (RemoteException e) {
18496 // can't happen; the backup manager service is local
18497 } catch (Exception e) {
18498 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18499 e.printStackTrace();
18501 Binder.restoreCallingIdentity(oldIdent);
18505 // done with this agent
18506 public void unbindBackupAgent(ApplicationInfo appInfo) {
18507 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18508 if (appInfo == null) {
18509 Slog.w(TAG, "unbind backup agent for null app");
18515 synchronized(this) {
18517 if (mBackupAppName == null) {
18518 Slog.w(TAG, "Unbinding backup agent with no active backup");
18522 if (!mBackupAppName.equals(appInfo.packageName)) {
18523 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18527 // Not backing this app up any more; reset its OOM adjustment
18528 final ProcessRecord proc = mBackupTarget.app;
18529 updateOomAdjLocked(proc, true);
18530 proc.inFullBackup = false;
18532 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18534 // If the app crashed during backup, 'thread' will be null here
18535 if (proc.thread != null) {
18537 proc.thread.scheduleDestroyBackupAgent(appInfo,
18538 compatibilityInfoForPackageLocked(appInfo));
18539 } catch (Exception e) {
18540 Slog.e(TAG, "Exception when unbinding backup agent:");
18541 e.printStackTrace();
18545 mBackupTarget = null;
18546 mBackupAppName = null;
18550 if (oldBackupUid != -1) {
18551 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18552 js.removeBackingUpUid(oldBackupUid);
18556 // =========================================================
18558 // =========================================================
18560 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18561 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18564 // Easy case -- we have the app's ProcessRecord.
18565 if (record != null) {
18566 return record.info.isInstantApp();
18568 // Otherwise check with PackageManager.
18569 if (callerPackage == null) {
18570 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18571 throw new IllegalArgumentException("Calling application did not provide package name");
18573 mAppOpsService.checkPackage(uid, callerPackage);
18575 IPackageManager pm = AppGlobals.getPackageManager();
18576 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18577 } catch (RemoteException e) {
18578 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18583 boolean isPendingBroadcastProcessLocked(int pid) {
18584 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18585 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18588 void skipPendingBroadcastLocked(int pid) {
18589 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18590 for (BroadcastQueue queue : mBroadcastQueues) {
18591 queue.skipPendingBroadcastLocked(pid);
18595 // The app just attached; send any pending broadcasts that it should receive
18596 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18597 boolean didSomething = false;
18598 for (BroadcastQueue queue : mBroadcastQueues) {
18599 didSomething |= queue.sendPendingBroadcastsLocked(app);
18601 return didSomething;
18604 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18605 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18607 enforceNotIsolatedCaller("registerReceiver");
18608 ArrayList<Intent> stickyIntents = null;
18609 ProcessRecord callerApp = null;
18610 final boolean visibleToInstantApps
18611 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18614 boolean instantApp;
18615 synchronized(this) {
18616 if (caller != null) {
18617 callerApp = getRecordForAppLocked(caller);
18618 if (callerApp == null) {
18619 throw new SecurityException(
18620 "Unable to find app for caller " + caller
18621 + " (pid=" + Binder.getCallingPid()
18622 + ") when registering receiver " + receiver);
18624 if (callerApp.info.uid != SYSTEM_UID &&
18625 !callerApp.pkgList.containsKey(callerPackage) &&
18626 !"android".equals(callerPackage)) {
18627 throw new SecurityException("Given caller package " + callerPackage
18628 + " is not running in process " + callerApp);
18630 callingUid = callerApp.info.uid;
18631 callingPid = callerApp.pid;
18633 callerPackage = null;
18634 callingUid = Binder.getCallingUid();
18635 callingPid = Binder.getCallingPid();
18638 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18639 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18640 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18642 Iterator<String> actions = filter.actionsIterator();
18643 if (actions == null) {
18644 ArrayList<String> noAction = new ArrayList<String>(1);
18645 noAction.add(null);
18646 actions = noAction.iterator();
18649 // Collect stickies of users
18650 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18651 while (actions.hasNext()) {
18652 String action = actions.next();
18653 for (int id : userIds) {
18654 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18655 if (stickies != null) {
18656 ArrayList<Intent> intents = stickies.get(action);
18657 if (intents != null) {
18658 if (stickyIntents == null) {
18659 stickyIntents = new ArrayList<Intent>();
18661 stickyIntents.addAll(intents);
18668 ArrayList<Intent> allSticky = null;
18669 if (stickyIntents != null) {
18670 final ContentResolver resolver = mContext.getContentResolver();
18671 // Look for any matching sticky broadcasts...
18672 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18673 Intent intent = stickyIntents.get(i);
18674 // Don't provided intents that aren't available to instant apps.
18676 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18679 // If intent has scheme "content", it will need to acccess
18680 // provider that needs to lock mProviderMap in ActivityThread
18681 // and also it may need to wait application response, so we
18682 // cannot lock ActivityManagerService here.
18683 if (filter.match(resolver, intent, true, TAG) >= 0) {
18684 if (allSticky == null) {
18685 allSticky = new ArrayList<Intent>();
18687 allSticky.add(intent);
18692 // The first sticky in the list is returned directly back to the client.
18693 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18694 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18695 if (receiver == null) {
18699 synchronized (this) {
18700 if (callerApp != null && (callerApp.thread == null
18701 || callerApp.thread.asBinder() != caller.asBinder())) {
18702 // Original caller already died
18705 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18707 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18709 if (rl.app != null) {
18710 rl.app.receivers.add(rl);
18713 receiver.asBinder().linkToDeath(rl, 0);
18714 } catch (RemoteException e) {
18717 rl.linkedToDeath = true;
18719 mRegisteredReceivers.put(receiver.asBinder(), rl);
18720 } else if (rl.uid != callingUid) {
18721 throw new IllegalArgumentException(
18722 "Receiver requested to register for uid " + callingUid
18723 + " was previously registered for uid " + rl.uid
18724 + " callerPackage is " + callerPackage);
18725 } else if (rl.pid != callingPid) {
18726 throw new IllegalArgumentException(
18727 "Receiver requested to register for pid " + callingPid
18728 + " was previously registered for pid " + rl.pid
18729 + " callerPackage is " + callerPackage);
18730 } else if (rl.userId != userId) {
18731 throw new IllegalArgumentException(
18732 "Receiver requested to register for user " + userId
18733 + " was previously registered for user " + rl.userId
18734 + " callerPackage is " + callerPackage);
18736 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18737 permission, callingUid, userId, instantApp, visibleToInstantApps);
18739 if (!bf.debugCheck()) {
18740 Slog.w(TAG, "==> For Dynamic broadcast");
18742 mReceiverResolver.addFilter(bf);
18744 // Enqueue broadcasts for all existing stickies that match
18746 if (allSticky != null) {
18747 ArrayList receivers = new ArrayList();
18750 final int stickyCount = allSticky.size();
18751 for (int i = 0; i < stickyCount; i++) {
18752 Intent intent = allSticky.get(i);
18753 BroadcastQueue queue = broadcastQueueForIntent(intent);
18754 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18755 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18756 null, 0, null, null, false, true, true, -1);
18757 queue.enqueueParallelBroadcastLocked(r);
18758 queue.scheduleBroadcastsLocked();
18766 public void unregisterReceiver(IIntentReceiver receiver) {
18767 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18769 final long origId = Binder.clearCallingIdentity();
18771 boolean doTrim = false;
18773 synchronized(this) {
18774 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18776 final BroadcastRecord r = rl.curBroadcast;
18777 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18778 final boolean doNext = r.queue.finishReceiverLocked(
18779 r, r.resultCode, r.resultData, r.resultExtras,
18780 r.resultAbort, false);
18783 r.queue.processNextBroadcast(false);
18787 if (rl.app != null) {
18788 rl.app.receivers.remove(rl);
18790 removeReceiverLocked(rl);
18791 if (rl.linkedToDeath) {
18792 rl.linkedToDeath = false;
18793 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18798 // If we actually concluded any broadcasts, we might now be able
18799 // to trim the recipients' apps from our working set
18801 trimApplications();
18806 Binder.restoreCallingIdentity(origId);
18810 void removeReceiverLocked(ReceiverList rl) {
18811 mRegisteredReceivers.remove(rl.receiver.asBinder());
18812 for (int i = rl.size() - 1; i >= 0; i--) {
18813 mReceiverResolver.removeFilter(rl.get(i));
18817 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18818 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18819 ProcessRecord r = mLruProcesses.get(i);
18820 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18822 r.thread.dispatchPackageBroadcast(cmd, packages);
18823 } catch (RemoteException ex) {
18829 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18830 int callingUid, int[] users) {
18831 // TODO: come back and remove this assumption to triage all broadcasts
18832 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18834 List<ResolveInfo> receivers = null;
18836 HashSet<ComponentName> singleUserReceivers = null;
18837 boolean scannedFirstReceivers = false;
18838 for (int user : users) {
18839 // Skip users that have Shell restrictions, with exception of always permitted
18840 // Shell broadcasts
18841 if (callingUid == SHELL_UID
18842 && mUserController.hasUserRestriction(
18843 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18844 && !isPermittedShellBroadcast(intent)) {
18847 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18848 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18849 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18850 // If this is not the system user, we need to check for
18851 // any receivers that should be filtered out.
18852 for (int i=0; i<newReceivers.size(); i++) {
18853 ResolveInfo ri = newReceivers.get(i);
18854 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18855 newReceivers.remove(i);
18860 if (newReceivers != null && newReceivers.size() == 0) {
18861 newReceivers = null;
18863 if (receivers == null) {
18864 receivers = newReceivers;
18865 } else if (newReceivers != null) {
18866 // We need to concatenate the additional receivers
18867 // found with what we have do far. This would be easy,
18868 // but we also need to de-dup any receivers that are
18870 if (!scannedFirstReceivers) {
18871 // Collect any single user receivers we had already retrieved.
18872 scannedFirstReceivers = true;
18873 for (int i=0; i<receivers.size(); i++) {
18874 ResolveInfo ri = receivers.get(i);
18875 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18876 ComponentName cn = new ComponentName(
18877 ri.activityInfo.packageName, ri.activityInfo.name);
18878 if (singleUserReceivers == null) {
18879 singleUserReceivers = new HashSet<ComponentName>();
18881 singleUserReceivers.add(cn);
18885 // Add the new results to the existing results, tracking
18886 // and de-dupping single user receivers.
18887 for (int i=0; i<newReceivers.size(); i++) {
18888 ResolveInfo ri = newReceivers.get(i);
18889 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18890 ComponentName cn = new ComponentName(
18891 ri.activityInfo.packageName, ri.activityInfo.name);
18892 if (singleUserReceivers == null) {
18893 singleUserReceivers = new HashSet<ComponentName>();
18895 if (!singleUserReceivers.contains(cn)) {
18896 singleUserReceivers.add(cn);
18905 } catch (RemoteException ex) {
18906 // pm is in same process, this will never happen.
18911 private boolean isPermittedShellBroadcast(Intent intent) {
18912 // remote bugreport should always be allowed to be taken
18913 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18916 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18917 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18918 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18919 // Don't yell about broadcasts sent via shell
18923 final String action = intent.getAction();
18924 if (isProtectedBroadcast
18925 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18926 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18927 || Intent.ACTION_MEDIA_BUTTON.equals(action)
18928 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18929 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18930 || Intent.ACTION_MASTER_CLEAR.equals(action)
18931 || Intent.ACTION_FACTORY_RESET.equals(action)
18932 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18933 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18934 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18935 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18936 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18937 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18938 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18939 // Broadcast is either protected, or it's a public action that
18940 // we've relaxed, so it's fine for system internals to send.
18944 // This broadcast may be a problem... but there are often system components that
18945 // want to send an internal broadcast to themselves, which is annoying to have to
18946 // explicitly list each action as a protected broadcast, so we will check for that
18947 // one safe case and allow it: an explicit broadcast, only being received by something
18948 // that has protected itself.
18949 if (receivers != null && receivers.size() > 0
18950 && (intent.getPackage() != null || intent.getComponent() != null)) {
18951 boolean allProtected = true;
18952 for (int i = receivers.size()-1; i >= 0; i--) {
18953 Object target = receivers.get(i);
18954 if (target instanceof ResolveInfo) {
18955 ResolveInfo ri = (ResolveInfo)target;
18956 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18957 allProtected = false;
18961 BroadcastFilter bf = (BroadcastFilter)target;
18962 if (bf.requiredPermission == null) {
18963 allProtected = false;
18968 if (allProtected) {
18974 // The vast majority of broadcasts sent from system internals
18975 // should be protected to avoid security holes, so yell loudly
18976 // to ensure we examine these cases.
18977 if (callerApp != null) {
18978 Log.wtf(TAG, "Sending non-protected broadcast " + action
18979 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18982 Log.wtf(TAG, "Sending non-protected broadcast " + action
18983 + " from system uid " + UserHandle.formatUid(callingUid)
18984 + " pkg " + callerPackage,
18989 final int broadcastIntentLocked(ProcessRecord callerApp,
18990 String callerPackage, Intent intent, String resolvedType,
18991 IIntentReceiver resultTo, int resultCode, String resultData,
18992 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18993 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18994 intent = new Intent(intent);
18996 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
18997 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
18998 if (callerInstantApp) {
18999 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19002 // By default broadcasts do not go to stopped apps.
19003 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19005 // If we have not finished booting, don't allow this to launch new processes.
19006 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19007 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19010 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19011 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19012 + " ordered=" + ordered + " userid=" + userId);
19013 if ((resultTo != null) && !ordered) {
19014 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19017 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19018 ALLOW_NON_FULL, "broadcast", callerPackage);
19020 // Make sure that the user who is receiving this broadcast is running.
19021 // If not, we will just skip it. Make an exception for shutdown broadcasts
19022 // and upgrade steps.
19024 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19025 if ((callingUid != SYSTEM_UID
19026 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19027 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19028 Slog.w(TAG, "Skipping broadcast of " + intent
19029 + ": user " + userId + " is stopped");
19030 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19034 BroadcastOptions brOptions = null;
19035 if (bOptions != null) {
19036 brOptions = new BroadcastOptions(bOptions);
19037 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19038 // See if the caller is allowed to do this. Note we are checking against
19039 // the actual real caller (not whoever provided the operation as say a
19040 // PendingIntent), because that who is actually supplied the arguments.
19041 if (checkComponentPermission(
19042 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19043 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19044 != PackageManager.PERMISSION_GRANTED) {
19045 String msg = "Permission Denial: " + intent.getAction()
19046 + " broadcast from " + callerPackage + " (pid=" + callingPid
19047 + ", uid=" + callingUid + ")"
19049 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19051 throw new SecurityException(msg);
19056 // Verify that protected broadcasts are only being sent by system code,
19057 // and that system code is only sending protected broadcasts.
19058 final String action = intent.getAction();
19059 final boolean isProtectedBroadcast;
19061 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19062 } catch (RemoteException e) {
19063 Slog.w(TAG, "Remote exception", e);
19064 return ActivityManager.BROADCAST_SUCCESS;
19067 final boolean isCallerSystem;
19068 switch (UserHandle.getAppId(callingUid)) {
19072 case BLUETOOTH_UID:
19074 isCallerSystem = true;
19077 isCallerSystem = (callerApp != null) && callerApp.persistent;
19081 // First line security check before anything else: stop non-system apps from
19082 // sending protected broadcasts.
19083 if (!isCallerSystem) {
19084 if (isProtectedBroadcast) {
19085 String msg = "Permission Denial: not allowed to send broadcast "
19086 + action + " from pid="
19087 + callingPid + ", uid=" + callingUid;
19089 throw new SecurityException(msg);
19091 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19092 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19093 // Special case for compatibility: we don't want apps to send this,
19094 // but historically it has not been protected and apps may be using it
19095 // to poke their own app widget. So, instead of making it protected,
19096 // just limit it to the caller.
19097 if (callerPackage == null) {
19098 String msg = "Permission Denial: not allowed to send broadcast "
19099 + action + " from unknown caller.";
19101 throw new SecurityException(msg);
19102 } else if (intent.getComponent() != null) {
19103 // They are good enough to send to an explicit component... verify
19104 // it is being sent to the calling app.
19105 if (!intent.getComponent().getPackageName().equals(
19107 String msg = "Permission Denial: not allowed to send broadcast "
19109 + intent.getComponent().getPackageName() + " from "
19112 throw new SecurityException(msg);
19115 // Limit broadcast to their own package.
19116 intent.setPackage(callerPackage);
19121 if (action != null) {
19122 if (getBackgroundLaunchBroadcasts().contains(action)) {
19123 if (DEBUG_BACKGROUND_CHECK) {
19124 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19126 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19130 case Intent.ACTION_UID_REMOVED:
19131 case Intent.ACTION_PACKAGE_REMOVED:
19132 case Intent.ACTION_PACKAGE_CHANGED:
19133 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19134 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19135 case Intent.ACTION_PACKAGES_SUSPENDED:
19136 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19137 // Handle special intents: if this broadcast is from the package
19138 // manager about a package being removed, we need to remove all of
19139 // its activities from the history stack.
19140 if (checkComponentPermission(
19141 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19142 callingPid, callingUid, -1, true)
19143 != PackageManager.PERMISSION_GRANTED) {
19144 String msg = "Permission Denial: " + intent.getAction()
19145 + " broadcast from " + callerPackage + " (pid=" + callingPid
19146 + ", uid=" + callingUid + ")"
19148 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19150 throw new SecurityException(msg);
19153 case Intent.ACTION_UID_REMOVED:
19154 final int uid = getUidFromIntent(intent);
19156 mBatteryStatsService.removeUid(uid);
19157 mAppOpsService.uidRemoved(uid);
19160 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19161 // If resources are unavailable just force stop all those packages
19162 // and flush the attribute cache as well.
19164 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19165 if (list != null && list.length > 0) {
19166 for (int i = 0; i < list.length; i++) {
19167 forceStopPackageLocked(list[i], -1, false, true, true,
19168 false, false, userId, "storage unmount");
19170 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19171 sendPackageBroadcastLocked(
19172 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19176 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19177 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19179 case Intent.ACTION_PACKAGE_REMOVED:
19180 case Intent.ACTION_PACKAGE_CHANGED:
19181 Uri data = intent.getData();
19183 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19184 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19185 final boolean replacing =
19186 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19187 final boolean killProcess =
19188 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19189 final boolean fullUninstall = removed && !replacing;
19192 forceStopPackageLocked(ssp, UserHandle.getAppId(
19193 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19194 false, true, true, false, fullUninstall, userId,
19195 removed ? "pkg removed" : "pkg changed");
19197 final int cmd = killProcess
19198 ? ApplicationThreadConstants.PACKAGE_REMOVED
19199 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19200 sendPackageBroadcastLocked(cmd,
19201 new String[] {ssp}, userId);
19202 if (fullUninstall) {
19203 mAppOpsService.packageRemoved(
19204 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19206 // Remove all permissions granted from/to this package
19207 removeUriPermissionsForPackageLocked(ssp, userId, true);
19209 removeTasksByPackageNameLocked(ssp, userId);
19211 mServices.forceStopPackageLocked(ssp, userId);
19213 // Hide the "unsupported display" dialog if necessary.
19214 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19215 mUnsupportedDisplaySizeDialog.getPackageName())) {
19216 mUnsupportedDisplaySizeDialog.dismiss();
19217 mUnsupportedDisplaySizeDialog = null;
19219 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19220 mBatteryStatsService.notePackageUninstalled(ssp);
19224 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19225 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19226 userId, ProcessList.INVALID_ADJ,
19227 false, true, true, false, "change " + ssp);
19229 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19230 intent.getStringArrayExtra(
19231 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19235 case Intent.ACTION_PACKAGES_SUSPENDED:
19236 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19237 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19238 intent.getAction());
19239 final String[] packageNames = intent.getStringArrayExtra(
19240 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19241 final int userHandle = intent.getIntExtra(
19242 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19244 synchronized(ActivityManagerService.this) {
19245 mRecentTasks.onPackagesSuspendedChanged(
19246 packageNames, suspended, userHandle);
19251 case Intent.ACTION_PACKAGE_REPLACED:
19253 final Uri data = intent.getData();
19255 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19256 ApplicationInfo aInfo = null;
19258 aInfo = AppGlobals.getPackageManager()
19259 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19260 } catch (RemoteException ignore) {}
19261 if (aInfo == null) {
19262 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19263 + " ssp=" + ssp + " data=" + data);
19264 return ActivityManager.BROADCAST_SUCCESS;
19266 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19267 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19268 new String[] {ssp}, userId);
19272 case Intent.ACTION_PACKAGE_ADDED:
19274 // Special case for adding a package: by default turn on compatibility mode.
19275 Uri data = intent.getData();
19277 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19278 final boolean replacing =
19279 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19280 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19283 ApplicationInfo ai = AppGlobals.getPackageManager().
19284 getApplicationInfo(ssp, 0, 0);
19285 mBatteryStatsService.notePackageInstalled(ssp,
19286 ai != null ? ai.versionCode : 0);
19287 } catch (RemoteException e) {
19292 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19294 Uri data = intent.getData();
19296 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19297 // Hide the "unsupported display" dialog if necessary.
19298 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19299 mUnsupportedDisplaySizeDialog.getPackageName())) {
19300 mUnsupportedDisplaySizeDialog.dismiss();
19301 mUnsupportedDisplaySizeDialog = null;
19303 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19307 case Intent.ACTION_TIMEZONE_CHANGED:
19308 // If this is the time zone changed action, queue up a message that will reset
19309 // the timezone of all currently running processes. This message will get
19310 // queued up before the broadcast happens.
19311 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19313 case Intent.ACTION_TIME_CHANGED:
19314 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19315 // the tri-state value it may contain and "unknown".
19316 // For convenience we re-use the Intent extra values.
19317 final int NO_EXTRA_VALUE_FOUND = -1;
19318 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19319 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19320 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19321 // Only send a message if the time preference is available.
19322 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19323 Message updateTimePreferenceMsg =
19324 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19325 timeFormatPreferenceMsgValue, 0);
19326 mHandler.sendMessage(updateTimePreferenceMsg);
19328 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19329 synchronized (stats) {
19330 stats.noteCurrentTimeChangedLocked();
19333 case Intent.ACTION_CLEAR_DNS_CACHE:
19334 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19336 case Proxy.PROXY_CHANGE_ACTION:
19337 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19338 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19340 case android.hardware.Camera.ACTION_NEW_PICTURE:
19341 case android.hardware.Camera.ACTION_NEW_VIDEO:
19342 // In N we just turned these off; in O we are turing them back on partly,
19343 // only for registered receivers. This will still address the main problem
19344 // (a spam of apps waking up when a picture is taken putting significant
19345 // memory pressure on the system at a bad point), while still allowing apps
19346 // that are already actively running to know about this happening.
19347 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19349 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19350 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19352 case "com.android.launcher.action.INSTALL_SHORTCUT":
19353 // As of O, we no longer support this broadcasts, even for pre-O apps.
19354 // Apps should now be using ShortcutManager.pinRequestShortcut().
19355 Log.w(TAG, "Broadcast " + action
19356 + " no longer supported. It will not be delivered.");
19357 return ActivityManager.BROADCAST_SUCCESS;
19360 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19361 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19362 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19363 final int uid = getUidFromIntent(intent);
19365 final UidRecord uidRec = mActiveUids.get(uid);
19366 if (uidRec != null) {
19367 uidRec.updateHasInternetPermission();
19373 // Add to the sticky list if requested.
19375 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19376 callingPid, callingUid)
19377 != PackageManager.PERMISSION_GRANTED) {
19378 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19379 + callingPid + ", uid=" + callingUid
19380 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19382 throw new SecurityException(msg);
19384 if (requiredPermissions != null && requiredPermissions.length > 0) {
19385 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19386 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19387 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19389 if (intent.getComponent() != null) {
19390 throw new SecurityException(
19391 "Sticky broadcasts can't target a specific component");
19393 // We use userId directly here, since the "all" target is maintained
19394 // as a separate set of sticky broadcasts.
19395 if (userId != UserHandle.USER_ALL) {
19396 // But first, if this is not a broadcast to all users, then
19397 // make sure it doesn't conflict with an existing broadcast to
19399 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19400 UserHandle.USER_ALL);
19401 if (stickies != null) {
19402 ArrayList<Intent> list = stickies.get(intent.getAction());
19403 if (list != null) {
19404 int N = list.size();
19406 for (i=0; i<N; i++) {
19407 if (intent.filterEquals(list.get(i))) {
19408 throw new IllegalArgumentException(
19409 "Sticky broadcast " + intent + " for user "
19410 + userId + " conflicts with existing global broadcast");
19416 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19417 if (stickies == null) {
19418 stickies = new ArrayMap<>();
19419 mStickyBroadcasts.put(userId, stickies);
19421 ArrayList<Intent> list = stickies.get(intent.getAction());
19422 if (list == null) {
19423 list = new ArrayList<>();
19424 stickies.put(intent.getAction(), list);
19426 final int stickiesCount = list.size();
19428 for (i = 0; i < stickiesCount; i++) {
19429 if (intent.filterEquals(list.get(i))) {
19430 // This sticky already exists, replace it.
19431 list.set(i, new Intent(intent));
19435 if (i >= stickiesCount) {
19436 list.add(new Intent(intent));
19441 if (userId == UserHandle.USER_ALL) {
19442 // Caller wants broadcast to go to all started users.
19443 users = mUserController.getStartedUserArrayLocked();
19445 // Caller wants broadcast to go to one specific user.
19446 users = new int[] {userId};
19449 // Figure out who all will receive this broadcast.
19450 List receivers = null;
19451 List<BroadcastFilter> registeredReceivers = null;
19452 // Need to resolve the intent to interested receivers...
19453 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19455 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19457 if (intent.getComponent() == null) {
19458 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19459 // Query one target user at a time, excluding shell-restricted users
19460 for (int i = 0; i < users.length; i++) {
19461 if (mUserController.hasUserRestriction(
19462 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19465 List<BroadcastFilter> registeredReceiversForUser =
19466 mReceiverResolver.queryIntent(intent,
19467 resolvedType, false /*defaultOnly*/, users[i]);
19468 if (registeredReceivers == null) {
19469 registeredReceivers = registeredReceiversForUser;
19470 } else if (registeredReceiversForUser != null) {
19471 registeredReceivers.addAll(registeredReceiversForUser);
19475 registeredReceivers = mReceiverResolver.queryIntent(intent,
19476 resolvedType, false /*defaultOnly*/, userId);
19480 final boolean replacePending =
19481 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19483 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19484 + " replacePending=" + replacePending);
19486 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19487 if (!ordered && NR > 0) {
19488 // If we are not serializing this broadcast, then send the
19489 // registered receivers separately so they don't wait for the
19490 // components to be launched.
19491 if (isCallerSystem) {
19492 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19493 isProtectedBroadcast, registeredReceivers);
19495 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19496 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19497 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19498 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19499 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19500 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19501 final boolean replaced = replacePending
19502 && (queue.replaceParallelBroadcastLocked(r) != null);
19503 // Note: We assume resultTo is null for non-ordered broadcasts.
19505 queue.enqueueParallelBroadcastLocked(r);
19506 queue.scheduleBroadcastsLocked();
19508 registeredReceivers = null;
19512 // Merge into one list.
19514 if (receivers != null) {
19515 // A special case for PACKAGE_ADDED: do not allow the package
19516 // being added to see this broadcast. This prevents them from
19517 // using this as a back door to get run as soon as they are
19518 // installed. Maybe in the future we want to have a special install
19519 // broadcast or such for apps, but we'd like to deliberately make
19521 String skipPackages[] = null;
19522 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19523 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19524 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19525 Uri data = intent.getData();
19526 if (data != null) {
19527 String pkgName = data.getSchemeSpecificPart();
19528 if (pkgName != null) {
19529 skipPackages = new String[] { pkgName };
19532 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19533 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19535 if (skipPackages != null && (skipPackages.length > 0)) {
19536 for (String skipPackage : skipPackages) {
19537 if (skipPackage != null) {
19538 int NT = receivers.size();
19539 for (int it=0; it<NT; it++) {
19540 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19541 if (curt.activityInfo.packageName.equals(skipPackage)) {
19542 receivers.remove(it);
19551 int NT = receivers != null ? receivers.size() : 0;
19553 ResolveInfo curt = null;
19554 BroadcastFilter curr = null;
19555 while (it < NT && ir < NR) {
19556 if (curt == null) {
19557 curt = (ResolveInfo)receivers.get(it);
19559 if (curr == null) {
19560 curr = registeredReceivers.get(ir);
19562 if (curr.getPriority() >= curt.priority) {
19563 // Insert this broadcast record into the final list.
19564 receivers.add(it, curr);
19570 // Skip to the next ResolveInfo in the final list.
19577 if (receivers == null) {
19578 receivers = new ArrayList();
19580 receivers.add(registeredReceivers.get(ir));
19584 if (isCallerSystem) {
19585 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19586 isProtectedBroadcast, receivers);
19589 if ((receivers != null && receivers.size() > 0)
19590 || resultTo != null) {
19591 BroadcastQueue queue = broadcastQueueForIntent(intent);
19592 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19593 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19594 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19595 resultData, resultExtras, ordered, sticky, false, userId);
19597 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19598 + ": prev had " + queue.mOrderedBroadcasts.size());
19599 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19600 "Enqueueing broadcast " + r.intent.getAction());
19602 final BroadcastRecord oldRecord =
19603 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19604 if (oldRecord != null) {
19605 // Replaced, fire the result-to receiver.
19606 if (oldRecord.resultTo != null) {
19607 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19609 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19611 Activity.RESULT_CANCELED, null, null,
19612 false, false, oldRecord.userId);
19613 } catch (RemoteException e) {
19614 Slog.w(TAG, "Failure ["
19615 + queue.mQueueName + "] sending broadcast result of "
19621 queue.enqueueOrderedBroadcastLocked(r);
19622 queue.scheduleBroadcastsLocked();
19625 // There was nobody interested in the broadcast, but we still want to record
19626 // that it happened.
19627 if (intent.getComponent() == null && intent.getPackage() == null
19628 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19629 // This was an implicit broadcast... let's record it for posterity.
19630 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19634 return ActivityManager.BROADCAST_SUCCESS;
19638 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19640 private int getUidFromIntent(Intent intent) {
19641 if (intent == null) {
19644 final Bundle intentExtras = intent.getExtras();
19645 return intent.hasExtra(Intent.EXTRA_UID)
19646 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19649 final void rotateBroadcastStatsIfNeededLocked() {
19650 final long now = SystemClock.elapsedRealtime();
19651 if (mCurBroadcastStats == null ||
19652 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19653 mLastBroadcastStats = mCurBroadcastStats;
19654 if (mLastBroadcastStats != null) {
19655 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19656 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19658 mCurBroadcastStats = new BroadcastStats();
19662 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19663 int skipCount, long dispatchTime) {
19664 rotateBroadcastStatsIfNeededLocked();
19665 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19668 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19669 rotateBroadcastStatsIfNeededLocked();
19670 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19673 final Intent verifyBroadcastLocked(Intent intent) {
19674 // Refuse possible leaked file descriptors
19675 if (intent != null && intent.hasFileDescriptors() == true) {
19676 throw new IllegalArgumentException("File descriptors passed in Intent");
19679 int flags = intent.getFlags();
19681 if (!mProcessesReady) {
19682 // if the caller really truly claims to know what they're doing, go
19683 // ahead and allow the broadcast without launching any receivers
19684 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19685 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19686 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19687 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19688 + " before boot completion");
19689 throw new IllegalStateException("Cannot broadcast before boot completed");
19693 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19694 throw new IllegalArgumentException(
19695 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19698 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19699 switch (Binder.getCallingUid()) {
19704 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19705 + Binder.getCallingUid());
19706 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19714 public final int broadcastIntent(IApplicationThread caller,
19715 Intent intent, String resolvedType, IIntentReceiver resultTo,
19716 int resultCode, String resultData, Bundle resultExtras,
19717 String[] requiredPermissions, int appOp, Bundle bOptions,
19718 boolean serialized, boolean sticky, int userId) {
19719 enforceNotIsolatedCaller("broadcastIntent");
19720 synchronized(this) {
19721 intent = verifyBroadcastLocked(intent);
19723 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19724 final int callingPid = Binder.getCallingPid();
19725 final int callingUid = Binder.getCallingUid();
19726 final long origId = Binder.clearCallingIdentity();
19727 int res = broadcastIntentLocked(callerApp,
19728 callerApp != null ? callerApp.info.packageName : null,
19729 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19730 requiredPermissions, appOp, bOptions, serialized, sticky,
19731 callingPid, callingUid, userId);
19732 Binder.restoreCallingIdentity(origId);
19738 int broadcastIntentInPackage(String packageName, int uid,
19739 Intent intent, String resolvedType, IIntentReceiver resultTo,
19740 int resultCode, String resultData, Bundle resultExtras,
19741 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19743 synchronized(this) {
19744 intent = verifyBroadcastLocked(intent);
19746 final long origId = Binder.clearCallingIdentity();
19747 String[] requiredPermissions = requiredPermission == null ? null
19748 : new String[] {requiredPermission};
19749 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19750 resultTo, resultCode, resultData, resultExtras,
19751 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19752 sticky, -1, uid, userId);
19753 Binder.restoreCallingIdentity(origId);
19758 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19759 // Refuse possible leaked file descriptors
19760 if (intent != null && intent.hasFileDescriptors() == true) {
19761 throw new IllegalArgumentException("File descriptors passed in Intent");
19764 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19765 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19767 synchronized(this) {
19768 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19769 != PackageManager.PERMISSION_GRANTED) {
19770 String msg = "Permission Denial: unbroadcastIntent() from pid="
19771 + Binder.getCallingPid()
19772 + ", uid=" + Binder.getCallingUid()
19773 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19775 throw new SecurityException(msg);
19777 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19778 if (stickies != null) {
19779 ArrayList<Intent> list = stickies.get(intent.getAction());
19780 if (list != null) {
19781 int N = list.size();
19783 for (i=0; i<N; i++) {
19784 if (intent.filterEquals(list.get(i))) {
19789 if (list.size() <= 0) {
19790 stickies.remove(intent.getAction());
19793 if (stickies.size() <= 0) {
19794 mStickyBroadcasts.remove(userId);
19800 void backgroundServicesFinishedLocked(int userId) {
19801 for (BroadcastQueue queue : mBroadcastQueues) {
19802 queue.backgroundServicesFinishedLocked(userId);
19806 public void finishReceiver(IBinder who, int resultCode, String resultData,
19807 Bundle resultExtras, boolean resultAbort, int flags) {
19808 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19810 // Refuse possible leaked file descriptors
19811 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19812 throw new IllegalArgumentException("File descriptors passed in Bundle");
19815 final long origId = Binder.clearCallingIdentity();
19817 boolean doNext = false;
19820 synchronized(this) {
19821 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19822 ? mFgBroadcastQueue : mBgBroadcastQueue;
19823 r = queue.getMatchingOrderedReceiver(who);
19825 doNext = r.queue.finishReceiverLocked(r, resultCode,
19826 resultData, resultExtras, resultAbort, true);
19831 r.queue.processNextBroadcast(false);
19833 trimApplications();
19835 Binder.restoreCallingIdentity(origId);
19839 // =========================================================
19841 // =========================================================
19843 public boolean startInstrumentation(ComponentName className,
19844 String profileFile, int flags, Bundle arguments,
19845 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19846 int userId, String abiOverride) {
19847 enforceNotIsolatedCaller("startInstrumentation");
19848 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19849 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19850 // Refuse possible leaked file descriptors
19851 if (arguments != null && arguments.hasFileDescriptors()) {
19852 throw new IllegalArgumentException("File descriptors passed in Bundle");
19855 synchronized(this) {
19856 InstrumentationInfo ii = null;
19857 ApplicationInfo ai = null;
19859 ii = mContext.getPackageManager().getInstrumentationInfo(
19860 className, STOCK_PM_FLAGS);
19861 ai = AppGlobals.getPackageManager().getApplicationInfo(
19862 ii.targetPackage, STOCK_PM_FLAGS, userId);
19863 } catch (PackageManager.NameNotFoundException e) {
19864 } catch (RemoteException e) {
19867 reportStartInstrumentationFailureLocked(watcher, className,
19868 "Unable to find instrumentation info for: " + className);
19872 reportStartInstrumentationFailureLocked(watcher, className,
19873 "Unable to find instrumentation target package: " + ii.targetPackage);
19876 if (!ai.hasCode()) {
19877 reportStartInstrumentationFailureLocked(watcher, className,
19878 "Instrumentation target has no code: " + ii.targetPackage);
19882 int match = mContext.getPackageManager().checkSignatures(
19883 ii.targetPackage, ii.packageName);
19884 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19885 String msg = "Permission Denial: starting instrumentation "
19886 + className + " from pid="
19887 + Binder.getCallingPid()
19888 + ", uid=" + Binder.getCallingPid()
19889 + " not allowed because package " + ii.packageName
19890 + " does not have a signature matching the target "
19891 + ii.targetPackage;
19892 reportStartInstrumentationFailureLocked(watcher, className, msg);
19893 throw new SecurityException(msg);
19896 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19897 activeInstr.mClass = className;
19898 String defProcess = ai.processName;;
19899 if (ii.targetProcesses == null) {
19900 activeInstr.mTargetProcesses = new String[]{ai.processName};
19901 } else if (ii.targetProcesses.equals("*")) {
19902 activeInstr.mTargetProcesses = new String[0];
19904 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19905 defProcess = activeInstr.mTargetProcesses[0];
19907 activeInstr.mTargetInfo = ai;
19908 activeInstr.mProfileFile = profileFile;
19909 activeInstr.mArguments = arguments;
19910 activeInstr.mWatcher = watcher;
19911 activeInstr.mUiAutomationConnection = uiAutomationConnection;
19912 activeInstr.mResultClass = className;
19914 final long origId = Binder.clearCallingIdentity();
19915 // Instrumentation can kill and relaunch even persistent processes
19916 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19918 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19919 app.instr = activeInstr;
19920 activeInstr.mFinished = false;
19921 activeInstr.mRunningProcesses.add(app);
19922 if (!mActiveInstrumentation.contains(activeInstr)) {
19923 mActiveInstrumentation.add(activeInstr);
19925 Binder.restoreCallingIdentity(origId);
19932 * Report errors that occur while attempting to start Instrumentation. Always writes the
19933 * error to the logs, but if somebody is watching, send the report there too. This enables
19934 * the "am" command to report errors with more information.
19936 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
19937 * @param cn The component name of the instrumentation.
19938 * @param report The error report.
19940 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19941 ComponentName cn, String report) {
19942 Slog.w(TAG, report);
19943 if (watcher != null) {
19944 Bundle results = new Bundle();
19945 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19946 results.putString("Error", report);
19947 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19951 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19952 if (app.instr == null) {
19953 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19957 if (!app.instr.mFinished && results != null) {
19958 if (app.instr.mCurResults == null) {
19959 app.instr.mCurResults = new Bundle(results);
19961 app.instr.mCurResults.putAll(results);
19966 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19967 int userId = UserHandle.getCallingUserId();
19968 // Refuse possible leaked file descriptors
19969 if (results != null && results.hasFileDescriptors()) {
19970 throw new IllegalArgumentException("File descriptors passed in Intent");
19973 synchronized(this) {
19974 ProcessRecord app = getRecordForAppLocked(target);
19976 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19979 final long origId = Binder.clearCallingIdentity();
19980 addInstrumentationResultsLocked(app, results);
19981 Binder.restoreCallingIdentity(origId);
19985 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19986 if (app.instr == null) {
19987 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19991 if (!app.instr.mFinished) {
19992 if (app.instr.mWatcher != null) {
19993 Bundle finalResults = app.instr.mCurResults;
19994 if (finalResults != null) {
19995 if (app.instr.mCurResults != null && results != null) {
19996 finalResults.putAll(results);
19999 finalResults = results;
20001 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20002 app.instr.mClass, resultCode, finalResults);
20005 // Can't call out of the system process with a lock held, so post a message.
20006 if (app.instr.mUiAutomationConnection != null) {
20007 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20008 app.instr.mUiAutomationConnection).sendToTarget();
20010 app.instr.mFinished = true;
20013 app.instr.removeProcess(app);
20016 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20020 public void finishInstrumentation(IApplicationThread target,
20021 int resultCode, Bundle results) {
20022 int userId = UserHandle.getCallingUserId();
20023 // Refuse possible leaked file descriptors
20024 if (results != null && results.hasFileDescriptors()) {
20025 throw new IllegalArgumentException("File descriptors passed in Intent");
20028 synchronized(this) {
20029 ProcessRecord app = getRecordForAppLocked(target);
20031 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20034 final long origId = Binder.clearCallingIdentity();
20035 finishInstrumentationLocked(app, resultCode, results);
20036 Binder.restoreCallingIdentity(origId);
20040 // =========================================================
20042 // =========================================================
20044 public ConfigurationInfo getDeviceConfigurationInfo() {
20045 ConfigurationInfo config = new ConfigurationInfo();
20046 synchronized (this) {
20047 final Configuration globalConfig = getGlobalConfiguration();
20048 config.reqTouchScreen = globalConfig.touchscreen;
20049 config.reqKeyboardType = globalConfig.keyboard;
20050 config.reqNavigation = globalConfig.navigation;
20051 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20052 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20053 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20055 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20056 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20057 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20059 config.reqGlEsVersion = GL_ES_VERSION;
20064 ActivityStack getFocusedStack() {
20065 return mStackSupervisor.getFocusedStack();
20069 public int getFocusedStackId() throws RemoteException {
20070 ActivityStack focusedStack = getFocusedStack();
20071 if (focusedStack != null) {
20072 return focusedStack.getStackId();
20077 public Configuration getConfiguration() {
20079 synchronized(this) {
20080 ci = new Configuration(getGlobalConfiguration());
20081 ci.userSetLocale = false;
20087 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20088 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20089 synchronized (this) {
20090 mSuppressResizeConfigChanges = suppress;
20095 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20096 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20097 * activity and clearing the task at the same time.
20100 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20101 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20102 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20103 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20105 synchronized (this) {
20106 final long origId = Binder.clearCallingIdentity();
20108 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20110 Binder.restoreCallingIdentity(origId);
20116 public void updatePersistentConfiguration(Configuration values) {
20117 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20118 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20119 if (values == null) {
20120 throw new NullPointerException("Configuration must not be null");
20123 int userId = UserHandle.getCallingUserId();
20125 synchronized(this) {
20126 updatePersistentConfigurationLocked(values, userId);
20130 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20131 final long origId = Binder.clearCallingIdentity();
20133 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20135 Binder.restoreCallingIdentity(origId);
20139 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20140 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20141 FONT_SCALE, 1.0f, userId);
20143 synchronized (this) {
20144 if (getGlobalConfiguration().fontScale == scaleFactor) {
20148 final Configuration configuration
20149 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20150 configuration.fontScale = scaleFactor;
20151 updatePersistentConfigurationLocked(configuration, userId);
20155 private void enforceWriteSettingsPermission(String func) {
20156 int uid = Binder.getCallingUid();
20157 if (uid == ROOT_UID) {
20161 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20162 Settings.getPackageNameForUid(mContext, uid), false)) {
20166 String msg = "Permission Denial: " + func + " from pid="
20167 + Binder.getCallingPid()
20169 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20171 throw new SecurityException(msg);
20175 public boolean updateConfiguration(Configuration values) {
20176 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20178 synchronized(this) {
20179 if (values == null && mWindowManager != null) {
20180 // sentinel: fetch the current configuration from the window manager
20181 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20184 if (mWindowManager != null) {
20185 // Update OOM levels based on display size.
20186 mProcessList.applyDisplaySize(mWindowManager);
20189 final long origId = Binder.clearCallingIdentity();
20191 if (values != null) {
20192 Settings.System.clearConfiguration(values);
20194 updateConfigurationLocked(values, null, false, false /* persistent */,
20195 UserHandle.USER_NULL, false /* deferResume */,
20196 mTmpUpdateConfigurationResult);
20197 return mTmpUpdateConfigurationResult.changes != 0;
20199 Binder.restoreCallingIdentity(origId);
20204 void updateUserConfigurationLocked() {
20205 final Configuration configuration = new Configuration(getGlobalConfiguration());
20206 final int currentUserId = mUserController.getCurrentUserIdLocked();
20207 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20208 currentUserId, Settings.System.canWrite(mContext));
20209 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20210 false /* persistent */, currentUserId, false /* deferResume */);
20213 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20214 boolean initLocale) {
20215 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20218 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20219 boolean initLocale, boolean deferResume) {
20220 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20221 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20222 UserHandle.USER_NULL, deferResume);
20225 // To cache the list of supported system locales
20226 private String[] mSupportedSystemLocales = null;
20228 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20229 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20230 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20231 deferResume, null /* result */);
20235 * Do either or both things: (1) change the current configuration, and (2)
20236 * make sure the given activity is running with the (now) current
20237 * configuration. Returns true if the activity has been left running, or
20238 * false if <var>starting</var> is being destroyed to match the new
20241 * @param userId is only used when persistent parameter is set to true to persist configuration
20242 * for that particular user
20244 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20245 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20246 UpdateConfigurationResult result) {
20248 boolean kept = true;
20250 if (mWindowManager != null) {
20251 mWindowManager.deferSurfaceLayout();
20254 if (values != null) {
20255 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20259 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20261 if (mWindowManager != null) {
20262 mWindowManager.continueSurfaceLayout();
20266 if (result != null) {
20267 result.changes = changes;
20268 result.activityRelaunched = !kept;
20273 /** Update default (global) configuration and notify listeners about changes. */
20274 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20275 boolean persistent, int userId, boolean deferResume) {
20276 mTempConfig.setTo(getGlobalConfiguration());
20277 final int changes = mTempConfig.updateFrom(values);
20278 if (changes == 0) {
20279 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20280 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20281 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20282 // (even if there are no actual changes) to unfreeze the window.
20283 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20287 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20288 "Updating global configuration to: " + values);
20290 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20292 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20293 final LocaleList locales = values.getLocales();
20294 int bestLocaleIndex = 0;
20295 if (locales.size() > 1) {
20296 if (mSupportedSystemLocales == null) {
20297 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20299 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20301 SystemProperties.set("persist.sys.locale",
20302 locales.get(bestLocaleIndex).toLanguageTag());
20303 LocaleList.setDefault(locales, bestLocaleIndex);
20304 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20305 locales.get(bestLocaleIndex)));
20308 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20309 mTempConfig.seq = mConfigurationSeq;
20311 // Update stored global config and notify everyone about the change.
20312 mStackSupervisor.onConfigurationChanged(mTempConfig);
20314 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20315 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20316 mUsageStatsService.reportConfigurationChange(mTempConfig,
20317 mUserController.getCurrentUserIdLocked());
20319 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20320 mShowDialogs = shouldShowDialogs(mTempConfig);
20322 AttributeCache ac = AttributeCache.instance();
20324 ac.updateConfiguration(mTempConfig);
20327 // Make sure all resources in our process are updated right now, so that anyone who is going
20328 // to retrieve resource values after we return will be sure to get the new ones. This is
20329 // especially important during boot, where the first config change needs to guarantee all
20330 // resources have that config before following boot code is executed.
20331 mSystemThread.applyConfigurationToResources(mTempConfig);
20333 // We need another copy of global config because we're scheduling some calls instead of
20334 // running them in place. We need to be sure that object we send will be handled unchanged.
20335 final Configuration configCopy = new Configuration(mTempConfig);
20336 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20337 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20338 msg.obj = configCopy;
20340 mHandler.sendMessage(msg);
20343 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20344 ProcessRecord app = mLruProcesses.get(i);
20346 if (app.thread != null) {
20347 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20348 + app.processName + " new config " + configCopy);
20349 app.thread.scheduleConfigurationChanged(configCopy);
20351 } catch (Exception e) {
20355 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20356 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20357 | Intent.FLAG_RECEIVER_FOREGROUND
20358 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20359 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20360 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20361 UserHandle.USER_ALL);
20362 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20363 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20364 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20365 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20366 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20367 if (initLocale || !mProcessesReady) {
20368 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20370 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20371 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20372 UserHandle.USER_ALL);
20375 // Override configuration of the default display duplicates global config, so we need to
20376 // update it also. This will also notify WindowManager about changes.
20377 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20384 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20385 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20387 synchronized (this) {
20388 // Check if display is initialized in AM.
20389 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20390 // Call might come when display is not yet added or has already been removed.
20391 if (DEBUG_CONFIGURATION) {
20392 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20398 if (values == null && mWindowManager != null) {
20399 // sentinel: fetch the current configuration from the window manager
20400 values = mWindowManager.computeNewConfiguration(displayId);
20403 if (mWindowManager != null) {
20404 // Update OOM levels based on display size.
20405 mProcessList.applyDisplaySize(mWindowManager);
20408 final long origId = Binder.clearCallingIdentity();
20410 if (values != null) {
20411 Settings.System.clearConfiguration(values);
20413 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20414 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20415 return mTmpUpdateConfigurationResult.changes != 0;
20417 Binder.restoreCallingIdentity(origId);
20422 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20423 boolean deferResume, int displayId) {
20424 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20425 displayId, null /* result */);
20429 * Updates override configuration specific for the selected display. If no config is provided,
20430 * new one will be computed in WM based on current display info.
20432 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20433 ActivityRecord starting, boolean deferResume, int displayId,
20434 UpdateConfigurationResult result) {
20436 boolean kept = true;
20438 if (mWindowManager != null) {
20439 mWindowManager.deferSurfaceLayout();
20442 if (values != null) {
20443 if (displayId == DEFAULT_DISPLAY) {
20444 // Override configuration of the default display duplicates global config, so
20445 // we're calling global config update instead for default display. It will also
20446 // apply the correct override config.
20447 changes = updateGlobalConfiguration(values, false /* initLocale */,
20448 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20450 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20454 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20456 if (mWindowManager != null) {
20457 mWindowManager.continueSurfaceLayout();
20461 if (result != null) {
20462 result.changes = changes;
20463 result.activityRelaunched = !kept;
20468 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20470 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20471 final int changes = mTempConfig.updateFrom(values);
20472 if (changes != 0) {
20473 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20474 + mTempConfig + " for displayId=" + displayId);
20475 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20477 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20478 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20479 // Reset the unsupported display size dialog.
20480 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20482 killAllBackgroundProcessesExcept(N,
20483 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20487 // Update the configuration with WM first and check if any of the stacks need to be resized
20488 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20489 // necessary. This way we don't need to relaunch again afterwards in
20490 // ensureActivityConfigurationLocked().
20491 if (mWindowManager != null) {
20492 final int[] resizedStacks =
20493 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20494 if (resizedStacks != null) {
20495 for (int stackId : resizedStacks) {
20496 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20504 /** Applies latest configuration and/or visibility updates if needed. */
20505 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20506 boolean kept = true;
20507 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20508 // mainStack is null during startup.
20509 if (mainStack != null) {
20510 if (changes != 0 && starting == null) {
20511 // If the configuration changed, and the caller is not already
20512 // in the process of starting an activity, then find the top
20513 // activity to check if its configuration needs to change.
20514 starting = mainStack.topRunningActivityLocked();
20517 if (starting != null) {
20518 kept = starting.ensureActivityConfigurationLocked(changes,
20519 false /* preserveWindow */);
20520 // And we need to make sure at this point that all other activities
20521 // are made visible with the correct configuration.
20522 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20523 !PRESERVE_WINDOWS);
20530 /** Helper method that requests bounds from WM and applies them to stack. */
20531 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20532 final Rect newStackBounds = new Rect();
20533 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20534 mStackSupervisor.resizeStackLocked(
20535 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20536 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20537 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20541 * Decide based on the configuration whether we should show the ANR,
20542 * crash, etc dialogs. The idea is that if there is no affordance to
20543 * press the on-screen buttons, or the user experience would be more
20544 * greatly impacted than the crash itself, we shouldn't show the dialog.
20546 * A thought: SystemUI might also want to get told about this, the Power
20547 * dialog / global actions also might want different behaviors.
20549 private static boolean shouldShowDialogs(Configuration config) {
20550 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20551 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20552 && config.navigation == Configuration.NAVIGATION_NONAV);
20553 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20554 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20555 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20556 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20557 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20558 return inputMethodExists && uiModeSupportsDialogs;
20562 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20563 synchronized (this) {
20564 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20565 if (srec != null) {
20566 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20572 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20573 Intent resultData) {
20575 synchronized (this) {
20576 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20578 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20584 public int getLaunchedFromUid(IBinder activityToken) {
20585 ActivityRecord srec;
20586 synchronized (this) {
20587 srec = ActivityRecord.forTokenLocked(activityToken);
20589 if (srec == null) {
20592 return srec.launchedFromUid;
20595 public String getLaunchedFromPackage(IBinder activityToken) {
20596 ActivityRecord srec;
20597 synchronized (this) {
20598 srec = ActivityRecord.forTokenLocked(activityToken);
20600 if (srec == null) {
20603 return srec.launchedFromPackage;
20606 // =========================================================
20607 // LIFETIME MANAGEMENT
20608 // =========================================================
20610 // Returns whether the app is receiving broadcast.
20611 // If receiving, fetch all broadcast queues which the app is
20612 // the current [or imminent] receiver on.
20613 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20614 ArraySet<BroadcastQueue> receivingQueues) {
20615 if (!app.curReceivers.isEmpty()) {
20616 for (BroadcastRecord r : app.curReceivers) {
20617 receivingQueues.add(r.queue);
20622 // It's not the current receiver, but it might be starting up to become one
20623 for (BroadcastQueue queue : mBroadcastQueues) {
20624 final BroadcastRecord r = queue.mPendingBroadcast;
20625 if (r != null && r.curApp == app) {
20626 // found it; report which queue it's in
20627 receivingQueues.add(queue);
20631 return !receivingQueues.isEmpty();
20634 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20635 int targetUid, ComponentName targetComponent, String targetProcess) {
20636 if (!mTrackingAssociations) {
20639 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20640 = mAssociations.get(targetUid);
20641 if (components == null) {
20642 components = new ArrayMap<>();
20643 mAssociations.put(targetUid, components);
20645 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20646 if (sourceUids == null) {
20647 sourceUids = new SparseArray<>();
20648 components.put(targetComponent, sourceUids);
20650 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20651 if (sourceProcesses == null) {
20652 sourceProcesses = new ArrayMap<>();
20653 sourceUids.put(sourceUid, sourceProcesses);
20655 Association ass = sourceProcesses.get(sourceProcess);
20657 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20659 sourceProcesses.put(sourceProcess, ass);
20663 if (ass.mNesting == 1) {
20664 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20665 ass.mLastState = sourceState;
20670 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20671 ComponentName targetComponent) {
20672 if (!mTrackingAssociations) {
20675 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20676 = mAssociations.get(targetUid);
20677 if (components == null) {
20680 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20681 if (sourceUids == null) {
20684 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20685 if (sourceProcesses == null) {
20688 Association ass = sourceProcesses.get(sourceProcess);
20689 if (ass == null || ass.mNesting <= 0) {
20693 if (ass.mNesting == 0) {
20694 long uptime = SystemClock.uptimeMillis();
20695 ass.mTime += uptime - ass.mStartTime;
20696 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20697 += uptime - ass.mLastStateUptime;
20698 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20702 private void noteUidProcessState(final int uid, final int state) {
20703 mBatteryStatsService.noteUidProcessState(uid, state);
20704 if (mTrackingAssociations) {
20705 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20706 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20707 = mAssociations.valueAt(i1);
20708 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20709 SparseArray<ArrayMap<String, Association>> sourceUids
20710 = targetComponents.valueAt(i2);
20711 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20712 if (sourceProcesses != null) {
20713 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20714 Association ass = sourceProcesses.valueAt(i4);
20715 if (ass.mNesting >= 1) {
20716 // currently associated
20717 long uptime = SystemClock.uptimeMillis();
20718 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20719 += uptime - ass.mLastStateUptime;
20720 ass.mLastState = state;
20721 ass.mLastStateUptime = uptime;
20730 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20731 boolean doingAll, long now) {
20732 if (mAdjSeq == app.adjSeq) {
20733 // This adjustment has already been computed.
20734 return app.curRawAdj;
20737 if (app.thread == null) {
20738 app.adjSeq = mAdjSeq;
20739 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20740 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20741 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20744 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20745 app.adjSource = null;
20746 app.adjTarget = null;
20748 app.cached = false;
20750 final int activitiesSize = app.activities.size();
20752 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20753 // The max adjustment doesn't allow this app to be anything
20754 // below foreground, so it is not worth doing work for it.
20755 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20756 app.adjType = "fixed";
20757 app.adjSeq = mAdjSeq;
20758 app.curRawAdj = app.maxAdj;
20759 app.foregroundActivities = false;
20760 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20761 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20762 // System processes can do UI, and when they do we want to have
20763 // them trim their memory after the user leaves the UI. To
20764 // facilitate this, here we need to determine whether or not it
20765 // is currently showing UI.
20766 app.systemNoUi = true;
20767 if (app == TOP_APP) {
20768 app.systemNoUi = false;
20769 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20770 app.adjType = "pers-top-activity";
20771 } else if (app.hasTopUi) {
20772 app.systemNoUi = false;
20773 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20774 app.adjType = "pers-top-ui";
20775 } else if (activitiesSize > 0) {
20776 for (int j = 0; j < activitiesSize; j++) {
20777 final ActivityRecord r = app.activities.get(j);
20779 app.systemNoUi = false;
20783 if (!app.systemNoUi) {
20784 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20786 return (app.curAdj=app.maxAdj);
20789 app.systemNoUi = false;
20791 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20793 // Determine the importance of the process, starting with most
20794 // important to least, and assign an appropriate OOM adjustment.
20798 boolean foregroundActivities = false;
20799 mTmpBroadcastQueue.clear();
20800 if (app == TOP_APP) {
20801 // The last app on the list is the foreground app.
20802 adj = ProcessList.FOREGROUND_APP_ADJ;
20803 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20804 app.adjType = "top-activity";
20805 foregroundActivities = true;
20806 procState = PROCESS_STATE_CUR_TOP;
20807 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20808 } else if (app.instr != null) {
20809 // Don't want to kill running instrumentation.
20810 adj = ProcessList.FOREGROUND_APP_ADJ;
20811 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20812 app.adjType = "instrumentation";
20813 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20814 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20815 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20816 // An app that is currently receiving a broadcast also
20817 // counts as being in the foreground for OOM killer purposes.
20818 // It's placed in a sched group based on the nature of the
20819 // broadcast as reflected by which queue it's active in.
20820 adj = ProcessList.FOREGROUND_APP_ADJ;
20821 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20822 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20823 app.adjType = "broadcast";
20824 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20825 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20826 } else if (app.executingServices.size() > 0) {
20827 // An app that is currently executing a service callback also
20828 // counts as being in the foreground.
20829 adj = ProcessList.FOREGROUND_APP_ADJ;
20830 schedGroup = app.execServicesFg ?
20831 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20832 app.adjType = "exec-service";
20833 procState = ActivityManager.PROCESS_STATE_SERVICE;
20834 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20835 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20837 // As far as we know the process is empty. We may change our mind later.
20838 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20839 // At this point we don't actually know the adjustment. Use the cached adj
20840 // value that the caller wants us to.
20842 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20845 app.adjType = "cch-empty";
20846 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20849 // Examine all activities if not already foreground.
20850 if (!foregroundActivities && activitiesSize > 0) {
20851 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20852 for (int j = 0; j < activitiesSize; j++) {
20853 final ActivityRecord r = app.activities.get(j);
20854 if (r.app != app) {
20855 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20856 + " instead of expected " + app);
20857 if (r.app == null || (r.app.uid == app.uid)) {
20858 // Only fix things up when they look sane
20865 // App has a visible activity; only upgrade adjustment.
20866 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20867 adj = ProcessList.VISIBLE_APP_ADJ;
20868 app.adjType = "vis-activity";
20869 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20871 if (procState > PROCESS_STATE_CUR_TOP) {
20872 procState = PROCESS_STATE_CUR_TOP;
20873 app.adjType = "vis-activity";
20874 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20876 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20877 app.cached = false;
20879 foregroundActivities = true;
20880 final TaskRecord task = r.getTask();
20881 if (task != null && minLayer > 0) {
20882 final int layer = task.mLayerRank;
20883 if (layer >= 0 && minLayer > layer) {
20888 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20889 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20890 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20891 app.adjType = "pause-activity";
20892 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20894 if (procState > PROCESS_STATE_CUR_TOP) {
20895 procState = PROCESS_STATE_CUR_TOP;
20896 app.adjType = "pause-activity";
20897 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20899 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20900 app.cached = false;
20902 foregroundActivities = true;
20903 } else if (r.state == ActivityState.STOPPING) {
20904 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20905 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20906 app.adjType = "stop-activity";
20907 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20909 // For the process state, we will at this point consider the
20910 // process to be cached. It will be cached either as an activity
20911 // or empty depending on whether the activity is finishing. We do
20912 // this so that we can treat the process as cached for purposes of
20913 // memory trimming (determing current memory level, trim command to
20914 // send to process) since there can be an arbitrary number of stopping
20915 // processes and they should soon all go into the cached state.
20916 if (!r.finishing) {
20917 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20918 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20919 app.adjType = "stop-activity";
20920 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20923 app.cached = false;
20925 foregroundActivities = true;
20927 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20928 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20929 app.adjType = "cch-act";
20930 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20934 if (adj == ProcessList.VISIBLE_APP_ADJ) {
20939 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20940 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20941 if (app.foregroundServices) {
20942 // The user is aware of this app, so make it visible.
20943 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20944 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20945 app.cached = false;
20946 app.adjType = "fg-service";
20947 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20948 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
20949 } else if (app.hasOverlayUi) {
20950 // The process is display an overlay UI.
20951 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20952 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20953 app.cached = false;
20954 app.adjType = "has-overlay-ui";
20955 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20956 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
20960 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20961 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
20962 if (app.forcingToImportant != null) {
20963 // This is currently used for toasts... they are not interactive, and
20964 // we don't want them to cause the app to become fully foreground (and
20965 // thus out of background check), so we yes the best background level we can.
20966 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20967 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
20968 app.cached = false;
20969 app.adjType = "force-imp";
20970 app.adjSource = app.forcingToImportant;
20971 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20972 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
20976 if (app == mHeavyWeightProcess) {
20977 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20978 // We don't want to kill the current heavy-weight process.
20979 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20980 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20981 app.cached = false;
20982 app.adjType = "heavy";
20983 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
20985 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20986 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20987 app.adjType = "heavy";
20988 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
20992 if (app == mHomeProcess) {
20993 if (adj > ProcessList.HOME_APP_ADJ) {
20994 // This process is hosting what we currently consider to be the
20995 // home app, so we don't want to let it go into the background.
20996 adj = ProcessList.HOME_APP_ADJ;
20997 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20998 app.cached = false;
20999 app.adjType = "home";
21000 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21002 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21003 procState = ActivityManager.PROCESS_STATE_HOME;
21004 app.adjType = "home";
21005 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21009 if (app == mPreviousProcess && app.activities.size() > 0) {
21010 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21011 // This was the previous process that showed UI to the user.
21012 // We want to try to keep it around more aggressively, to give
21013 // a good experience around switching between two apps.
21014 adj = ProcessList.PREVIOUS_APP_ADJ;
21015 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21016 app.cached = false;
21017 app.adjType = "previous";
21018 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21020 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21021 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21022 app.adjType = "previous";
21023 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21027 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21028 + " reason=" + app.adjType);
21030 // By default, we use the computed adjustment. It may be changed if
21031 // there are applications dependent on our services or providers, but
21032 // this gives us a baseline and makes sure we don't get into an
21033 // infinite recursion.
21034 app.adjSeq = mAdjSeq;
21035 app.curRawAdj = adj;
21036 app.hasStartedServices = false;
21038 if (mBackupTarget != null && app == mBackupTarget.app) {
21039 // If possible we want to avoid killing apps while they're being backed up
21040 if (adj > ProcessList.BACKUP_APP_ADJ) {
21041 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21042 adj = ProcessList.BACKUP_APP_ADJ;
21043 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21044 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21046 app.adjType = "backup";
21047 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21048 app.cached = false;
21050 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21051 procState = ActivityManager.PROCESS_STATE_BACKUP;
21052 app.adjType = "backup";
21053 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21057 boolean mayBeTop = false;
21058 String mayBeTopType = null;
21059 Object mayBeTopSource = null;
21060 Object mayBeTopTarget = null;
21062 for (int is = app.services.size()-1;
21063 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21064 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21065 || procState > ActivityManager.PROCESS_STATE_TOP);
21067 ServiceRecord s = app.services.valueAt(is);
21068 if (s.startRequested) {
21069 app.hasStartedServices = true;
21070 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21071 procState = ActivityManager.PROCESS_STATE_SERVICE;
21072 app.adjType = "started-services";
21073 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21075 if (app.hasShownUi && app != mHomeProcess) {
21076 // If this process has shown some UI, let it immediately
21077 // go to the LRU list because it may be pretty heavy with
21078 // UI stuff. We'll tag it with a label just to help
21079 // debug and understand what is going on.
21080 if (adj > ProcessList.SERVICE_ADJ) {
21081 app.adjType = "cch-started-ui-services";
21084 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21085 // This service has seen some activity within
21086 // recent memory, so we will keep its process ahead
21087 // of the background processes.
21088 if (adj > ProcessList.SERVICE_ADJ) {
21089 adj = ProcessList.SERVICE_ADJ;
21090 app.adjType = "started-services";
21091 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21092 app.cached = false;
21095 // If we have let the service slide into the background
21096 // state, still have some text describing what it is doing
21097 // even though the service no longer has an impact.
21098 if (adj > ProcessList.SERVICE_ADJ) {
21099 app.adjType = "cch-started-services";
21104 for (int conni = s.connections.size()-1;
21105 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21106 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21107 || procState > ActivityManager.PROCESS_STATE_TOP);
21109 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21111 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21112 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21113 || procState > ActivityManager.PROCESS_STATE_TOP);
21115 // XXX should compute this based on the max of
21116 // all connected clients.
21117 ConnectionRecord cr = clist.get(i);
21118 if (cr.binding.client == app) {
21119 // Binding to ourself is not interesting.
21123 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21124 ProcessRecord client = cr.binding.client;
21125 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21126 TOP_APP, doingAll, now);
21127 int clientProcState = client.curProcState;
21128 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21129 // If the other app is cached for any reason, for purposes here
21130 // we are going to consider it empty. The specific cached state
21131 // doesn't propagate except under certain conditions.
21132 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21134 String adjType = null;
21135 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21136 // Not doing bind OOM management, so treat
21137 // this guy more like a started service.
21138 if (app.hasShownUi && app != mHomeProcess) {
21139 // If this process has shown some UI, let it immediately
21140 // go to the LRU list because it may be pretty heavy with
21141 // UI stuff. We'll tag it with a label just to help
21142 // debug and understand what is going on.
21143 if (adj > clientAdj) {
21144 adjType = "cch-bound-ui-services";
21146 app.cached = false;
21148 clientProcState = procState;
21150 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21151 // This service has not seen activity within
21152 // recent memory, so allow it to drop to the
21153 // LRU list if there is no other reason to keep
21154 // it around. We'll also tag it with a label just
21155 // to help debug and undertand what is going on.
21156 if (adj > clientAdj) {
21157 adjType = "cch-bound-services";
21163 if (adj > clientAdj) {
21164 // If this process has recently shown UI, and
21165 // the process that is binding to it is less
21166 // important than being visible, then we don't
21167 // care about the binding as much as we care
21168 // about letting this process get into the LRU
21169 // list to be killed and restarted if needed for
21171 if (app.hasShownUi && app != mHomeProcess
21172 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21173 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21174 adjType = "cch-bound-ui-services";
21178 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21179 |Context.BIND_IMPORTANT)) != 0) {
21180 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21181 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21182 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21183 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21184 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21185 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21186 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21187 newAdj = clientAdj;
21189 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21190 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21195 if (!client.cached) {
21196 app.cached = false;
21198 if (adj > newAdj) {
21200 adjType = "service";
21204 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21205 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21206 // This will treat important bound services identically to
21207 // the top app, which may behave differently than generic
21208 // foreground work.
21209 if (client.curSchedGroup > schedGroup) {
21210 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21211 schedGroup = client.curSchedGroup;
21213 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21216 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21217 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21218 // Special handling of clients who are in the top state.
21219 // We *may* want to consider this process to be in the
21220 // top state as well, but only if there is not another
21221 // reason for it to be running. Being on the top is a
21222 // special state, meaning you are specifically running
21223 // for the current top app. If the process is already
21224 // running in the background for some other reason, it
21225 // is more important to continue considering it to be
21226 // in the background state.
21228 mayBeTopType = "service";
21229 mayBeTopSource = cr.binding.client;
21230 mayBeTopTarget = s.name;
21231 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21233 // Special handling for above-top states (persistent
21234 // processes). These should not bring the current process
21235 // into the top state, since they are not on top. Instead
21236 // give them the best state after that.
21237 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21239 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21240 } else if (mWakefulness
21241 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21242 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21245 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21248 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21252 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21253 if (clientProcState <
21254 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21256 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21259 if (clientProcState <
21260 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21262 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21265 if (procState > clientProcState) {
21266 procState = clientProcState;
21267 if (adjType == null) {
21268 adjType = "service";
21271 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21272 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21273 app.pendingUiClean = true;
21275 if (adjType != null) {
21276 app.adjType = adjType;
21277 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21278 .REASON_SERVICE_IN_USE;
21279 app.adjSource = cr.binding.client;
21280 app.adjSourceProcState = clientProcState;
21281 app.adjTarget = s.name;
21282 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21283 + ": " + app + ", due to " + cr.binding.client
21284 + " adj=" + adj + " procState=" + procState);
21287 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21288 app.treatLikeActivity = true;
21290 final ActivityRecord a = cr.activity;
21291 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21292 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21293 (a.visible || a.state == ActivityState.RESUMED ||
21294 a.state == ActivityState.PAUSING)) {
21295 adj = ProcessList.FOREGROUND_APP_ADJ;
21296 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21297 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21298 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21300 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21303 app.cached = false;
21304 app.adjType = "service";
21305 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21306 .REASON_SERVICE_IN_USE;
21308 app.adjSourceProcState = procState;
21309 app.adjTarget = s.name;
21310 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21318 for (int provi = app.pubProviders.size()-1;
21319 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21320 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21321 || procState > ActivityManager.PROCESS_STATE_TOP);
21323 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21324 for (int i = cpr.connections.size()-1;
21325 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21326 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21327 || procState > ActivityManager.PROCESS_STATE_TOP);
21329 ContentProviderConnection conn = cpr.connections.get(i);
21330 ProcessRecord client = conn.client;
21331 if (client == app) {
21332 // Being our own client is not interesting.
21335 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21336 int clientProcState = client.curProcState;
21337 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21338 // If the other app is cached for any reason, for purposes here
21339 // we are going to consider it empty.
21340 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21342 String adjType = null;
21343 if (adj > clientAdj) {
21344 if (app.hasShownUi && app != mHomeProcess
21345 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21346 adjType = "cch-ui-provider";
21348 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21349 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21350 adjType = "provider";
21352 app.cached &= client.cached;
21354 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21355 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21356 // Special handling of clients who are in the top state.
21357 // We *may* want to consider this process to be in the
21358 // top state as well, but only if there is not another
21359 // reason for it to be running. Being on the top is a
21360 // special state, meaning you are specifically running
21361 // for the current top app. If the process is already
21362 // running in the background for some other reason, it
21363 // is more important to continue considering it to be
21364 // in the background state.
21366 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21367 mayBeTopType = adjType = "provider-top";
21368 mayBeTopSource = client;
21369 mayBeTopTarget = cpr.name;
21371 // Special handling for above-top states (persistent
21372 // processes). These should not bring the current process
21373 // into the top state, since they are not on top. Instead
21374 // give them the best state after that.
21376 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21377 if (adjType == null) {
21378 adjType = "provider";
21382 if (procState > clientProcState) {
21383 procState = clientProcState;
21385 if (client.curSchedGroup > schedGroup) {
21386 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21388 if (adjType != null) {
21389 app.adjType = adjType;
21390 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21391 .REASON_PROVIDER_IN_USE;
21392 app.adjSource = client;
21393 app.adjSourceProcState = clientProcState;
21394 app.adjTarget = cpr.name;
21395 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21396 + ": " + app + ", due to " + client
21397 + " adj=" + adj + " procState=" + procState);
21400 // If the provider has external (non-framework) process
21401 // dependencies, ensure that its adjustment is at least
21402 // FOREGROUND_APP_ADJ.
21403 if (cpr.hasExternalProcessHandles()) {
21404 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21405 adj = ProcessList.FOREGROUND_APP_ADJ;
21406 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21407 app.cached = false;
21408 app.adjType = "ext-provider";
21409 app.adjTarget = cpr.name;
21410 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21412 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21413 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21418 if (app.lastProviderTime > 0 &&
21419 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21420 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21421 adj = ProcessList.PREVIOUS_APP_ADJ;
21422 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21423 app.cached = false;
21424 app.adjType = "recent-provider";
21425 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21427 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21428 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21429 app.adjType = "recent-provider";
21430 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21434 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21435 // A client of one of our services or providers is in the top state. We
21436 // *may* want to be in the top state, but not if we are already running in
21437 // the background for some other reason. For the decision here, we are going
21438 // to pick out a few specific states that we want to remain in when a client
21439 // is top (states that tend to be longer-term) and otherwise allow it to go
21440 // to the top state.
21441 switch (procState) {
21442 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21443 // Something else is keeping it at this level, just leave it.
21445 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21446 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21447 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21448 case ActivityManager.PROCESS_STATE_SERVICE:
21449 // These all are longer-term states, so pull them up to the top
21450 // of the background states, but not all the way to the top state.
21451 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21452 app.adjType = mayBeTopType;
21453 app.adjSource = mayBeTopSource;
21454 app.adjTarget = mayBeTopTarget;
21455 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21456 + ": " + app + ", due to " + mayBeTopSource
21457 + " adj=" + adj + " procState=" + procState);
21460 // Otherwise, top is a better choice, so take it.
21461 procState = ActivityManager.PROCESS_STATE_TOP;
21462 app.adjType = mayBeTopType;
21463 app.adjSource = mayBeTopSource;
21464 app.adjTarget = mayBeTopTarget;
21465 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21466 + ": " + app + ", due to " + mayBeTopSource
21467 + " adj=" + adj + " procState=" + procState);
21472 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21473 if (app.hasClientActivities) {
21474 // This is a cached process, but with client activities. Mark it so.
21475 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21476 app.adjType = "cch-client-act";
21477 } else if (app.treatLikeActivity) {
21478 // This is a cached process, but somebody wants us to treat it like it has
21479 // an activity, okay!
21480 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21481 app.adjType = "cch-as-act";
21485 if (adj == ProcessList.SERVICE_ADJ) {
21487 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21488 mNewNumServiceProcs++;
21489 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21490 if (!app.serviceb) {
21491 // This service isn't far enough down on the LRU list to
21492 // normally be a B service, but if we are low on RAM and it
21493 // is large we want to force it down since we would prefer to
21494 // keep launcher over it.
21495 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21496 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21497 app.serviceHighRam = true;
21498 app.serviceb = true;
21499 //Slog.i(TAG, "ADJ " + app + " high ram!");
21501 mNewNumAServiceProcs++;
21502 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21505 app.serviceHighRam = false;
21508 if (app.serviceb) {
21509 adj = ProcessList.SERVICE_B_ADJ;
21513 app.curRawAdj = adj;
21515 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21516 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21517 if (adj > app.maxAdj) {
21519 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21520 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21524 // Do final modification to adj. Everything we do between here and applying
21525 // the final setAdj must be done in this function, because we will also use
21526 // it when computing the final cached adj later. Note that we don't need to
21527 // worry about this for max adj above, since max adj will always be used to
21528 // keep it out of the cached vaues.
21529 app.curAdj = app.modifyRawOomAdj(adj);
21530 app.curSchedGroup = schedGroup;
21531 app.curProcState = procState;
21532 app.foregroundActivities = foregroundActivities;
21534 return app.curRawAdj;
21538 * Record new PSS sample for a process.
21540 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21542 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21544 proc.lastPssTime = now;
21545 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21546 if (DEBUG_PSS) Slog.d(TAG_PSS,
21547 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21548 + " state=" + ProcessList.makeProcStateString(procState));
21549 if (proc.initialIdlePss == 0) {
21550 proc.initialIdlePss = pss;
21552 proc.lastPss = pss;
21553 proc.lastSwapPss = swapPss;
21554 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21555 proc.lastCachedPss = pss;
21556 proc.lastCachedSwapPss = swapPss;
21559 final SparseArray<Pair<Long, String>> watchUids
21560 = mMemWatchProcesses.getMap().get(proc.processName);
21562 if (watchUids != null) {
21563 Pair<Long, String> val = watchUids.get(proc.uid);
21565 val = watchUids.get(0);
21571 if (check != null) {
21572 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21573 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21574 if (!isDebuggable) {
21575 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21576 isDebuggable = true;
21579 if (isDebuggable) {
21580 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21581 final ProcessRecord myProc = proc;
21582 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21583 mMemWatchDumpProcName = proc.processName;
21584 mMemWatchDumpFile = heapdumpFile.toString();
21585 mMemWatchDumpPid = proc.pid;
21586 mMemWatchDumpUid = proc.uid;
21587 BackgroundThread.getHandler().post(new Runnable() {
21589 public void run() {
21590 revokeUriPermission(ActivityThread.currentActivityThread()
21591 .getApplicationThread(),
21592 null, DumpHeapActivity.JAVA_URI,
21593 Intent.FLAG_GRANT_READ_URI_PERMISSION
21594 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21595 UserHandle.myUserId());
21596 ParcelFileDescriptor fd = null;
21598 heapdumpFile.delete();
21599 fd = ParcelFileDescriptor.open(heapdumpFile,
21600 ParcelFileDescriptor.MODE_CREATE |
21601 ParcelFileDescriptor.MODE_TRUNCATE |
21602 ParcelFileDescriptor.MODE_WRITE_ONLY |
21603 ParcelFileDescriptor.MODE_APPEND);
21604 IApplicationThread thread = myProc.thread;
21605 if (thread != null) {
21607 if (DEBUG_PSS) Slog.d(TAG_PSS,
21608 "Requesting dump heap from "
21609 + myProc + " to " + heapdumpFile);
21610 thread.dumpHeap(true, heapdumpFile.toString(), fd);
21611 } catch (RemoteException e) {
21614 } catch (FileNotFoundException e) {
21615 e.printStackTrace();
21620 } catch (IOException e) {
21627 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21628 + ", but debugging not enabled");
21635 * Schedule PSS collection of a process.
21637 void requestPssLocked(ProcessRecord proc, int procState) {
21638 if (mPendingPssProcesses.contains(proc)) {
21641 if (mPendingPssProcesses.size() == 0) {
21642 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21644 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21645 proc.pssProcState = procState;
21646 mPendingPssProcesses.add(proc);
21650 * Schedule PSS collection of all processes.
21652 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21654 if (now < (mLastFullPssTime +
21655 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21656 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21660 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21661 mLastFullPssTime = now;
21662 mFullPssPending = true;
21663 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21664 mPendingPssProcesses.clear();
21665 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21666 ProcessRecord app = mLruProcesses.get(i);
21667 if (app.thread == null
21668 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21671 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21672 app.pssProcState = app.setProcState;
21673 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21674 mTestPssMode, isSleepingLocked(), now);
21675 mPendingPssProcesses.add(app);
21678 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21681 public void setTestPssMode(boolean enabled) {
21682 synchronized (this) {
21683 mTestPssMode = enabled;
21685 // Whenever we enable the mode, we want to take a snapshot all of current
21686 // process mem use.
21687 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21693 * Ask a given process to GC right now.
21695 final void performAppGcLocked(ProcessRecord app) {
21697 app.lastRequestedGc = SystemClock.uptimeMillis();
21698 if (app.thread != null) {
21699 if (app.reportLowMemory) {
21700 app.reportLowMemory = false;
21701 app.thread.scheduleLowMemory();
21703 app.thread.processInBackground();
21706 } catch (Exception e) {
21712 * Returns true if things are idle enough to perform GCs.
21714 private final boolean canGcNowLocked() {
21715 boolean processingBroadcasts = false;
21716 for (BroadcastQueue q : mBroadcastQueues) {
21717 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21718 processingBroadcasts = true;
21721 return !processingBroadcasts
21722 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21726 * Perform GCs on all processes that are waiting for it, but only
21727 * if things are idle.
21729 final void performAppGcsLocked() {
21730 final int N = mProcessesToGc.size();
21734 if (canGcNowLocked()) {
21735 while (mProcessesToGc.size() > 0) {
21736 ProcessRecord proc = mProcessesToGc.remove(0);
21737 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21738 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21739 <= SystemClock.uptimeMillis()) {
21740 // To avoid spamming the system, we will GC processes one
21741 // at a time, waiting a few seconds between each.
21742 performAppGcLocked(proc);
21743 scheduleAppGcsLocked();
21746 // It hasn't been long enough since we last GCed this
21747 // process... put it in the list to wait for its time.
21748 addProcessToGcListLocked(proc);
21754 scheduleAppGcsLocked();
21759 * If all looks good, perform GCs on all processes waiting for them.
21761 final void performAppGcsIfAppropriateLocked() {
21762 if (canGcNowLocked()) {
21763 performAppGcsLocked();
21766 // Still not idle, wait some more.
21767 scheduleAppGcsLocked();
21771 * Schedule the execution of all pending app GCs.
21773 final void scheduleAppGcsLocked() {
21774 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21776 if (mProcessesToGc.size() > 0) {
21777 // Schedule a GC for the time to the next process.
21778 ProcessRecord proc = mProcessesToGc.get(0);
21779 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21781 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21782 long now = SystemClock.uptimeMillis();
21783 if (when < (now+mConstants.GC_TIMEOUT)) {
21784 when = now + mConstants.GC_TIMEOUT;
21786 mHandler.sendMessageAtTime(msg, when);
21791 * Add a process to the array of processes waiting to be GCed. Keeps the
21792 * list in sorted order by the last GC time. The process can't already be
21795 final void addProcessToGcListLocked(ProcessRecord proc) {
21796 boolean added = false;
21797 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21798 if (mProcessesToGc.get(i).lastRequestedGc <
21799 proc.lastRequestedGc) {
21801 mProcessesToGc.add(i+1, proc);
21806 mProcessesToGc.add(0, proc);
21811 * Set up to ask a process to GC itself. This will either do it
21812 * immediately, or put it on the list of processes to gc the next
21813 * time things are idle.
21815 final void scheduleAppGcLocked(ProcessRecord app) {
21816 long now = SystemClock.uptimeMillis();
21817 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21820 if (!mProcessesToGc.contains(app)) {
21821 addProcessToGcListLocked(app);
21822 scheduleAppGcsLocked();
21826 final void checkExcessivePowerUsageLocked(boolean doKills) {
21827 updateCpuStatsNow();
21829 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21830 boolean doWakeKills = doKills;
21831 boolean doCpuKills = doKills;
21832 if (mLastPowerCheckRealtime == 0) {
21833 doWakeKills = false;
21835 if (mLastPowerCheckUptime == 0) {
21836 doCpuKills = false;
21838 if (stats.isScreenOn()) {
21839 doWakeKills = false;
21841 final long curRealtime = SystemClock.elapsedRealtime();
21842 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21843 final long curUptime = SystemClock.uptimeMillis();
21844 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21845 mLastPowerCheckRealtime = curRealtime;
21846 mLastPowerCheckUptime = curUptime;
21847 if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21848 doWakeKills = false;
21850 if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21851 doCpuKills = false;
21853 int i = mLruProcesses.size();
21856 ProcessRecord app = mLruProcesses.get(i);
21857 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21859 synchronized (stats) {
21860 wtime = stats.getProcessWakeTime(app.info.uid,
21861 app.pid, curRealtime);
21863 long wtimeUsed = wtime - app.lastWakeTime;
21864 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21866 StringBuilder sb = new StringBuilder(128);
21867 sb.append("Wake for ");
21868 app.toShortString(sb);
21869 sb.append(": over ");
21870 TimeUtils.formatDuration(realtimeSince, sb);
21871 sb.append(" used ");
21872 TimeUtils.formatDuration(wtimeUsed, sb);
21874 sb.append((wtimeUsed*100)/realtimeSince);
21876 Slog.i(TAG_POWER, sb.toString());
21878 sb.append("CPU for ");
21879 app.toShortString(sb);
21880 sb.append(": over ");
21881 TimeUtils.formatDuration(uptimeSince, sb);
21882 sb.append(" used ");
21883 TimeUtils.formatDuration(cputimeUsed, sb);
21885 sb.append((cputimeUsed*100)/uptimeSince);
21887 Slog.i(TAG_POWER, sb.toString());
21889 // If a process has held a wake lock for more
21890 // than 50% of the time during this period,
21891 // that sounds bad. Kill!
21892 if (doWakeKills && realtimeSince > 0
21893 && ((wtimeUsed*100)/realtimeSince) >= 50) {
21894 synchronized (stats) {
21895 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21896 realtimeSince, wtimeUsed);
21898 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21899 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21900 } else if (doCpuKills && uptimeSince > 0
21901 && ((cputimeUsed*100)/uptimeSince) >= 25) {
21902 synchronized (stats) {
21903 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21904 uptimeSince, cputimeUsed);
21906 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21907 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21909 app.lastWakeTime = wtime;
21910 app.lastCpuTime = app.curCpuTime;
21916 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21918 boolean success = true;
21920 if (app.curRawAdj != app.setRawAdj) {
21921 app.setRawAdj = app.curRawAdj;
21926 if (app.curAdj != app.setAdj) {
21927 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21928 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21929 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21931 app.setAdj = app.curAdj;
21932 app.verifiedAdj = ProcessList.INVALID_ADJ;
21935 if (app.setSchedGroup != app.curSchedGroup) {
21936 int oldSchedGroup = app.setSchedGroup;
21937 app.setSchedGroup = app.curSchedGroup;
21938 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21939 "Setting sched group of " + app.processName
21940 + " to " + app.curSchedGroup);
21941 if (app.waitingToKill != null && app.curReceivers.isEmpty()
21942 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21943 app.kill(app.waitingToKill, true);
21947 switch (app.curSchedGroup) {
21948 case ProcessList.SCHED_GROUP_BACKGROUND:
21949 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21951 case ProcessList.SCHED_GROUP_TOP_APP:
21952 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21953 processGroup = THREAD_GROUP_TOP_APP;
21956 processGroup = THREAD_GROUP_DEFAULT;
21959 long oldId = Binder.clearCallingIdentity();
21961 setProcessGroup(app.pid, processGroup);
21962 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21963 // do nothing if we already switched to RT
21964 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21965 mVrController.onTopProcChangedLocked(app);
21966 if (mUseFifoUiScheduling) {
21967 // Switch UI pipeline for app to SCHED_FIFO
21968 app.savedPriority = Process.getThreadPriority(app.pid);
21969 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
21970 if (app.renderThreadTid != 0) {
21971 scheduleAsFifoPriority(app.renderThreadTid,
21972 /* suppressLogs */true);
21973 if (DEBUG_OOM_ADJ) {
21974 Slog.d("UI_FIFO", "Set RenderThread (TID " +
21975 app.renderThreadTid + ") to FIFO");
21978 if (DEBUG_OOM_ADJ) {
21979 Slog.d("UI_FIFO", "Not setting RenderThread TID");
21983 // Boost priority for top app UI and render threads
21984 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
21985 if (app.renderThreadTid != 0) {
21987 setThreadPriority(app.renderThreadTid,
21988 TOP_APP_PRIORITY_BOOST);
21989 } catch (IllegalArgumentException e) {
21990 // thread died, ignore
21995 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21996 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21997 mVrController.onTopProcChangedLocked(app);
21998 if (mUseFifoUiScheduling) {
21999 // Reset UI pipeline to SCHED_OTHER
22000 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22001 setThreadPriority(app.pid, app.savedPriority);
22002 if (app.renderThreadTid != 0) {
22003 setThreadScheduler(app.renderThreadTid,
22005 setThreadPriority(app.renderThreadTid, -4);
22008 // Reset priority for top app UI and render threads
22009 setThreadPriority(app.pid, 0);
22010 if (app.renderThreadTid != 0) {
22011 setThreadPriority(app.renderThreadTid, 0);
22015 } catch (Exception e) {
22017 Slog.w(TAG, "Failed setting process group of " + app.pid
22018 + " to " + app.curSchedGroup);
22019 Slog.w(TAG, "at location", e);
22022 Binder.restoreCallingIdentity(oldId);
22026 if (app.repForegroundActivities != app.foregroundActivities) {
22027 app.repForegroundActivities = app.foregroundActivities;
22028 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22030 if (app.repProcState != app.curProcState) {
22031 app.repProcState = app.curProcState;
22032 if (app.thread != null) {
22035 //RuntimeException h = new RuntimeException("here");
22036 Slog.i(TAG, "Sending new process state " + app.repProcState
22037 + " to " + app /*, h*/);
22039 app.thread.setProcessState(app.repProcState);
22040 } catch (RemoteException e) {
22044 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22045 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22046 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22047 // Experimental code to more aggressively collect pss while
22048 // running test... the problem is that this tends to collect
22049 // the data right when a process is transitioning between process
22050 // states, which well tend to give noisy data.
22051 long start = SystemClock.uptimeMillis();
22052 long pss = Debug.getPss(app.pid, mTmpLong, null);
22053 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22054 mPendingPssProcesses.remove(app);
22055 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22056 + " to " + app.curProcState + ": "
22057 + (SystemClock.uptimeMillis()-start) + "ms");
22059 app.lastStateTime = now;
22060 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22061 mTestPssMode, isSleepingLocked(), now);
22062 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22063 + ProcessList.makeProcStateString(app.setProcState) + " to "
22064 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22065 + (app.nextPssTime-now) + ": " + app);
22067 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22068 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22070 requestPssLocked(app, app.setProcState);
22071 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22072 mTestPssMode, isSleepingLocked(), now);
22073 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22074 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22076 if (app.setProcState != app.curProcState) {
22077 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22078 "Proc state change of " + app.processName
22079 + " to " + app.curProcState);
22080 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22081 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22082 if (setImportant && !curImportant) {
22083 // This app is no longer something we consider important enough to allow to
22084 // use arbitrary amounts of battery power. Note
22085 // its current wake lock time to later know to kill it if
22086 // it is not behaving well.
22087 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22088 synchronized (stats) {
22089 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
22090 app.pid, nowElapsed);
22092 app.lastCpuTime = app.curCpuTime;
22095 // Inform UsageStats of important process state change
22096 // Must be called before updating setProcState
22097 maybeUpdateUsageStatsLocked(app, nowElapsed);
22099 app.setProcState = app.curProcState;
22100 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22101 app.notCachedSinceIdle = false;
22104 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22106 app.procStateChanged = true;
22108 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22109 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22110 // For apps that sit around for a long time in the interactive state, we need
22111 // to report this at least once a day so they don't go idle.
22112 maybeUpdateUsageStatsLocked(app, nowElapsed);
22115 if (changes != 0) {
22116 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22117 "Changes in " + app + ": " + changes);
22118 int i = mPendingProcessChanges.size()-1;
22119 ProcessChangeItem item = null;
22121 item = mPendingProcessChanges.get(i);
22122 if (item.pid == app.pid) {
22123 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22124 "Re-using existing item: " + item);
22130 // No existing item in pending changes; need a new one.
22131 final int NA = mAvailProcessChanges.size();
22133 item = mAvailProcessChanges.remove(NA-1);
22134 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22135 "Retrieving available item: " + item);
22137 item = new ProcessChangeItem();
22138 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22139 "Allocating new item: " + item);
22142 item.pid = app.pid;
22143 item.uid = app.info.uid;
22144 if (mPendingProcessChanges.size() == 0) {
22145 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22146 "*** Enqueueing dispatch processes changed!");
22147 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22149 mPendingProcessChanges.add(item);
22151 item.changes |= changes;
22152 item.foregroundActivities = app.repForegroundActivities;
22153 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22154 "Item " + Integer.toHexString(System.identityHashCode(item))
22155 + " " + app.toShortString() + ": changes=" + item.changes
22156 + " foreground=" + item.foregroundActivities
22157 + " type=" + app.adjType + " source=" + app.adjSource
22158 + " target=" + app.adjTarget);
22164 private boolean isEphemeralLocked(int uid) {
22165 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22166 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22169 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22174 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22175 final UidRecord.ChangeItem pendingChange;
22176 if (uidRec == null || uidRec.pendingChange == null) {
22177 if (mPendingUidChanges.size() == 0) {
22178 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22179 "*** Enqueueing dispatch uid changed!");
22180 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22182 final int NA = mAvailUidChanges.size();
22184 pendingChange = mAvailUidChanges.remove(NA-1);
22185 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22186 "Retrieving available item: " + pendingChange);
22188 pendingChange = new UidRecord.ChangeItem();
22189 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22190 "Allocating new item: " + pendingChange);
22192 if (uidRec != null) {
22193 uidRec.pendingChange = pendingChange;
22194 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
22195 // If this uid is going away, and we haven't yet reported it is gone,
22197 change = UidRecord.CHANGE_GONE_IDLE;
22199 } else if (uid < 0) {
22200 throw new IllegalArgumentException("No UidRecord or uid");
22202 pendingChange.uidRecord = uidRec;
22203 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22204 mPendingUidChanges.add(pendingChange);
22206 pendingChange = uidRec.pendingChange;
22207 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
22208 change = UidRecord.CHANGE_GONE_IDLE;
22211 pendingChange.change = change;
22212 pendingChange.processState = uidRec != null
22213 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22214 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22215 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22216 if (uidRec != null) {
22217 uidRec.updateLastDispatchedProcStateSeq(change);
22220 // Directly update the power manager, since we sit on top of it and it is critical
22221 // it be kept in sync (so wake locks will be held as soon as appropriate).
22222 if (mLocalPowerManager != null) {
22224 case UidRecord.CHANGE_GONE:
22225 case UidRecord.CHANGE_GONE_IDLE:
22226 mLocalPowerManager.uidGone(pendingChange.uid);
22228 case UidRecord.CHANGE_IDLE:
22229 mLocalPowerManager.uidIdle(pendingChange.uid);
22231 case UidRecord.CHANGE_ACTIVE:
22232 mLocalPowerManager.uidActive(pendingChange.uid);
22235 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22236 pendingChange.processState);
22242 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22243 String authority) {
22244 if (app == null) return;
22245 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22246 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22247 if (userState == null) return;
22248 final long now = SystemClock.elapsedRealtime();
22249 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22250 if (lastReported == null || lastReported < now - 60 * 1000L) {
22251 if (mSystemReady) {
22252 // Cannot touch the user stats if not system ready
22253 mUsageStatsService.reportContentProviderUsage(
22254 authority, providerPkgName, app.userId);
22256 userState.mProviderLastReportedFg.put(authority, now);
22261 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22262 if (DEBUG_USAGE_STATS) {
22263 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22264 + "] state changes: old = " + app.setProcState + ", new = "
22265 + app.curProcState);
22267 if (mUsageStatsService == null) {
22270 boolean isInteraction;
22271 // To avoid some abuse patterns, we are going to be careful about what we consider
22272 // to be an app interaction. Being the top activity doesn't count while the display
22273 // is sleeping, nor do short foreground services.
22274 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22275 isInteraction = true;
22276 app.fgInteractionTime = 0;
22277 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22278 if (app.fgInteractionTime == 0) {
22279 app.fgInteractionTime = nowElapsed;
22280 isInteraction = false;
22282 isInteraction = nowElapsed > app.fgInteractionTime
22283 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22286 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22287 app.fgInteractionTime = 0;
22289 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22290 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22291 app.interactionEventTime = nowElapsed;
22292 String[] packages = app.getPackageList();
22293 if (packages != null) {
22294 for (int i = 0; i < packages.length; i++) {
22295 mUsageStatsService.reportEvent(packages[i], app.userId,
22296 UsageEvents.Event.SYSTEM_INTERACTION);
22300 app.reportedInteraction = isInteraction;
22301 if (!isInteraction) {
22302 app.interactionEventTime = 0;
22306 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22307 if (proc.thread != null) {
22308 if (proc.baseProcessTracker != null) {
22309 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22314 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22315 ProcessRecord TOP_APP, boolean doingAll, long now) {
22316 if (app.thread == null) {
22320 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22322 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22325 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22327 if (isForeground != proc.foregroundServices) {
22328 proc.foregroundServices = isForeground;
22329 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22331 if (isForeground) {
22332 if (curProcs == null) {
22333 curProcs = new ArrayList<ProcessRecord>();
22334 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22336 if (!curProcs.contains(proc)) {
22337 curProcs.add(proc);
22338 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22339 proc.info.packageName, proc.info.uid);
22342 if (curProcs != null) {
22343 if (curProcs.remove(proc)) {
22344 mBatteryStatsService.noteEvent(
22345 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22346 proc.info.packageName, proc.info.uid);
22347 if (curProcs.size() <= 0) {
22348 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22354 updateOomAdjLocked();
22359 private final ActivityRecord resumedAppLocked() {
22360 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22364 pkg = act.packageName;
22365 uid = act.info.applicationInfo.uid;
22370 // Has the UID or resumed package name changed?
22371 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22372 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22373 if (mCurResumedPackage != null) {
22374 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22375 mCurResumedPackage, mCurResumedUid);
22377 mCurResumedPackage = pkg;
22378 mCurResumedUid = uid;
22379 if (mCurResumedPackage != null) {
22380 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22381 mCurResumedPackage, mCurResumedUid);
22388 * Update OomAdj for a specific process.
22389 * @param app The process to update
22390 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22391 * if necessary, or skip.
22392 * @return whether updateOomAdjLocked(app) was successful.
22394 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22395 final ActivityRecord TOP_ACT = resumedAppLocked();
22396 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22397 final boolean wasCached = app.cached;
22401 // This is the desired cached adjusment we want to tell it to use.
22402 // If our app is currently cached, we know it, and that is it. Otherwise,
22403 // we don't know it yet, and it needs to now be cached we will then
22404 // need to do a complete oom adj.
22405 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22406 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22407 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22408 SystemClock.uptimeMillis());
22410 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22411 // Changed to/from cached state, so apps after it in the LRU
22412 // list may also be changed.
22413 updateOomAdjLocked();
22418 final void updateOomAdjLocked() {
22419 final ActivityRecord TOP_ACT = resumedAppLocked();
22420 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22421 final long now = SystemClock.uptimeMillis();
22422 final long nowElapsed = SystemClock.elapsedRealtime();
22423 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22424 final int N = mLruProcesses.size();
22427 RuntimeException e = new RuntimeException();
22428 e.fillInStackTrace();
22429 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22432 // Reset state in all uid records.
22433 for (int i=mActiveUids.size()-1; i>=0; i--) {
22434 final UidRecord uidRec = mActiveUids.valueAt(i);
22435 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22436 "Starting update of " + uidRec);
22440 mStackSupervisor.rankTaskLayersIfNeeded();
22443 mNewNumServiceProcs = 0;
22444 mNewNumAServiceProcs = 0;
22446 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22447 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22449 // Let's determine how many processes we have running vs.
22450 // how many slots we have for background processes; we may want
22451 // to put multiple processes in a slot of there are enough of
22453 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22454 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22455 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22456 if (numEmptyProcs > cachedProcessLimit) {
22457 // If there are more empty processes than our limit on cached
22458 // processes, then use the cached process limit for the factor.
22459 // This ensures that the really old empty processes get pushed
22460 // down to the bottom, so if we are running low on memory we will
22461 // have a better chance at keeping around more cached processes
22462 // instead of a gazillion empty processes.
22463 numEmptyProcs = cachedProcessLimit;
22465 int emptyFactor = numEmptyProcs/numSlots;
22466 if (emptyFactor < 1) emptyFactor = 1;
22467 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22468 if (cachedFactor < 1) cachedFactor = 1;
22469 int stepCached = 0;
22473 int numTrimming = 0;
22475 mNumNonCachedProcs = 0;
22476 mNumCachedHiddenProcs = 0;
22478 // First update the OOM adjustment for each of the
22479 // application processes based on their current state.
22480 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22481 int nextCachedAdj = curCachedAdj+1;
22482 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22483 int nextEmptyAdj = curEmptyAdj+2;
22484 for (int i=N-1; i>=0; i--) {
22485 ProcessRecord app = mLruProcesses.get(i);
22486 if (!app.killedByAm && app.thread != null) {
22487 app.procStateChanged = false;
22488 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22490 // If we haven't yet assigned the final cached adj
22491 // to the process, do that now.
22492 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22493 switch (app.curProcState) {
22494 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22495 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22496 // This process is a cached process holding activities...
22497 // assign it the next cached value for that type, and then
22498 // step that cached level.
22499 app.curRawAdj = curCachedAdj;
22500 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22501 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22502 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22504 if (curCachedAdj != nextCachedAdj) {
22506 if (stepCached >= cachedFactor) {
22508 curCachedAdj = nextCachedAdj;
22509 nextCachedAdj += 2;
22510 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22511 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22517 // For everything else, assign next empty cached process
22518 // level and bump that up. Note that this means that
22519 // long-running services that have dropped down to the
22520 // cached level will be treated as empty (since their process
22521 // state is still as a service), which is what we want.
22522 app.curRawAdj = curEmptyAdj;
22523 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22524 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22525 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22527 if (curEmptyAdj != nextEmptyAdj) {
22529 if (stepEmpty >= emptyFactor) {
22531 curEmptyAdj = nextEmptyAdj;
22533 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22534 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22542 applyOomAdjLocked(app, true, now, nowElapsed);
22544 // Count the number of process types.
22545 switch (app.curProcState) {
22546 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22547 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22548 mNumCachedHiddenProcs++;
22550 if (numCached > cachedProcessLimit) {
22551 app.kill("cached #" + numCached, true);
22554 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22555 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22556 && app.lastActivityTime < oldTime) {
22557 app.kill("empty for "
22558 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22559 / 1000) + "s", true);
22562 if (numEmpty > emptyProcessLimit) {
22563 app.kill("empty #" + numEmpty, true);
22568 mNumNonCachedProcs++;
22572 if (app.isolated && app.services.size() <= 0) {
22573 // If this is an isolated process, and there are no
22574 // services running in it, then the process is no longer
22575 // needed. We agressively kill these because we can by
22576 // definition not re-use the same process again, and it is
22577 // good to avoid having whatever code was running in them
22578 // left sitting around after no longer needed.
22579 app.kill("isolated not needed", true);
22581 // Keeping this process, update its uid.
22582 final UidRecord uidRec = app.uidRecord;
22583 if (uidRec != null) {
22584 uidRec.ephemeral = app.info.isInstantApp();
22585 if (uidRec.curProcState > app.curProcState) {
22586 uidRec.curProcState = app.curProcState;
22588 if (app.foregroundServices) {
22589 uidRec.foregroundServices = true;
22594 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22595 && !app.killedByAm) {
22601 incrementProcStateSeqAndNotifyAppsLocked();
22603 mNumServiceProcs = mNewNumServiceProcs;
22605 // Now determine the memory trimming level of background processes.
22606 // Unfortunately we need to start at the back of the list to do this
22607 // properly. We only do this if the number of background apps we
22608 // are managing to keep around is less than half the maximum we desire;
22609 // if we are keeping a good number around, we'll let them use whatever
22610 // memory they want.
22611 final int numCachedAndEmpty = numCached + numEmpty;
22613 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22614 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22615 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22616 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22617 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22618 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22620 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22623 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22625 // We always allow the memory level to go up (better). We only allow it to go
22626 // down if we are in a state where that is allowed, *and* the total number of processes
22627 // has gone down since last time.
22628 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22629 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22630 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22631 if (memFactor > mLastMemoryLevel) {
22632 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22633 memFactor = mLastMemoryLevel;
22634 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22637 if (memFactor != mLastMemoryLevel) {
22638 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22640 mLastMemoryLevel = memFactor;
22641 mLastNumProcesses = mLruProcesses.size();
22642 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22643 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22644 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22645 if (mLowRamStartTime == 0) {
22646 mLowRamStartTime = now;
22650 switch (memFactor) {
22651 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22652 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22654 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22655 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22658 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22661 int factor = numTrimming/3;
22663 if (mHomeProcess != null) minFactor++;
22664 if (mPreviousProcess != null) minFactor++;
22665 if (factor < minFactor) factor = minFactor;
22666 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22667 for (int i=N-1; i>=0; i--) {
22668 ProcessRecord app = mLruProcesses.get(i);
22669 if (allChanged || app.procStateChanged) {
22670 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22671 app.procStateChanged = false;
22673 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22674 && !app.killedByAm) {
22675 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22677 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22678 "Trimming memory of " + app.processName + " to " + curLevel);
22679 app.thread.scheduleTrimMemory(curLevel);
22680 } catch (RemoteException e) {
22683 // For now we won't do this; our memory trimming seems
22684 // to be good enough at this point that destroying
22685 // activities causes more harm than good.
22686 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22687 && app != mHomeProcess && app != mPreviousProcess) {
22688 // Need to do this on its own message because the stack may not
22689 // be in a consistent state at this point.
22690 // For these apps we will also finish their activities
22691 // to help them free memory.
22692 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22696 app.trimMemoryLevel = curLevel;
22698 if (step >= factor) {
22700 switch (curLevel) {
22701 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22702 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22704 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22705 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22709 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22710 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22711 && app.thread != null) {
22713 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22714 "Trimming memory of heavy-weight " + app.processName
22715 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22716 app.thread.scheduleTrimMemory(
22717 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22718 } catch (RemoteException e) {
22721 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22723 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22724 || app.systemNoUi) && app.pendingUiClean) {
22725 // If this application is now in the background and it
22726 // had done UI, then give it the special trim level to
22727 // have it free UI resources.
22728 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22729 if (app.trimMemoryLevel < level && app.thread != null) {
22731 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22732 "Trimming memory of bg-ui " + app.processName
22734 app.thread.scheduleTrimMemory(level);
22735 } catch (RemoteException e) {
22738 app.pendingUiClean = false;
22740 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22742 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22743 "Trimming memory of fg " + app.processName
22744 + " to " + fgTrimLevel);
22745 app.thread.scheduleTrimMemory(fgTrimLevel);
22746 } catch (RemoteException e) {
22749 app.trimMemoryLevel = fgTrimLevel;
22753 if (mLowRamStartTime != 0) {
22754 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22755 mLowRamStartTime = 0;
22757 for (int i=N-1; i>=0; i--) {
22758 ProcessRecord app = mLruProcesses.get(i);
22759 if (allChanged || app.procStateChanged) {
22760 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22761 app.procStateChanged = false;
22763 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22764 || app.systemNoUi) && app.pendingUiClean) {
22765 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22766 && app.thread != null) {
22768 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22769 "Trimming memory of ui hidden " + app.processName
22770 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22771 app.thread.scheduleTrimMemory(
22772 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22773 } catch (RemoteException e) {
22776 app.pendingUiClean = false;
22778 app.trimMemoryLevel = 0;
22782 if (mAlwaysFinishActivities) {
22783 // Need to do this on its own message because the stack may not
22784 // be in a consistent state at this point.
22785 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22789 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22792 // Update from any uid changes.
22793 if (mLocalPowerManager != null) {
22794 mLocalPowerManager.startUidChanges();
22796 for (int i=mActiveUids.size()-1; i>=0; i--) {
22797 final UidRecord uidRec = mActiveUids.valueAt(i);
22798 int uidChange = UidRecord.CHANGE_PROCSTATE;
22799 if (uidRec.setProcState != uidRec.curProcState
22800 || uidRec.setWhitelist != uidRec.curWhitelist) {
22801 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22802 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22803 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22804 + " to " + uidRec.curWhitelist);
22805 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22806 && !uidRec.curWhitelist) {
22807 // UID is now in the background (and not on the temp whitelist). Was it
22808 // previously in the foreground (or on the temp whitelist)?
22809 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22810 || uidRec.setWhitelist) {
22811 uidRec.lastBackgroundTime = nowElapsed;
22812 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22813 // Note: the background settle time is in elapsed realtime, while
22814 // the handler time base is uptime. All this means is that we may
22815 // stop background uids later than we had intended, but that only
22816 // happens because the device was sleeping so we are okay anyway.
22817 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22818 mConstants.BACKGROUND_SETTLE_TIME);
22823 uidChange = UidRecord.CHANGE_ACTIVE;
22824 EventLogTags.writeAmUidActive(uidRec.uid);
22825 uidRec.idle = false;
22827 uidRec.lastBackgroundTime = 0;
22829 uidRec.setProcState = uidRec.curProcState;
22830 uidRec.setWhitelist = uidRec.curWhitelist;
22831 enqueueUidChangeLocked(uidRec, -1, uidChange);
22832 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22833 if (uidRec.foregroundServices) {
22834 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22838 if (mLocalPowerManager != null) {
22839 mLocalPowerManager.finishUidChanges();
22842 if (mProcessStats.shouldWriteNowLocked(now)) {
22843 mHandler.post(new Runnable() {
22844 @Override public void run() {
22845 synchronized (ActivityManagerService.this) {
22846 mProcessStats.writeStateAsyncLocked();
22852 if (DEBUG_OOM_ADJ) {
22853 final long duration = SystemClock.uptimeMillis() - now;
22855 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22856 new RuntimeException("here").fillInStackTrace());
22858 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22864 public void makePackageIdle(String packageName, int userId) {
22865 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22866 != PackageManager.PERMISSION_GRANTED) {
22867 String msg = "Permission Denial: makePackageIdle() from pid="
22868 + Binder.getCallingPid()
22869 + ", uid=" + Binder.getCallingUid()
22870 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22872 throw new SecurityException(msg);
22874 final int callingPid = Binder.getCallingPid();
22875 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22876 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22877 long callingId = Binder.clearCallingIdentity();
22878 synchronized(this) {
22880 IPackageManager pm = AppGlobals.getPackageManager();
22883 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22884 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22885 } catch (RemoteException e) {
22887 if (pkgUid == -1) {
22888 throw new IllegalArgumentException("Unknown package name " + packageName);
22891 if (mLocalPowerManager != null) {
22892 mLocalPowerManager.startUidChanges();
22894 final int appId = UserHandle.getAppId(pkgUid);
22895 final int N = mActiveUids.size();
22896 for (int i=N-1; i>=0; i--) {
22897 final UidRecord uidRec = mActiveUids.valueAt(i);
22898 final long bgTime = uidRec.lastBackgroundTime;
22899 if (bgTime > 0 && !uidRec.idle) {
22900 if (UserHandle.getAppId(uidRec.uid) == appId) {
22901 if (userId == UserHandle.USER_ALL ||
22902 userId == UserHandle.getUserId(uidRec.uid)) {
22903 EventLogTags.writeAmUidIdle(uidRec.uid);
22904 uidRec.idle = true;
22905 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22906 + " from package " + packageName + " user " + userId);
22907 doStopUidLocked(uidRec.uid, uidRec);
22913 if (mLocalPowerManager != null) {
22914 mLocalPowerManager.finishUidChanges();
22916 Binder.restoreCallingIdentity(callingId);
22921 final void idleUids() {
22922 synchronized (this) {
22923 final int N = mActiveUids.size();
22927 final long nowElapsed = SystemClock.elapsedRealtime();
22928 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22930 if (mLocalPowerManager != null) {
22931 mLocalPowerManager.startUidChanges();
22933 for (int i=N-1; i>=0; i--) {
22934 final UidRecord uidRec = mActiveUids.valueAt(i);
22935 final long bgTime = uidRec.lastBackgroundTime;
22936 if (bgTime > 0 && !uidRec.idle) {
22937 if (bgTime <= maxBgTime) {
22938 EventLogTags.writeAmUidIdle(uidRec.uid);
22939 uidRec.idle = true;
22940 doStopUidLocked(uidRec.uid, uidRec);
22942 if (nextTime == 0 || nextTime > bgTime) {
22948 if (mLocalPowerManager != null) {
22949 mLocalPowerManager.finishUidChanges();
22951 if (nextTime > 0) {
22952 mHandler.removeMessages(IDLE_UIDS_MSG);
22953 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22954 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
22960 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22961 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22962 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22966 void incrementProcStateSeqAndNotifyAppsLocked() {
22967 if (mWaitForNetworkTimeoutMs <= 0) {
22970 // Used for identifying which uids need to block for network.
22971 ArrayList<Integer> blockingUids = null;
22972 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
22973 final UidRecord uidRec = mActiveUids.valueAt(i);
22974 // If the network is not restricted for uid, then nothing to do here.
22975 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
22978 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
22981 // If process state is not changed, then there's nothing to do.
22982 if (uidRec.setProcState == uidRec.curProcState) {
22985 final int blockState = getBlockStateForUid(uidRec);
22986 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
22987 // there's nothing the app needs to do in this scenario.
22988 if (blockState == NETWORK_STATE_NO_CHANGE) {
22991 synchronized (uidRec.networkStateLock) {
22992 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22993 if (blockState == NETWORK_STATE_BLOCK) {
22994 if (blockingUids == null) {
22995 blockingUids = new ArrayList<>();
22997 blockingUids.add(uidRec.uid);
22999 if (DEBUG_NETWORK) {
23000 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23001 + " threads for uid: " + uidRec);
23003 if (uidRec.waitingForNetwork) {
23004 uidRec.networkStateLock.notifyAll();
23010 // There are no uids that need to block, so nothing more to do.
23011 if (blockingUids == null) {
23015 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23016 final ProcessRecord app = mLruProcesses.get(i);
23017 if (!blockingUids.contains(app.uid)) {
23020 if (!app.killedByAm && app.thread != null) {
23021 final UidRecord uidRec = mActiveUids.get(app.uid);
23023 if (DEBUG_NETWORK) {
23024 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23027 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23028 } catch (RemoteException ignored) {
23035 * Checks if the uid is coming from background to foreground or vice versa and returns
23036 * appropriate block state based on this.
23038 * @return blockState based on whether the uid is coming from background to foreground or
23039 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23040 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23041 * {@link #NETWORK_STATE_NO_CHANGE}.
23044 int getBlockStateForUid(UidRecord uidRec) {
23045 // Denotes whether uid's process state is currently allowed network access.
23046 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23047 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23048 // Denotes whether uid's process state was previously allowed network access.
23049 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23050 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23052 // When the uid is coming to foreground, AMS should inform the app thread that it should
23053 // block for the network rules to get updated before launching an activity.
23054 if (!wasAllowed && isAllowed) {
23055 return NETWORK_STATE_BLOCK;
23057 // When the uid is going to background, AMS should inform the app thread that if an
23058 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23059 if (wasAllowed && !isAllowed) {
23060 return NETWORK_STATE_UNBLOCK;
23062 return NETWORK_STATE_NO_CHANGE;
23065 final void runInBackgroundDisabled(int uid) {
23066 synchronized (this) {
23067 UidRecord uidRec = mActiveUids.get(uid);
23068 if (uidRec != null) {
23069 // This uid is actually running... should it be considered background now?
23071 doStopUidLocked(uidRec.uid, uidRec);
23074 // This uid isn't actually running... still send a report about it being "stopped".
23075 doStopUidLocked(uid, null);
23080 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23081 mServices.stopInBackgroundLocked(uid);
23082 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23086 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23088 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23089 long duration, String tag) {
23090 if (DEBUG_WHITELISTS) {
23091 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23092 + targetUid + ", " + duration + ")");
23095 synchronized (mPidsSelfLocked) {
23096 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23098 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23102 if (!pr.whitelistManager) {
23103 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23104 != PackageManager.PERMISSION_GRANTED) {
23105 if (DEBUG_WHITELISTS) {
23106 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23107 + ": pid " + callerPid + " is not allowed");
23114 tempWhitelistUidLocked(targetUid, duration, tag);
23118 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23120 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23121 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23122 setUidTempWhitelistStateLocked(targetUid, true);
23123 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23126 void pushTempWhitelist() {
23128 final PendingTempWhitelist[] list;
23130 // First copy out the pending changes... we need to leave them in the map for now,
23131 // in case someone needs to check what is coming up while we don't have the lock held.
23132 synchronized(this) {
23133 N = mPendingTempWhitelist.size();
23134 list = new PendingTempWhitelist[N];
23135 for (int i = 0; i < N; i++) {
23136 list[i] = mPendingTempWhitelist.valueAt(i);
23140 // Now safely dispatch changes to device idle controller.
23141 for (int i = 0; i < N; i++) {
23142 PendingTempWhitelist ptw = list[i];
23143 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23144 ptw.duration, true, ptw.tag);
23147 // And now we can safely remove them from the map.
23148 synchronized(this) {
23149 for (int i = 0; i < N; i++) {
23150 PendingTempWhitelist ptw = list[i];
23151 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23152 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23153 mPendingTempWhitelist.removeAt(index);
23159 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23160 boolean changed = false;
23161 for (int i=mActiveUids.size()-1; i>=0; i--) {
23162 final UidRecord uidRec = mActiveUids.valueAt(i);
23163 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23164 uidRec.curWhitelist = onWhitelist;
23169 updateOomAdjLocked();
23173 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23174 boolean changed = false;
23175 final UidRecord uidRec = mActiveUids.get(uid);
23176 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23177 uidRec.curWhitelist = onWhitelist;
23178 updateOomAdjLocked();
23182 final void trimApplications() {
23183 synchronized (this) {
23186 // First remove any unused application processes whose package
23187 // has been removed.
23188 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23189 final ProcessRecord app = mRemovedProcesses.get(i);
23190 if (app.activities.size() == 0
23191 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23193 TAG, "Exiting empty application process "
23194 + app.toShortString() + " ("
23195 + (app.thread != null ? app.thread.asBinder() : null)
23197 if (app.pid > 0 && app.pid != MY_PID) {
23198 app.kill("empty", false);
23201 app.thread.scheduleExit();
23202 } catch (Exception e) {
23203 // Ignore exceptions.
23206 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23207 mRemovedProcesses.remove(i);
23209 if (app.persistent) {
23210 addAppLocked(app.info, null, false, null /* ABI override */);
23215 // Now update the oom adj for all processes.
23216 updateOomAdjLocked();
23220 /** This method sends the specified signal to each of the persistent apps */
23221 public void signalPersistentProcesses(int sig) throws RemoteException {
23222 if (sig != SIGNAL_USR1) {
23223 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23226 synchronized (this) {
23227 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23228 != PackageManager.PERMISSION_GRANTED) {
23229 throw new SecurityException("Requires permission "
23230 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23233 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23234 ProcessRecord r = mLruProcesses.get(i);
23235 if (r.thread != null && r.persistent) {
23236 sendSignal(r.pid, sig);
23242 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23243 if (proc == null || proc == mProfileProc) {
23244 proc = mProfileProc;
23245 profileType = mProfileType;
23246 clearProfilerLocked();
23248 if (proc == null) {
23252 proc.thread.profilerControl(false, null, profileType);
23253 } catch (RemoteException e) {
23254 throw new IllegalStateException("Process disappeared");
23258 private void clearProfilerLocked() {
23259 if (mProfileFd != null) {
23261 mProfileFd.close();
23262 } catch (IOException e) {
23265 mProfileApp = null;
23266 mProfileProc = null;
23267 mProfileFile = null;
23269 mAutoStopProfiler = false;
23270 mStreamingOutput = false;
23271 mSamplingInterval = 0;
23274 public boolean profileControl(String process, int userId, boolean start,
23275 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23278 synchronized (this) {
23279 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23280 // its own permission.
23281 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23282 != PackageManager.PERMISSION_GRANTED) {
23283 throw new SecurityException("Requires permission "
23284 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23287 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23288 throw new IllegalArgumentException("null profile info or fd");
23291 ProcessRecord proc = null;
23292 if (process != null) {
23293 proc = findProcessLocked(process, userId, "profileControl");
23296 if (start && (proc == null || proc.thread == null)) {
23297 throw new IllegalArgumentException("Unknown process: " + process);
23301 stopProfilerLocked(null, 0);
23302 setProfileApp(proc.info, proc.processName, profilerInfo);
23303 mProfileProc = proc;
23304 mProfileType = profileType;
23305 ParcelFileDescriptor fd = profilerInfo.profileFd;
23308 } catch (IOException e) {
23311 profilerInfo.profileFd = fd;
23312 proc.thread.profilerControl(start, profilerInfo, profileType);
23315 mProfileFd.close();
23316 } catch (IOException e) {
23320 stopProfilerLocked(proc, profileType);
23321 if (profilerInfo != null && profilerInfo.profileFd != null) {
23323 profilerInfo.profileFd.close();
23324 } catch (IOException e) {
23331 } catch (RemoteException e) {
23332 throw new IllegalStateException("Process disappeared");
23334 if (profilerInfo != null && profilerInfo.profileFd != null) {
23336 profilerInfo.profileFd.close();
23337 } catch (IOException e) {
23343 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23344 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23345 userId, true, ALLOW_FULL_ONLY, callName, null);
23346 ProcessRecord proc = null;
23348 int pid = Integer.parseInt(process);
23349 synchronized (mPidsSelfLocked) {
23350 proc = mPidsSelfLocked.get(pid);
23352 } catch (NumberFormatException e) {
23355 if (proc == null) {
23356 ArrayMap<String, SparseArray<ProcessRecord>> all
23357 = mProcessNames.getMap();
23358 SparseArray<ProcessRecord> procs = all.get(process);
23359 if (procs != null && procs.size() > 0) {
23360 proc = procs.valueAt(0);
23361 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23362 for (int i=1; i<procs.size(); i++) {
23363 ProcessRecord thisProc = procs.valueAt(i);
23364 if (thisProc.userId == userId) {
23376 public boolean dumpHeap(String process, int userId, boolean managed,
23377 String path, ParcelFileDescriptor fd) throws RemoteException {
23380 synchronized (this) {
23381 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23382 // its own permission (same as profileControl).
23383 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23384 != PackageManager.PERMISSION_GRANTED) {
23385 throw new SecurityException("Requires permission "
23386 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23390 throw new IllegalArgumentException("null fd");
23393 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23394 if (proc == null || proc.thread == null) {
23395 throw new IllegalArgumentException("Unknown process: " + process);
23398 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23399 if (!isDebuggable) {
23400 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23401 throw new SecurityException("Process not debuggable: " + proc);
23405 proc.thread.dumpHeap(managed, path, fd);
23409 } catch (RemoteException e) {
23410 throw new IllegalStateException("Process disappeared");
23415 } catch (IOException e) {
23422 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23423 String reportPackage) {
23424 if (processName != null) {
23425 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23426 "setDumpHeapDebugLimit()");
23428 synchronized (mPidsSelfLocked) {
23429 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23430 if (proc == null) {
23431 throw new SecurityException("No process found for calling pid "
23432 + Binder.getCallingPid());
23434 if (!Build.IS_DEBUGGABLE
23435 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23436 throw new SecurityException("Not running a debuggable build");
23438 processName = proc.processName;
23440 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23441 throw new SecurityException("Package " + reportPackage + " is not running in "
23446 synchronized (this) {
23447 if (maxMemSize > 0) {
23448 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23451 mMemWatchProcesses.remove(processName, uid);
23453 mMemWatchProcesses.getMap().remove(processName);
23460 public void dumpHeapFinished(String path) {
23461 synchronized (this) {
23462 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23463 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23464 + " does not match last pid " + mMemWatchDumpPid);
23467 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23468 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23469 + " does not match last path " + mMemWatchDumpFile);
23472 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23473 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23477 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23478 public void monitor() {
23479 synchronized (this) { }
23482 void onCoreSettingsChange(Bundle settings) {
23483 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23484 ProcessRecord processRecord = mLruProcesses.get(i);
23486 if (processRecord.thread != null) {
23487 processRecord.thread.setCoreSettings(settings);
23489 } catch (RemoteException re) {
23495 // Multi-user methods
23498 * Start user, if its not already running, but don't bring it to foreground.
23501 public boolean startUserInBackground(final int userId) {
23502 return mUserController.startUser(userId, /* foreground */ false);
23506 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23507 return mUserController.unlockUser(userId, token, secret, listener);
23511 public boolean switchUser(final int targetUserId) {
23512 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23514 UserInfo targetUserInfo;
23515 synchronized (this) {
23516 currentUserId = mUserController.getCurrentUserIdLocked();
23517 targetUserInfo = mUserController.getUserInfo(targetUserId);
23518 if (targetUserId == currentUserId) {
23519 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23522 if (targetUserInfo == null) {
23523 Slog.w(TAG, "No user info for user #" + targetUserId);
23526 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23527 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23528 + " when device is in demo mode");
23531 if (!targetUserInfo.supportsSwitchTo()) {
23532 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23535 if (targetUserInfo.isManagedProfile()) {
23536 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23539 mUserController.setTargetUserIdLocked(targetUserId);
23541 if (mUserController.mUserSwitchUiEnabled) {
23542 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23543 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23544 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23545 mUiHandler.sendMessage(mHandler.obtainMessage(
23546 START_USER_SWITCH_UI_MSG, userNames));
23548 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23549 mHandler.sendMessage(mHandler.obtainMessage(
23550 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23555 void scheduleStartProfilesLocked() {
23556 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23557 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23558 DateUtils.SECOND_IN_MILLIS);
23563 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23564 return mUserController.stopUser(userId, force, callback);
23568 public UserInfo getCurrentUser() {
23569 return mUserController.getCurrentUser();
23572 String getStartedUserState(int userId) {
23573 synchronized (this) {
23574 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23575 return UserState.stateToString(userState.state);
23580 public boolean isUserRunning(int userId, int flags) {
23581 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23582 && checkCallingPermission(INTERACT_ACROSS_USERS)
23583 != PackageManager.PERMISSION_GRANTED) {
23584 String msg = "Permission Denial: isUserRunning() from pid="
23585 + Binder.getCallingPid()
23586 + ", uid=" + Binder.getCallingUid()
23587 + " requires " + INTERACT_ACROSS_USERS;
23589 throw new SecurityException(msg);
23591 synchronized (this) {
23592 return mUserController.isUserRunningLocked(userId, flags);
23597 public int[] getRunningUserIds() {
23598 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23599 != PackageManager.PERMISSION_GRANTED) {
23600 String msg = "Permission Denial: isUserRunning() from pid="
23601 + Binder.getCallingPid()
23602 + ", uid=" + Binder.getCallingUid()
23603 + " requires " + INTERACT_ACROSS_USERS;
23605 throw new SecurityException(msg);
23607 synchronized (this) {
23608 return mUserController.getStartedUserArrayLocked();
23613 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23614 mUserController.registerUserSwitchObserver(observer, name);
23618 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23619 mUserController.unregisterUserSwitchObserver(observer);
23622 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23623 if (info == null) return null;
23624 ApplicationInfo newInfo = new ApplicationInfo(info);
23625 newInfo.initForUser(userId);
23629 public boolean isUserStopped(int userId) {
23630 synchronized (this) {
23631 return mUserController.getStartedUserStateLocked(userId) == null;
23635 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23637 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23641 ActivityInfo info = new ActivityInfo(aInfo);
23642 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23646 private boolean processSanityChecksLocked(ProcessRecord process) {
23647 if (process == null || process.thread == null) {
23651 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23652 if (!isDebuggable) {
23653 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23661 public boolean startBinderTracking() throws RemoteException {
23662 synchronized (this) {
23663 mBinderTransactionTrackingEnabled = true;
23664 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23665 // permission (same as profileControl).
23666 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23667 != PackageManager.PERMISSION_GRANTED) {
23668 throw new SecurityException("Requires permission "
23669 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23672 for (int i = 0; i < mLruProcesses.size(); i++) {
23673 ProcessRecord process = mLruProcesses.get(i);
23674 if (!processSanityChecksLocked(process)) {
23678 process.thread.startBinderTracking();
23679 } catch (RemoteException e) {
23680 Log.v(TAG, "Process disappared");
23687 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23689 synchronized (this) {
23690 mBinderTransactionTrackingEnabled = false;
23691 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23692 // permission (same as profileControl).
23693 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23694 != PackageManager.PERMISSION_GRANTED) {
23695 throw new SecurityException("Requires permission "
23696 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23700 throw new IllegalArgumentException("null fd");
23703 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23704 pw.println("Binder transaction traces for all processes.\n");
23705 for (ProcessRecord process : mLruProcesses) {
23706 if (!processSanityChecksLocked(process)) {
23710 pw.println("Traces for process: " + process.processName);
23713 TransferPipe tp = new TransferPipe();
23715 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23716 tp.go(fd.getFileDescriptor());
23720 } catch (IOException e) {
23721 pw.println("Failure while dumping IPC traces from " + process +
23722 ". Exception: " + e);
23724 } catch (RemoteException e) {
23725 pw.println("Got a RemoteException while dumping IPC traces from " +
23726 process + ". Exception: " + e);
23737 } catch (IOException e) {
23744 final class LocalService extends ActivityManagerInternal {
23746 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23747 int targetUserId) {
23748 synchronized (ActivityManagerService.this) {
23749 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23750 targetPkg, intent, null, targetUserId);
23755 public String checkContentProviderAccess(String authority, int userId) {
23756 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23760 public void onWakefulnessChanged(int wakefulness) {
23761 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23765 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23766 String processName, String abiOverride, int uid, Runnable crashHandler) {
23767 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23768 processName, abiOverride, uid, crashHandler);
23772 public SleepToken acquireSleepToken(String tag) {
23773 Preconditions.checkNotNull(tag);
23775 synchronized (ActivityManagerService.this) {
23776 SleepTokenImpl token = new SleepTokenImpl(tag);
23777 mSleepTokens.add(token);
23778 updateSleepIfNeededLocked();
23784 public ComponentName getHomeActivityForUser(int userId) {
23785 synchronized (ActivityManagerService.this) {
23786 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23787 return homeActivity == null ? null : homeActivity.realActivity;
23792 public void onUserRemoved(int userId) {
23793 synchronized (ActivityManagerService.this) {
23794 ActivityManagerService.this.onUserStoppedLocked(userId);
23799 public void onLocalVoiceInteractionStarted(IBinder activity,
23800 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23801 synchronized (ActivityManagerService.this) {
23802 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23803 voiceSession, voiceInteractor);
23808 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23809 synchronized (ActivityManagerService.this) {
23810 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23811 reasons, timestamp);
23816 public void notifyAppTransitionFinished() {
23817 synchronized (ActivityManagerService.this) {
23818 mStackSupervisor.notifyAppTransitionDone();
23823 public void notifyAppTransitionCancelled() {
23824 synchronized (ActivityManagerService.this) {
23825 mStackSupervisor.notifyAppTransitionDone();
23830 public List<IBinder> getTopVisibleActivities() {
23831 synchronized (ActivityManagerService.this) {
23832 return mStackSupervisor.getTopVisibleActivities();
23837 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23838 synchronized (ActivityManagerService.this) {
23839 mStackSupervisor.setDockedStackMinimized(minimized);
23844 public void killForegroundAppsForUser(int userHandle) {
23845 synchronized (ActivityManagerService.this) {
23846 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23847 final int NP = mProcessNames.getMap().size();
23848 for (int ip = 0; ip < NP; ip++) {
23849 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23850 final int NA = apps.size();
23851 for (int ia = 0; ia < NA; ia++) {
23852 final ProcessRecord app = apps.valueAt(ia);
23853 if (app.persistent) {
23854 // We don't kill persistent processes.
23859 } else if (app.userId == userHandle && app.foregroundActivities) {
23860 app.removed = true;
23866 final int N = procs.size();
23867 for (int i = 0; i < N; i++) {
23868 removeProcessLocked(procs.get(i), false, true, "kill all fg");
23874 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23876 if (!(target instanceof PendingIntentRecord)) {
23877 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23880 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23884 public void setDeviceIdleWhitelist(int[] appids) {
23885 synchronized (ActivityManagerService.this) {
23886 mDeviceIdleWhitelist = appids;
23891 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23892 synchronized (ActivityManagerService.this) {
23893 mDeviceIdleTempWhitelist = appids;
23894 setAppIdTempWhitelistStateLocked(changingAppId, adding);
23899 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23901 Preconditions.checkNotNull(values, "Configuration must not be null");
23902 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23903 synchronized (ActivityManagerService.this) {
23904 updateConfigurationLocked(values, null, false, true, userId,
23905 false /* deferResume */);
23910 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23912 Preconditions.checkNotNull(intents, "intents");
23913 final String[] resolvedTypes = new String[intents.length];
23914 for (int i = 0; i < intents.length; i++) {
23915 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23918 // UID of the package on user userId.
23919 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23920 // packageUid may not be initialized.
23921 int packageUid = 0;
23923 packageUid = AppGlobals.getPackageManager().getPackageUid(
23924 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23925 } catch (RemoteException e) {
23926 // Shouldn't happen.
23929 synchronized (ActivityManagerService.this) {
23930 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23931 /*resultTo*/ null, bOptions, userId);
23936 public int getUidProcessState(int uid) {
23937 return getUidState(uid);
23941 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23942 synchronized (ActivityManagerService.this) {
23944 // We might change the visibilities here, so prepare an empty app transition which
23945 // might be overridden later if we actually change visibilities.
23946 mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23947 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23948 mWindowManager.executeAppTransition();
23950 if (callback != null) {
23956 public boolean isSystemReady() {
23957 // no need to synchronize(this) just to read & return the value
23958 return mSystemReady;
23962 public void notifyKeyguardTrustedChanged() {
23963 synchronized (ActivityManagerService.this) {
23964 if (mKeyguardController.isKeyguardShowing()) {
23965 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23971 * Sets if the given pid has an overlay UI or not.
23973 * @param pid The pid we are setting overlay UI for.
23974 * @param hasOverlayUi True if the process has overlay UI.
23975 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23978 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23979 synchronized (ActivityManagerService.this) {
23980 final ProcessRecord pr;
23981 synchronized (mPidsSelfLocked) {
23982 pr = mPidsSelfLocked.get(pid);
23984 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23988 if (pr.hasOverlayUi == hasOverlayUi) {
23991 pr.hasOverlayUi = hasOverlayUi;
23992 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23993 updateOomAdjLocked(pr, true);
23998 * Called after the network policy rules are updated by
23999 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24000 * and {@param procStateSeq}.
24003 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24004 if (DEBUG_NETWORK) {
24005 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24006 + uid + " seq: " + procStateSeq);
24009 synchronized (ActivityManagerService.this) {
24010 record = mActiveUids.get(uid);
24011 if (record == null) {
24012 if (DEBUG_NETWORK) {
24013 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24014 + " procStateSeq: " + procStateSeq);
24019 synchronized (record.networkStateLock) {
24020 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24021 if (DEBUG_NETWORK) {
24022 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24023 + " been handled for uid: " + uid);
24027 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24028 if (record.curProcStateSeq > procStateSeq) {
24029 if (DEBUG_NETWORK) {
24030 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24031 + ", curProcstateSeq: " + record.curProcStateSeq
24032 + ", procStateSeq: " + procStateSeq);
24036 if (record.waitingForNetwork) {
24037 if (DEBUG_NETWORK) {
24038 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24039 + ", procStateSeq: " + procStateSeq);
24041 record.networkStateLock.notifyAll();
24047 * Called after virtual display Id is updated by
24048 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24049 * {@param vrVr2dDisplayId}.
24052 public void setVr2dDisplayId(int vr2dDisplayId) {
24054 Slog.d(TAG, "setVr2dDisplayId called for: " +
24057 synchronized (ActivityManagerService.this) {
24058 mVr2dDisplayId = vr2dDisplayId;
24063 public void saveANRState(String reason) {
24064 synchronized (ActivityManagerService.this) {
24065 final StringWriter sw = new StringWriter();
24066 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24067 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24068 if (reason != null) {
24069 pw.println(" Reason: " + reason);
24072 mActivityStarter.dump(pw, " ");
24074 pw.println("-------------------------------------------------------------------------------");
24075 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24076 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24081 mLastANRState = sw.toString();
24086 public void clearSavedANRState() {
24087 synchronized (ActivityManagerService.this) {
24088 mLastANRState = null;
24093 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24094 if (packageName == null) return false;
24096 synchronized (ActivityManagerService.this) {
24097 for (int i = 0; i < mLruProcesses.size(); i++) {
24098 final ProcessRecord processRecord = mLruProcesses.get(i);
24099 if (processRecord.uid == uid) {
24100 for (int j = 0; j < processRecord.activities.size(); j++) {
24101 final ActivityRecord activityRecord = processRecord.activities.get(j);
24102 if (packageName.equals(activityRecord.packageName)) {
24114 * Called by app main thread to wait for the network policy rules to get updated.
24116 * @param procStateSeq The sequence number indicating the process state change that the main
24117 * thread is interested in.
24120 public void waitForNetworkStateUpdate(long procStateSeq) {
24121 final int callingUid = Binder.getCallingUid();
24122 if (DEBUG_NETWORK) {
24123 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24126 synchronized (this) {
24127 record = mActiveUids.get(callingUid);
24128 if (record == null) {
24132 synchronized (record.networkStateLock) {
24133 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24134 if (DEBUG_NETWORK) {
24135 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24136 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24137 + " lastProcStateSeqDispatchedToObservers: "
24138 + record.lastDispatchedProcStateSeq);
24142 if (record.curProcStateSeq > procStateSeq) {
24143 if (DEBUG_NETWORK) {
24144 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24145 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24146 + ", procStateSeq: " + procStateSeq);
24150 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24151 if (DEBUG_NETWORK) {
24152 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24153 + procStateSeq + ", so no need to wait. Uid: "
24154 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24155 + record.lastNetworkUpdatedProcStateSeq);
24160 if (DEBUG_NETWORK) {
24161 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24162 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24164 final long startTime = SystemClock.uptimeMillis();
24165 record.waitingForNetwork = true;
24166 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24167 record.waitingForNetwork = false;
24168 final long totalTime = SystemClock.uptimeMillis() - startTime;
24169 if (totalTime >= mWaitForNetworkTimeoutMs) {
24170 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24171 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24172 + procStateSeq + " UidRec: " + record
24173 + " validateUidRec: " + mValidateUids.get(callingUid));
24175 } catch (InterruptedException e) {
24176 Thread.currentThread().interrupt();
24181 public void waitForBroadcastIdle(PrintWriter pw) {
24182 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24184 boolean idle = true;
24185 synchronized (this) {
24186 for (BroadcastQueue queue : mBroadcastQueues) {
24187 if (!queue.isIdle()) {
24188 final String msg = "Waiting for queue " + queue + " to become idle...";
24198 final String msg = "All broadcast queues are idle!";
24204 SystemClock.sleep(1000);
24210 * Return the user id of the last resumed activity.
24213 public @UserIdInt int getLastResumedActivityUserId() {
24214 enforceCallingPermission(
24215 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24216 synchronized (this) {
24217 if (mLastResumedActivity == null) {
24218 return mUserController.getCurrentUserIdLocked();
24220 return mLastResumedActivity.userId;
24224 private final class SleepTokenImpl extends SleepToken {
24225 private final String mTag;
24226 private final long mAcquireTime;
24228 public SleepTokenImpl(String tag) {
24230 mAcquireTime = SystemClock.uptimeMillis();
24234 public void release() {
24235 synchronized (ActivityManagerService.this) {
24236 if (mSleepTokens.remove(this)) {
24237 updateSleepIfNeededLocked();
24243 public String toString() {
24244 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
24249 * An implementation of IAppTask, that allows an app to manage its own tasks via
24250 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24251 * only the process that calls getAppTasks() can call the AppTask methods.
24253 class AppTaskImpl extends IAppTask.Stub {
24254 private int mTaskId;
24255 private int mCallingUid;
24257 public AppTaskImpl(int taskId, int callingUid) {
24259 mCallingUid = callingUid;
24262 private void checkCaller() {
24263 if (mCallingUid != Binder.getCallingUid()) {
24264 throw new SecurityException("Caller " + mCallingUid
24265 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24270 public void finishAndRemoveTask() {
24273 synchronized (ActivityManagerService.this) {
24274 long origId = Binder.clearCallingIdentity();
24276 // We remove the task from recents to preserve backwards
24277 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24278 REMOVE_FROM_RECENTS)) {
24279 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24282 Binder.restoreCallingIdentity(origId);
24288 public ActivityManager.RecentTaskInfo getTaskInfo() {
24291 synchronized (ActivityManagerService.this) {
24292 long origId = Binder.clearCallingIdentity();
24294 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24296 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24298 return createRecentTaskInfoFromTaskRecord(tr);
24300 Binder.restoreCallingIdentity(origId);
24306 public void moveToFront() {
24308 // Will bring task to front if it already has a root activity.
24309 final long origId = Binder.clearCallingIdentity();
24311 synchronized (this) {
24312 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24315 Binder.restoreCallingIdentity(origId);
24320 public int startActivity(IBinder whoThread, String callingPackage,
24321 Intent intent, String resolvedType, Bundle bOptions) {
24324 int callingUser = UserHandle.getCallingUserId();
24326 IApplicationThread appThread;
24327 synchronized (ActivityManagerService.this) {
24328 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24330 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24332 appThread = IApplicationThread.Stub.asInterface(whoThread);
24333 if (appThread == null) {
24334 throw new IllegalArgumentException("Bad app thread " + appThread);
24337 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24338 resolvedType, null, null, null, null, 0, 0, null, null,
24339 null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
24343 public void setExcludeFromRecents(boolean exclude) {
24346 synchronized (ActivityManagerService.this) {
24347 long origId = Binder.clearCallingIdentity();
24349 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24351 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24353 Intent intent = tr.getBaseIntent();
24355 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24357 intent.setFlags(intent.getFlags()
24358 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24361 Binder.restoreCallingIdentity(origId);
24368 * Kill processes for the user with id userId and that depend on the package named packageName
24371 public void killPackageDependents(String packageName, int userId) {
24372 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24373 if (packageName == null) {
24374 throw new NullPointerException(
24375 "Cannot kill the dependents of a package without its name.");
24378 long callingId = Binder.clearCallingIdentity();
24379 IPackageManager pm = AppGlobals.getPackageManager();
24382 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24383 } catch (RemoteException e) {
24385 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24386 throw new IllegalArgumentException(
24387 "Cannot kill dependents of non-existing package " + packageName);
24390 synchronized(this) {
24391 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24392 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24393 "dep: " + packageName);
24396 Binder.restoreCallingIdentity(callingId);
24401 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24402 throws RemoteException {
24403 final long callingId = Binder.clearCallingIdentity();
24405 mKeyguardController.dismissKeyguard(token, callback);
24407 Binder.restoreCallingIdentity(callingId);
24412 public int restartUserInBackground(final int userId) {
24413 return mUserController.restartUser(userId, /* foreground */ false);
24417 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24418 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24419 "scheduleApplicationInfoChanged()");
24421 synchronized (this) {
24422 final long origId = Binder.clearCallingIdentity();
24424 updateApplicationInfoLocked(packageNames, userId);
24426 Binder.restoreCallingIdentity(origId);
24431 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24432 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24433 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24434 final ProcessRecord app = mLruProcesses.get(i);
24435 if (app.thread == null) {
24439 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24443 final int packageCount = app.pkgList.size();
24444 for (int j = 0; j < packageCount; j++) {
24445 final String packageName = app.pkgList.keyAt(j);
24446 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24448 final ApplicationInfo ai = AppGlobals.getPackageManager()
24449 .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24451 app.thread.scheduleApplicationInfoChanged(ai);
24453 } catch (RemoteException e) {
24454 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24455 packageName, app));
24463 * Attach an agent to the specified process (proces name or PID)
24465 public void attachAgent(String process, String path) {
24467 synchronized (this) {
24468 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24469 if (proc == null || proc.thread == null) {
24470 throw new IllegalArgumentException("Unknown process: " + process);
24473 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24474 if (!isDebuggable) {
24475 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24476 throw new SecurityException("Process not debuggable: " + proc);
24480 proc.thread.attachAgent(path);
24482 } catch (RemoteException e) {
24483 throw new IllegalStateException("Process disappeared");
24488 public static class Injector {
24489 private NetworkManagementInternal mNmi;
24491 public Context getContext() {
24495 public AppOpsService getAppOpsService(File file, Handler handler) {
24496 return new AppOpsService(file, handler);
24499 public Handler getUiHandler(ActivityManagerService service) {
24500 return service.new UiHandler();
24503 public boolean isNetworkRestrictedForUid(int uid) {
24504 if (ensureHasNetworkManagementInternal()) {
24505 return mNmi.isNetworkRestrictedForUid(uid);
24510 private boolean ensureHasNetworkManagementInternal() {
24511 if (mNmi == null) {
24512 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24514 return mNmi != null;