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 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
612 /** All system services */
613 SystemServiceManager mSystemServiceManager;
614 AssistUtils mAssistUtils;
616 private Installer mInstaller;
618 /** Run all ActivityStacks through this */
619 final ActivityStackSupervisor mStackSupervisor;
620 private final KeyguardController mKeyguardController;
622 final ActivityStarter mActivityStarter;
624 final TaskChangeNotificationController mTaskChangeNotificationController;
626 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
628 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
630 public final IntentFirewall mIntentFirewall;
632 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
633 // default action automatically. Important for devices without direct input
635 private boolean mShowDialogs = true;
637 private final VrController mVrController;
639 // VR Vr2d Display Id.
640 int mVr2dDisplayId = INVALID_DISPLAY;
642 // Whether we should use SCHED_FIFO for UI and RenderThreads.
643 private boolean mUseFifoUiScheduling = false;
645 BroadcastQueue mFgBroadcastQueue;
646 BroadcastQueue mBgBroadcastQueue;
647 // Convenient for easy iteration over the queues. Foreground is first
648 // so that dispatch of foreground broadcasts gets precedence.
649 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
651 BroadcastStats mLastBroadcastStats;
652 BroadcastStats mCurBroadcastStats;
654 BroadcastQueue broadcastQueueForIntent(Intent intent) {
655 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
656 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
657 "Broadcast intent " + intent + " on "
658 + (isFg ? "foreground" : "background") + " queue");
659 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
663 * The last resumed activity. This is identical to the current resumed activity most
664 * of the time but could be different when we're pausing one activity before we resume
667 private ActivityRecord mLastResumedActivity;
670 * If non-null, we are tracking the time the user spends in the currently focused app.
672 private AppTimeTracker mCurAppTimeTracker;
675 * List of intents that were used to start the most recent tasks.
677 final RecentTasks mRecentTasks;
680 * For addAppTask: cached of the last activity component that was added.
682 ComponentName mLastAddedTaskComponent;
685 * For addAppTask: cached of the last activity uid that was added.
687 int mLastAddedTaskUid;
690 * For addAppTask: cached of the last ActivityInfo that was added.
692 ActivityInfo mLastAddedTaskActivity;
695 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
697 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
700 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
702 String mDeviceOwnerName;
704 final UserController mUserController;
706 final AppErrors mAppErrors;
709 * Dump of the activity state at the time of the last ANR. Cleared after
710 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
712 String mLastANRState;
715 * Indicates the maximum time spent waiting for the network rules to get updated.
718 long mWaitForNetworkTimeoutMs;
720 public boolean canShowErrorDialogs() {
721 return mShowDialogs && !mSleeping && !mShuttingDown
722 && !mKeyguardController.isKeyguardShowing()
723 && !(UserManager.isDeviceInDemoMode(mContext)
724 && mUserController.getCurrentUser().isDemo());
727 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
728 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
730 static void boostPriorityForLockedSection() {
731 sThreadPriorityBooster.boost();
734 static void resetPriorityAfterLockedSection() {
735 sThreadPriorityBooster.reset();
738 public class PendingAssistExtras extends Binder implements Runnable {
739 public final ActivityRecord activity;
740 public boolean isHome;
741 public final Bundle extras;
742 public final Intent intent;
743 public final String hint;
744 public final IResultReceiver receiver;
745 public final int userHandle;
746 public boolean haveResult = false;
747 public Bundle result = null;
748 public AssistStructure structure = null;
749 public AssistContent content = null;
750 public Bundle receiverExtras;
752 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
753 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
754 activity = _activity;
758 receiver = _receiver;
759 receiverExtras = _receiverExtras;
760 userHandle = _userHandle;
765 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
766 synchronized (this) {
770 pendingAssistExtrasTimedOut(this);
774 final ArrayList<PendingAssistExtras> mPendingAssistExtras
775 = new ArrayList<PendingAssistExtras>();
778 * Process management.
780 final ProcessList mProcessList = new ProcessList();
783 * All of the applications we currently have running organized by name.
784 * The keys are strings of the application package name (as
785 * returned by the package manager), and the keys are ApplicationRecord
788 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
791 * Tracking long-term execution of processes to look for abuse and other
794 final ProcessStatsService mProcessStats;
797 * The currently running isolated processes.
799 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
802 * Counter for assigning isolated process uids, to avoid frequently reusing the
805 int mNextIsolatedProcessUid = 0;
808 * The currently running heavy-weight process, if any.
810 ProcessRecord mHeavyWeightProcess = null;
813 * Non-persistent appId whitelist for background restrictions
815 int[] mBackgroundAppIdWhitelist = new int[] {
820 * Broadcast actions that will always be deliverable to unlaunched/background apps
822 ArraySet<String> mBackgroundLaunchBroadcasts;
825 * All of the processes we currently have running organized by pid.
826 * The keys are the pid running the application.
828 * <p>NOTE: This object is protected by its own lock, NOT the global
829 * activity manager lock!
831 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
834 * All of the processes that have been forced to be important. The key
835 * is the pid of the caller who requested it (we hold a death
838 abstract class ImportanceToken implements IBinder.DeathRecipient {
843 ImportanceToken(int _pid, IBinder _token, String _reason) {
850 public String toString() {
851 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
852 + " " + reason + " " + pid + " " + token + " }";
855 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
858 * List of records for processes that someone had tried to start before the
859 * system was ready. We don't start them at that point, but ensure they
860 * are started by the time booting is complete.
862 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
865 * List of persistent applications that are in the process
868 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
871 * Processes that are being forcibly torn down.
873 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
876 * List of running applications, sorted by recent usage.
877 * The first entry in the list is the least recently used.
879 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
882 * Where in mLruProcesses that the processes hosting activities start.
884 int mLruProcessActivityStart = 0;
887 * Where in mLruProcesses that the processes hosting services start.
888 * This is after (lower index) than mLruProcessesActivityStart.
890 int mLruProcessServiceStart = 0;
893 * List of processes that should gc as soon as things are idle.
895 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
898 * Processes we want to collect PSS data from.
900 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
902 private boolean mBinderTransactionTrackingEnabled = false;
905 * Last time we requested PSS data of all processes.
907 long mLastFullPssTime = SystemClock.uptimeMillis();
910 * If set, the next time we collect PSS data we should do a full collection
911 * with data from native processes and the kernel.
913 boolean mFullPssPending = false;
916 * This is the process holding what we currently consider to be
917 * the "home" activity.
919 ProcessRecord mHomeProcess;
922 * This is the process holding the activity the user last visited that
923 * is in a different process from the one they are currently in.
925 ProcessRecord mPreviousProcess;
928 * The time at which the previous process was last visible.
930 long mPreviousProcessVisibleTime;
933 * Track all uids that have actively running processes.
935 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
938 * This is for verifying the UID report flow.
940 static final boolean VALIDATE_UID_STATES = true;
941 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
944 * Packages that the user has asked to have run in screen size
945 * compatibility mode instead of filling the screen.
947 final CompatModePackages mCompatModePackages;
950 * Set of IntentSenderRecord objects that are currently active.
952 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
953 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
956 * Fingerprints (hashCode()) of stack traces that we've
957 * already logged DropBox entries for. Guarded by itself. If
958 * something (rogue user app) forces this over
959 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
961 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
962 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
965 * Strict Mode background batched logging state.
967 * The string buffer is guarded by itself, and its lock is also
968 * used to determine if another batched write is already
971 private final StringBuilder mStrictModeBuffer = new StringBuilder();
974 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
975 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
977 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
980 * Resolver for broadcast intents to registered receivers.
981 * Holds BroadcastFilter (subclass of IntentFilter).
983 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
984 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
986 protected boolean allowFilterResult(
987 BroadcastFilter filter, List<BroadcastFilter> dest) {
988 IBinder target = filter.receiverList.receiver.asBinder();
989 for (int i = dest.size() - 1; i >= 0; i--) {
990 if (dest.get(i).receiverList.receiver.asBinder() == target) {
998 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
999 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1000 || userId == filter.owningUserId) {
1001 return super.newResult(filter, match, userId);
1007 protected BroadcastFilter[] newArray(int size) {
1008 return new BroadcastFilter[size];
1012 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1013 return packageName.equals(filter.packageName);
1018 * State of all active sticky broadcasts per user. Keys are the action of the
1019 * sticky Intent, values are an ArrayList of all broadcasted intents with
1020 * that action (which should usually be one). The SparseArray is keyed
1021 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1022 * for stickies that are sent to all users.
1024 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1025 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1027 final ActiveServices mServices;
1029 final static class Association {
1030 final int mSourceUid;
1031 final String mSourceProcess;
1032 final int mTargetUid;
1033 final ComponentName mTargetComponent;
1034 final String mTargetProcess;
1042 // states of the source process when the bind occurred.
1043 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1044 long mLastStateUptime;
1045 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1046 - ActivityManager.MIN_PROCESS_STATE+1];
1048 Association(int sourceUid, String sourceProcess, int targetUid,
1049 ComponentName targetComponent, String targetProcess) {
1050 mSourceUid = sourceUid;
1051 mSourceProcess = sourceProcess;
1052 mTargetUid = targetUid;
1053 mTargetComponent = targetComponent;
1054 mTargetProcess = targetProcess;
1059 * When service association tracking is enabled, this is all of the associations we
1060 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1061 * -> association data.
1063 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1064 mAssociations = new SparseArray<>();
1065 boolean mTrackingAssociations;
1068 * Backup/restore process management
1070 String mBackupAppName = null;
1071 BackupRecord mBackupTarget = null;
1073 final ProviderMap mProviderMap;
1076 * List of content providers who have clients waiting for them. The
1077 * application is currently being launched and the provider will be
1078 * removed from this list once it is published.
1080 final ArrayList<ContentProviderRecord> mLaunchingProviders
1081 = new ArrayList<ContentProviderRecord>();
1084 * File storing persisted {@link #mGrantedUriPermissions}.
1086 private final AtomicFile mGrantFile;
1088 /** XML constants used in {@link #mGrantFile} */
1089 private static final String TAG_URI_GRANTS = "uri-grants";
1090 private static final String TAG_URI_GRANT = "uri-grant";
1091 private static final String ATTR_USER_HANDLE = "userHandle";
1092 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1093 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1094 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1095 private static final String ATTR_TARGET_PKG = "targetPkg";
1096 private static final String ATTR_URI = "uri";
1097 private static final String ATTR_MODE_FLAGS = "modeFlags";
1098 private static final String ATTR_CREATED_TIME = "createdTime";
1099 private static final String ATTR_PREFIX = "prefix";
1102 * Global set of specific {@link Uri} permissions that have been granted.
1103 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1104 * to {@link UriPermission#uri} to {@link UriPermission}.
1107 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1108 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1110 public static class GrantUri {
1111 public final int sourceUserId;
1112 public final Uri uri;
1113 public boolean prefix;
1115 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1116 this.sourceUserId = sourceUserId;
1118 this.prefix = prefix;
1122 public int hashCode() {
1124 hashCode = 31 * hashCode + sourceUserId;
1125 hashCode = 31 * hashCode + uri.hashCode();
1126 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1131 public boolean equals(Object o) {
1132 if (o instanceof GrantUri) {
1133 GrantUri other = (GrantUri) o;
1134 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1135 && prefix == other.prefix;
1141 public String toString() {
1142 String result = uri.toString() + " [user " + sourceUserId + "]";
1143 if (prefix) result += " [prefix]";
1147 public String toSafeString() {
1148 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1149 if (prefix) result += " [prefix]";
1153 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1154 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1155 ContentProvider.getUriWithoutUserId(uri), false);
1159 CoreSettingsObserver mCoreSettingsObserver;
1161 FontScaleSettingObserver mFontScaleSettingObserver;
1163 private final class FontScaleSettingObserver extends ContentObserver {
1164 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1166 public FontScaleSettingObserver() {
1168 ContentResolver resolver = mContext.getContentResolver();
1169 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1173 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1174 if (mFontScaleUri.equals(uri)) {
1175 updateFontScaleIfNeeded(userId);
1181 * Thread-local storage used to carry caller permissions over through
1182 * indirect content-provider access.
1184 private class Identity {
1185 public final IBinder token;
1186 public final int pid;
1187 public final int uid;
1189 Identity(IBinder _token, int _pid, int _uid) {
1196 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1199 * All information we have collected about the runtime performance of
1200 * any user id that can impact battery performance.
1202 final BatteryStatsService mBatteryStatsService;
1205 * Information about component usage
1207 UsageStatsManagerInternal mUsageStatsService;
1210 * Access to DeviceIdleController service.
1212 DeviceIdleController.LocalService mLocalDeviceIdleController;
1215 * Set of app ids that are whitelisted for device idle and thus background check.
1217 int[] mDeviceIdleWhitelist = new int[0];
1220 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1222 int[] mDeviceIdleTempWhitelist = new int[0];
1224 static final class PendingTempWhitelist {
1225 final int targetUid;
1226 final long duration;
1229 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1230 targetUid = _targetUid;
1231 duration = _duration;
1236 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1239 * Information about and control over application operations
1241 final AppOpsService mAppOpsService;
1243 /** Current sequencing integer of the configuration, for skipping old configurations. */
1244 private int mConfigurationSeq;
1247 * Temp object used when global and/or display override configuration is updated. It is also
1248 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1251 private Configuration mTempConfig = new Configuration();
1253 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1254 new UpdateConfigurationResult();
1255 private static final class UpdateConfigurationResult {
1256 // Configuration changes that were updated.
1258 // If the activity was relaunched to match the new configuration.
1259 boolean activityRelaunched;
1263 activityRelaunched = false;
1267 boolean mSuppressResizeConfigChanges;
1270 * Hardware-reported OpenGLES version.
1272 final int GL_ES_VERSION;
1275 * List of initialization arguments to pass to all processes when binding applications to them.
1276 * For example, references to the commonly used services.
1278 HashMap<String, IBinder> mAppBindArgs;
1279 HashMap<String, IBinder> mIsolatedAppBindArgs;
1282 * Temporary to avoid allocations. Protected by main lock.
1284 final StringBuilder mStringBuilder = new StringBuilder(256);
1287 * Used to control how we initialize the service.
1289 ComponentName mTopComponent;
1290 String mTopAction = Intent.ACTION_MAIN;
1293 volatile boolean mProcessesReady = false;
1294 volatile boolean mSystemReady = false;
1295 volatile boolean mOnBattery = false;
1296 volatile int mFactoryTest;
1298 @GuardedBy("this") boolean mBooting = false;
1299 @GuardedBy("this") boolean mCallFinishBooting = false;
1300 @GuardedBy("this") boolean mBootAnimationComplete = false;
1301 @GuardedBy("this") boolean mLaunchWarningShown = false;
1302 @GuardedBy("this") boolean mCheckedForSetup = false;
1304 final Context mContext;
1307 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1308 * change at runtime. Use mContext for non-UI purposes.
1310 final Context mUiContext;
1313 * The time at which we will allow normal application switches again,
1314 * after a call to {@link #stopAppSwitches()}.
1316 long mAppSwitchesAllowedTime;
1319 * This is set to true after the first switch after mAppSwitchesAllowedTime
1320 * is set; any switches after that will clear the time.
1322 boolean mDidAppSwitch;
1325 * Last time (in realtime) at which we checked for power usage.
1327 long mLastPowerCheckRealtime;
1330 * Last time (in uptime) at which we checked for power usage.
1332 long mLastPowerCheckUptime;
1335 * Set while we are wanting to sleep, to prevent any
1336 * activities from being started/resumed.
1338 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1340 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1341 * while in the sleep state until there is a pending transition out of sleep, in which case
1342 * mSleeping is set to false, and remains false while awake.
1344 * Whether mSleeping can quickly toggled between true/false without the device actually
1345 * display changing states is undefined.
1347 private boolean mSleeping = false;
1350 * The process state used for processes that are running the top activities.
1351 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1353 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1356 * Set while we are running a voice interaction. This overrides
1357 * sleeping while it is active.
1359 private IVoiceInteractionSession mRunningVoice;
1362 * For some direct access we need to power manager.
1364 PowerManagerInternal mLocalPowerManager;
1367 * We want to hold a wake lock while running a voice interaction session, since
1368 * this may happen with the screen off and we need to keep the CPU running to
1369 * be able to continue to interact with the user.
1371 PowerManager.WakeLock mVoiceWakeLock;
1374 * State of external calls telling us if the device is awake or asleep.
1376 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1379 * A list of tokens that cause the top activity to be put to sleep.
1380 * They are used by components that may hide and block interaction with underlying
1383 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1386 * Set if we are shutting down the system, similar to sleeping.
1388 boolean mShuttingDown = false;
1391 * Current sequence id for oom_adj computation traversal.
1396 * Current sequence id for process LRU updating.
1401 * Keep track of the non-cached/empty process we last found, to help
1402 * determine how to distribute cached/empty processes next time.
1404 int mNumNonCachedProcs = 0;
1407 * Keep track of the number of cached hidden procs, to balance oom adj
1408 * distribution between those and empty procs.
1410 int mNumCachedHiddenProcs = 0;
1413 * Keep track of the number of service processes we last found, to
1414 * determine on the next iteration which should be B services.
1416 int mNumServiceProcs = 0;
1417 int mNewNumAServiceProcs = 0;
1418 int mNewNumServiceProcs = 0;
1421 * Allow the current computed overall memory level of the system to go down?
1422 * This is set to false when we are killing processes for reasons other than
1423 * memory management, so that the now smaller process list will not be taken as
1424 * an indication that memory is tighter.
1426 boolean mAllowLowerMemLevel = false;
1429 * The last computed memory level, for holding when we are in a state that
1430 * processes are going away for other reasons.
1432 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1435 * The last total number of process we have, to determine if changes actually look
1436 * like a shrinking number of process due to lower RAM.
1438 int mLastNumProcesses;
1441 * The uptime of the last time we performed idle maintenance.
1443 long mLastIdleTime = SystemClock.uptimeMillis();
1446 * Total time spent with RAM that has been added in the past since the last idle time.
1448 long mLowRamTimeSinceLastIdle = 0;
1451 * If RAM is currently low, when that horrible situation started.
1453 long mLowRamStartTime = 0;
1456 * For reporting to battery stats the current top application.
1458 private String mCurResumedPackage = null;
1459 private int mCurResumedUid = -1;
1462 * For reporting to battery stats the apps currently running foreground
1463 * service. The ProcessMap is package/uid tuples; each of these contain
1464 * an array of the currently foreground processes.
1466 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1467 = new ProcessMap<ArrayList<ProcessRecord>>();
1470 * Set if the systemServer made a call to enterSafeMode.
1475 * If true, we are running under a test environment so will sample PSS from processes
1476 * much more rapidly to try to collect better data when the tests are rapidly
1477 * running through apps.
1479 boolean mTestPssMode = false;
1481 String mDebugApp = null;
1482 boolean mWaitForDebugger = false;
1483 boolean mDebugTransient = false;
1484 String mOrigDebugApp = null;
1485 boolean mOrigWaitForDebugger = false;
1486 boolean mAlwaysFinishActivities = false;
1487 boolean mForceResizableActivities;
1489 * Flag that indicates if multi-window is enabled.
1491 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1492 * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
1493 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1494 * At least one of the forms of multi-window must be enabled in order for this flag to be
1495 * initialized to 'true'.
1497 * @see #mSupportsSplitScreenMultiWindow
1498 * @see #mSupportsFreeformWindowManagement
1499 * @see #mSupportsPictureInPicture
1500 * @see #mSupportsMultiDisplay
1502 boolean mSupportsMultiWindow;
1503 boolean mSupportsSplitScreenMultiWindow;
1504 boolean mSupportsFreeformWindowManagement;
1505 boolean mSupportsPictureInPicture;
1506 boolean mSupportsMultiDisplay;
1507 boolean mSupportsLeanbackOnly;
1508 IActivityController mController = null;
1509 boolean mControllerIsAMonkey = false;
1510 String mProfileApp = null;
1511 ProcessRecord mProfileProc = null;
1512 String mProfileFile;
1513 ParcelFileDescriptor mProfileFd;
1514 int mSamplingInterval = 0;
1515 boolean mAutoStopProfiler = false;
1516 boolean mStreamingOutput = false;
1517 int mProfileType = 0;
1518 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1519 String mMemWatchDumpProcName;
1520 String mMemWatchDumpFile;
1521 int mMemWatchDumpPid;
1522 int mMemWatchDumpUid;
1523 String mTrackAllocationApp = null;
1524 String mNativeDebuggingApp = null;
1526 final long[] mTmpLong = new long[2];
1528 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1531 * A global counter for generating sequence numbers.
1532 * This value will be used when incrementing sequence numbers in individual uidRecords.
1534 * Having a global counter ensures that seq numbers are monotonically increasing for a
1535 * particular uid even when the uidRecord is re-created.
1539 long mProcStateSeqCounter = 0;
1541 private final Injector mInjector;
1543 static final class ProcessChangeItem {
1544 static final int CHANGE_ACTIVITIES = 1<<0;
1549 boolean foregroundActivities;
1552 static final class UidObserverRegistration {
1558 final SparseIntArray lastProcStates;
1560 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1564 cutpoint = _cutpoint;
1565 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1566 lastProcStates = new SparseIntArray();
1568 lastProcStates = null;
1573 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1574 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1576 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1577 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1579 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1580 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1582 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1583 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1586 * Runtime CPU use collection thread. This object's lock is used to
1587 * perform synchronization with the thread (notifying it to run).
1589 final Thread mProcessCpuThread;
1592 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1593 * Must acquire this object's lock when accessing it.
1594 * NOTE: this lock will be held while doing long operations (trawling
1595 * through all processes in /proc), so it should never be acquired by
1596 * any critical paths such as when holding the main activity manager lock.
1598 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1599 MONITOR_THREAD_CPU_USAGE);
1600 final AtomicLong mLastCpuTime = new AtomicLong(0);
1601 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1602 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1604 long mLastWriteTime = 0;
1607 * Used to retain an update lock when the foreground activity is in
1610 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1613 * Set to true after the system has finished booting.
1615 boolean mBooted = false;
1617 WindowManagerService mWindowManager;
1618 final ActivityThread mSystemThread;
1620 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1621 final ProcessRecord mApp;
1623 final IApplicationThread mAppThread;
1625 AppDeathRecipient(ProcessRecord app, int pid,
1626 IApplicationThread thread) {
1627 if (DEBUG_ALL) Slog.v(
1628 TAG, "New death recipient " + this
1629 + " for thread " + thread.asBinder());
1632 mAppThread = thread;
1636 public void binderDied() {
1637 if (DEBUG_ALL) Slog.v(
1638 TAG, "Death received in " + this
1639 + " for thread " + mAppThread.asBinder());
1640 synchronized(ActivityManagerService.this) {
1641 appDiedLocked(mApp, mPid, mAppThread, true);
1646 static final int SHOW_ERROR_UI_MSG = 1;
1647 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1648 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1649 static final int UPDATE_CONFIGURATION_MSG = 4;
1650 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1651 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1652 static final int SERVICE_TIMEOUT_MSG = 12;
1653 static final int UPDATE_TIME_ZONE = 13;
1654 static final int SHOW_UID_ERROR_UI_MSG = 14;
1655 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1656 static final int PROC_START_TIMEOUT_MSG = 20;
1657 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1658 static final int KILL_APPLICATION_MSG = 22;
1659 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1660 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1661 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1662 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1663 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1664 static final int CLEAR_DNS_CACHE_MSG = 28;
1665 static final int UPDATE_HTTP_PROXY_MSG = 29;
1666 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1667 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1668 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1669 static final int REPORT_MEM_USAGE_MSG = 33;
1670 static final int REPORT_USER_SWITCH_MSG = 34;
1671 static final int CONTINUE_USER_SWITCH_MSG = 35;
1672 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1673 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1674 static final int PERSIST_URI_GRANTS_MSG = 38;
1675 static final int REQUEST_ALL_PSS_MSG = 39;
1676 static final int START_PROFILES_MSG = 40;
1677 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1678 static final int SYSTEM_USER_START_MSG = 42;
1679 static final int SYSTEM_USER_CURRENT_MSG = 43;
1680 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1681 static final int FINISH_BOOTING_MSG = 45;
1682 static final int START_USER_SWITCH_UI_MSG = 46;
1683 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1684 static final int DISMISS_DIALOG_UI_MSG = 48;
1685 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1686 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1687 static final int DELETE_DUMPHEAP_MSG = 51;
1688 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1689 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1690 static final int REPORT_TIME_TRACKER_MSG = 54;
1691 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1692 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1693 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1694 static final int IDLE_UIDS_MSG = 58;
1695 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1696 static final int LOG_STACK_STATE = 60;
1697 static final int VR_MODE_CHANGE_MSG = 61;
1698 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1699 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1700 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1701 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1702 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1703 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1704 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1705 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1706 static final int START_USER_SWITCH_FG_MSG = 712;
1708 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1709 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1710 static final int FIRST_COMPAT_MODE_MSG = 300;
1711 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1713 static ServiceThread sKillThread = null;
1714 static KillHandler sKillHandler = null;
1716 CompatModeDialog mCompatModeDialog;
1717 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1718 long mLastMemUsageReportTime = 0;
1721 * Flag whether the current user is a "monkey", i.e. whether
1722 * the UI is driven by a UI automation tool.
1724 private boolean mUserIsMonkey;
1726 /** Flag whether the device has a Recents UI */
1727 boolean mHasRecents;
1729 /** The dimensions of the thumbnails in the Recents UI. */
1730 int mThumbnailWidth;
1731 int mThumbnailHeight;
1732 float mFullscreenThumbnailScale;
1734 final ServiceThread mHandlerThread;
1735 final MainHandler mHandler;
1736 final Handler mUiHandler;
1738 final ActivityManagerConstants mConstants;
1740 PackageManagerInternal mPackageManagerInt;
1742 // VoiceInteraction session ID that changes for each new request except when
1743 // being called for multiwindow assist in a single session.
1744 private int mViSessionId = 1000;
1746 final boolean mPermissionReviewRequired;
1749 * Current global configuration information. Contains general settings for the entire system,
1750 * also corresponds to the merged configuration of the default display.
1752 Configuration getGlobalConfiguration() {
1753 return mStackSupervisor.getConfiguration();
1756 final class KillHandler extends Handler {
1757 static final int KILL_PROCESS_GROUP_MSG = 4000;
1759 public KillHandler(Looper looper) {
1760 super(looper, null, true);
1764 public void handleMessage(Message msg) {
1766 case KILL_PROCESS_GROUP_MSG:
1768 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1769 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1770 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1775 super.handleMessage(msg);
1780 final class UiHandler extends Handler {
1781 public UiHandler() {
1782 super(com.android.server.UiThread.get().getLooper(), null, true);
1786 public void handleMessage(Message msg) {
1788 case SHOW_ERROR_UI_MSG: {
1789 mAppErrors.handleShowAppErrorUi(msg);
1790 ensureBootCompleted();
1792 case SHOW_NOT_RESPONDING_UI_MSG: {
1793 mAppErrors.handleShowAnrUi(msg);
1794 ensureBootCompleted();
1796 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1797 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1798 synchronized (ActivityManagerService.this) {
1799 ProcessRecord proc = (ProcessRecord) data.get("app");
1801 Slog.e(TAG, "App not found when showing strict mode dialog.");
1804 if (proc.crashDialog != null) {
1805 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1808 AppErrorResult res = (AppErrorResult) data.get("result");
1809 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1810 Dialog d = new StrictModeViolationDialog(mUiContext,
1811 ActivityManagerService.this, res, proc);
1813 proc.crashDialog = d;
1815 // The device is asleep, so just pretend that the user
1816 // saw a crash dialog and hit "force quit".
1820 ensureBootCompleted();
1822 case SHOW_FACTORY_ERROR_UI_MSG: {
1823 Dialog d = new FactoryErrorDialog(
1824 mUiContext, msg.getData().getCharSequence("msg"));
1826 ensureBootCompleted();
1828 case WAIT_FOR_DEBUGGER_UI_MSG: {
1829 synchronized (ActivityManagerService.this) {
1830 ProcessRecord app = (ProcessRecord)msg.obj;
1831 if (msg.arg1 != 0) {
1832 if (!app.waitedForDebugger) {
1833 Dialog d = new AppWaitingForDebuggerDialog(
1834 ActivityManagerService.this,
1837 app.waitedForDebugger = true;
1841 if (app.waitDialog != null) {
1842 app.waitDialog.dismiss();
1843 app.waitDialog = null;
1848 case SHOW_UID_ERROR_UI_MSG: {
1850 AlertDialog d = new BaseErrorDialog(mUiContext);
1851 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1852 d.setCancelable(false);
1853 d.setTitle(mUiContext.getText(R.string.android_system_label));
1854 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1855 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1856 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1860 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1862 AlertDialog d = new BaseErrorDialog(mUiContext);
1863 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1864 d.setCancelable(false);
1865 d.setTitle(mUiContext.getText(R.string.android_system_label));
1866 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1867 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1868 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1872 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1873 synchronized (ActivityManagerService.this) {
1874 ActivityRecord ar = (ActivityRecord) msg.obj;
1875 if (mCompatModeDialog != null) {
1876 if (mCompatModeDialog.mAppInfo.packageName.equals(
1877 ar.info.applicationInfo.packageName)) {
1880 mCompatModeDialog.dismiss();
1881 mCompatModeDialog = null;
1883 if (ar != null && false) {
1884 if (mCompatModePackages.getPackageAskCompatModeLocked(
1886 int mode = mCompatModePackages.computeCompatModeLocked(
1887 ar.info.applicationInfo);
1888 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1889 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1890 mCompatModeDialog = new CompatModeDialog(
1891 ActivityManagerService.this, mUiContext,
1892 ar.info.applicationInfo);
1893 mCompatModeDialog.show();
1900 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1901 synchronized (ActivityManagerService.this) {
1902 final ActivityRecord ar = (ActivityRecord) msg.obj;
1903 if (mUnsupportedDisplaySizeDialog != null) {
1904 mUnsupportedDisplaySizeDialog.dismiss();
1905 mUnsupportedDisplaySizeDialog = null;
1907 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1909 // TODO(multi-display): Show dialog on appropriate display.
1910 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1911 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1912 mUnsupportedDisplaySizeDialog.show();
1917 case START_USER_SWITCH_UI_MSG: {
1918 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1921 case DISMISS_DIALOG_UI_MSG: {
1922 final Dialog d = (Dialog) msg.obj;
1926 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1927 dispatchProcessesChanged();
1930 case DISPATCH_PROCESS_DIED_UI_MSG: {
1931 final int pid = msg.arg1;
1932 final int uid = msg.arg2;
1933 dispatchProcessDied(pid, uid);
1936 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1937 dispatchUidsChanged();
1939 case PUSH_TEMP_WHITELIST_UI_MSG: {
1940 pushTempWhitelist();
1946 final class MainHandler extends Handler {
1947 public MainHandler(Looper looper) {
1948 super(looper, null, true);
1952 public void handleMessage(Message msg) {
1954 case UPDATE_CONFIGURATION_MSG: {
1955 final ContentResolver resolver = mContext.getContentResolver();
1956 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1959 case GC_BACKGROUND_PROCESSES_MSG: {
1960 synchronized (ActivityManagerService.this) {
1961 performAppGcsIfAppropriateLocked();
1964 case SERVICE_TIMEOUT_MSG: {
1965 mServices.serviceTimeout((ProcessRecord)msg.obj);
1967 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1968 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1970 case SERVICE_FOREGROUND_CRASH_MSG: {
1971 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1973 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1974 RemoteCallbackList<IResultReceiver> callbacks
1975 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1976 int N = callbacks.beginBroadcast();
1977 for (int i = 0; i < N; i++) {
1979 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1980 } catch (RemoteException e) {
1983 callbacks.finishBroadcast();
1985 case UPDATE_TIME_ZONE: {
1986 synchronized (ActivityManagerService.this) {
1987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1988 ProcessRecord r = mLruProcesses.get(i);
1989 if (r.thread != null) {
1991 r.thread.updateTimeZone();
1992 } catch (RemoteException ex) {
1993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1999 case CLEAR_DNS_CACHE_MSG: {
2000 synchronized (ActivityManagerService.this) {
2001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2002 ProcessRecord r = mLruProcesses.get(i);
2003 if (r.thread != null) {
2005 r.thread.clearDnsCache();
2006 } catch (RemoteException ex) {
2007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2013 case UPDATE_HTTP_PROXY_MSG: {
2014 ProxyInfo proxy = (ProxyInfo)msg.obj;
2017 String exclList = "";
2018 Uri pacFileUrl = Uri.EMPTY;
2019 if (proxy != null) {
2020 host = proxy.getHost();
2021 port = Integer.toString(proxy.getPort());
2022 exclList = proxy.getExclusionListAsString();
2023 pacFileUrl = proxy.getPacFileUrl();
2025 synchronized (ActivityManagerService.this) {
2026 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2027 ProcessRecord r = mLruProcesses.get(i);
2028 if (r.thread != null) {
2030 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2031 } catch (RemoteException ex) {
2032 Slog.w(TAG, "Failed to update http proxy for: " +
2033 r.info.processName);
2039 case PROC_START_TIMEOUT_MSG: {
2040 ProcessRecord app = (ProcessRecord)msg.obj;
2041 synchronized (ActivityManagerService.this) {
2042 processStartTimedOutLocked(app);
2045 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2046 ProcessRecord app = (ProcessRecord)msg.obj;
2047 synchronized (ActivityManagerService.this) {
2048 processContentProviderPublishTimedOutLocked(app);
2051 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2052 synchronized (ActivityManagerService.this) {
2053 mActivityStarter.doPendingActivityLaunchesLocked(true);
2056 case KILL_APPLICATION_MSG: {
2057 synchronized (ActivityManagerService.this) {
2058 final int appId = msg.arg1;
2059 final int userId = msg.arg2;
2060 Bundle bundle = (Bundle)msg.obj;
2061 String pkg = bundle.getString("pkg");
2062 String reason = bundle.getString("reason");
2063 forceStopPackageLocked(pkg, appId, false, false, true, false,
2064 false, userId, reason);
2067 case FINALIZE_PENDING_INTENT_MSG: {
2068 ((PendingIntentRecord)msg.obj).completeFinalize();
2070 case POST_HEAVY_NOTIFICATION_MSG: {
2071 INotificationManager inm = NotificationManager.getService();
2076 ActivityRecord root = (ActivityRecord)msg.obj;
2077 ProcessRecord process = root.app;
2078 if (process == null) {
2083 Context context = mContext.createPackageContext(process.info.packageName, 0);
2084 String text = mContext.getString(R.string.heavy_weight_notification,
2085 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2086 Notification notification =
2087 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2088 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2092 .setColor(mContext.getColor(
2093 com.android.internal.R.color.system_notification_accent_color))
2094 .setContentTitle(text)
2096 mContext.getText(R.string.heavy_weight_notification_detail))
2097 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2098 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2099 new UserHandle(root.userId)))
2102 inm.enqueueNotificationWithTag("android", "android", null,
2103 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2104 notification, root.userId);
2105 } catch (RuntimeException e) {
2106 Slog.w(ActivityManagerService.TAG,
2107 "Error showing notification for heavy-weight app", e);
2108 } catch (RemoteException e) {
2110 } catch (NameNotFoundException e) {
2111 Slog.w(TAG, "Unable to create context for heavy notification", e);
2114 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2115 INotificationManager inm = NotificationManager.getService();
2120 inm.cancelNotificationWithTag("android", null,
2121 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2122 } catch (RuntimeException e) {
2123 Slog.w(ActivityManagerService.TAG,
2124 "Error canceling notification for service", e);
2125 } catch (RemoteException e) {
2128 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2129 synchronized (ActivityManagerService.this) {
2130 checkExcessivePowerUsageLocked(true);
2131 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2132 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2133 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2136 case REPORT_MEM_USAGE_MSG: {
2137 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2138 Thread thread = new Thread() {
2139 @Override public void run() {
2140 reportMemUsage(memInfos);
2146 case START_USER_SWITCH_FG_MSG: {
2147 mUserController.startUserInForeground(msg.arg1);
2150 case REPORT_USER_SWITCH_MSG: {
2151 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2154 case CONTINUE_USER_SWITCH_MSG: {
2155 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2158 case USER_SWITCH_TIMEOUT_MSG: {
2159 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2162 case IMMERSIVE_MODE_LOCK_MSG: {
2163 final boolean nextState = (msg.arg1 != 0);
2164 if (mUpdateLock.isHeld() != nextState) {
2165 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2166 "Applying new update lock state '" + nextState
2167 + "' for " + (ActivityRecord)msg.obj);
2169 mUpdateLock.acquire();
2171 mUpdateLock.release();
2176 case PERSIST_URI_GRANTS_MSG: {
2177 writeGrantedUriPermissions();
2180 case REQUEST_ALL_PSS_MSG: {
2181 synchronized (ActivityManagerService.this) {
2182 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2186 case START_PROFILES_MSG: {
2187 synchronized (ActivityManagerService.this) {
2188 mUserController.startProfilesLocked();
2192 case UPDATE_TIME_PREFERENCE_MSG: {
2193 // The user's time format preference might have changed.
2194 // For convenience we re-use the Intent extra values.
2195 synchronized (ActivityManagerService.this) {
2196 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2197 ProcessRecord r = mLruProcesses.get(i);
2198 if (r.thread != null) {
2200 r.thread.updateTimePrefs(msg.arg1);
2201 } catch (RemoteException ex) {
2202 Slog.w(TAG, "Failed to update preferences for: "
2203 + r.info.processName);
2210 case SYSTEM_USER_START_MSG: {
2211 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2212 Integer.toString(msg.arg1), msg.arg1);
2213 mSystemServiceManager.startUser(msg.arg1);
2216 case SYSTEM_USER_UNLOCK_MSG: {
2217 final int userId = msg.arg1;
2218 mSystemServiceManager.unlockUser(userId);
2219 synchronized (ActivityManagerService.this) {
2220 mRecentTasks.loadUserRecentsLocked(userId);
2222 if (userId == UserHandle.USER_SYSTEM) {
2223 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2225 installEncryptionUnawareProviders(userId);
2226 mUserController.finishUserUnlocked((UserState) msg.obj);
2229 case SYSTEM_USER_CURRENT_MSG: {
2230 mBatteryStatsService.noteEvent(
2231 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2232 Integer.toString(msg.arg2), msg.arg2);
2233 mBatteryStatsService.noteEvent(
2234 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2235 Integer.toString(msg.arg1), msg.arg1);
2236 mSystemServiceManager.switchUser(msg.arg1);
2239 case ENTER_ANIMATION_COMPLETE_MSG: {
2240 synchronized (ActivityManagerService.this) {
2241 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2242 if (r != null && r.app != null && r.app.thread != null) {
2244 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2245 } catch (RemoteException e) {
2251 case FINISH_BOOTING_MSG: {
2252 if (msg.arg1 != 0) {
2253 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2255 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2257 if (msg.arg2 != 0) {
2258 enableScreenAfterBoot();
2262 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2264 Locale l = (Locale) msg.obj;
2265 IBinder service = ServiceManager.getService("mount");
2266 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2267 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2268 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2269 } catch (RemoteException e) {
2270 Log.e(TAG, "Error storing locale for decryption UI", e);
2274 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2275 final int uid = msg.arg1;
2276 final byte[] firstPacket = (byte[]) msg.obj;
2278 synchronized (mPidsSelfLocked) {
2279 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2280 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2283 p.thread.notifyCleartextNetwork(firstPacket);
2284 } catch (RemoteException ignored) {
2291 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2292 final String procName;
2294 final long memLimit;
2295 final String reportPackage;
2296 synchronized (ActivityManagerService.this) {
2297 procName = mMemWatchDumpProcName;
2298 uid = mMemWatchDumpUid;
2299 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2301 val = mMemWatchProcesses.get(procName, 0);
2304 memLimit = val.first;
2305 reportPackage = val.second;
2308 reportPackage = null;
2311 if (procName == null) {
2315 if (DEBUG_PSS) Slog.d(TAG_PSS,
2316 "Showing dump heap notification from " + procName + "/" + uid);
2318 INotificationManager inm = NotificationManager.getService();
2323 String text = mContext.getString(R.string.dump_heap_notification, procName);
2326 Intent deleteIntent = new Intent();
2327 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2328 Intent intent = new Intent();
2329 intent.setClassName("android", DumpHeapActivity.class.getName());
2330 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2331 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2332 if (reportPackage != null) {
2333 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2335 int userId = UserHandle.getUserId(uid);
2336 Notification notification =
2337 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2338 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2341 .setAutoCancel(true)
2343 .setColor(mContext.getColor(
2344 com.android.internal.R.color.system_notification_accent_color))
2345 .setContentTitle(text)
2347 mContext.getText(R.string.dump_heap_notification_detail))
2348 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2349 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2350 new UserHandle(userId)))
2351 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2352 deleteIntent, 0, UserHandle.SYSTEM))
2356 inm.enqueueNotificationWithTag("android", "android", null,
2357 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2358 notification, userId);
2359 } catch (RuntimeException e) {
2360 Slog.w(ActivityManagerService.TAG,
2361 "Error showing notification for dump heap", e);
2362 } catch (RemoteException e) {
2365 case DELETE_DUMPHEAP_MSG: {
2366 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2367 null, DumpHeapActivity.JAVA_URI,
2368 Intent.FLAG_GRANT_READ_URI_PERMISSION
2369 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2370 UserHandle.myUserId());
2371 synchronized (ActivityManagerService.this) {
2372 mMemWatchDumpFile = null;
2373 mMemWatchDumpProcName = null;
2374 mMemWatchDumpPid = -1;
2375 mMemWatchDumpUid = -1;
2378 case FOREGROUND_PROFILE_CHANGED_MSG: {
2379 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2381 case REPORT_TIME_TRACKER_MSG: {
2382 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2383 tracker.deliverResult(mContext);
2385 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2386 mUserController.dispatchUserSwitchComplete(msg.arg1);
2388 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2389 mUserController.dispatchLockedBootComplete(msg.arg1);
2391 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2392 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2394 connection.shutdown();
2395 } catch (RemoteException e) {
2396 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2398 // Only a UiAutomation can set this flag and now that
2399 // it is finished we make sure it is reset to its default.
2400 mUserIsMonkey = false;
2402 case IDLE_UIDS_MSG: {
2405 case VR_MODE_CHANGE_MSG: {
2406 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2409 synchronized (ActivityManagerService.this) {
2410 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2411 mWindowManager.disableNonVrUi(disableNonVrUi);
2412 if (disableNonVrUi) {
2413 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2414 // then remove the pinned stack.
2415 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2417 if (pinnedStack != null) {
2418 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2423 case NOTIFY_VR_SLEEPING_MSG: {
2424 notifyVrManagerOfSleepState(msg.arg1 != 0);
2426 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2427 synchronized (ActivityManagerService.this) {
2428 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2429 ProcessRecord r = mLruProcesses.get(i);
2430 if (r.thread != null) {
2432 r.thread.handleTrustStorageUpdate();
2433 } catch (RemoteException ex) {
2434 Slog.w(TAG, "Failed to handle trust storage update for: " +
2435 r.info.processName);
2445 static final int COLLECT_PSS_BG_MSG = 1;
2447 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2449 public void handleMessage(Message msg) {
2451 case COLLECT_PSS_BG_MSG: {
2452 long start = SystemClock.uptimeMillis();
2453 MemInfoReader memInfo = null;
2454 synchronized (ActivityManagerService.this) {
2455 if (mFullPssPending) {
2456 mFullPssPending = false;
2457 memInfo = new MemInfoReader();
2460 if (memInfo != null) {
2461 updateCpuStatsNow();
2462 long nativeTotalPss = 0;
2463 final List<ProcessCpuTracker.Stats> stats;
2464 synchronized (mProcessCpuTracker) {
2465 stats = mProcessCpuTracker.getStats( (st)-> {
2466 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2469 final int N = stats.size();
2470 for (int j = 0; j < N; j++) {
2471 synchronized (mPidsSelfLocked) {
2472 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2473 // This is one of our own processes; skip it.
2477 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2479 memInfo.readMemInfo();
2480 synchronized (ActivityManagerService.this) {
2481 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2482 + (SystemClock.uptimeMillis()-start) + "ms");
2483 final long cachedKb = memInfo.getCachedSizeKb();
2484 final long freeKb = memInfo.getFreeSizeKb();
2485 final long zramKb = memInfo.getZramTotalSizeKb();
2486 final long kernelKb = memInfo.getKernelUsedSizeKb();
2487 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2488 kernelKb*1024, nativeTotalPss*1024);
2489 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2495 long[] tmp = new long[2];
2501 synchronized (ActivityManagerService.this) {
2502 if (mPendingPssProcesses.size() <= 0) {
2503 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2504 "Collected PSS of " + num + " processes in "
2505 + (SystemClock.uptimeMillis() - start) + "ms");
2506 mPendingPssProcesses.clear();
2509 proc = mPendingPssProcesses.remove(0);
2510 procState = proc.pssProcState;
2511 lastPssTime = proc.lastPssTime;
2512 if (proc.thread != null && procState == proc.setProcState
2513 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2514 < SystemClock.uptimeMillis()) {
2522 long pss = Debug.getPss(pid, tmp, null);
2523 synchronized (ActivityManagerService.this) {
2524 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2525 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2527 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2528 SystemClock.uptimeMillis());
2538 public void setSystemProcess() {
2540 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2541 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2542 ServiceManager.addService("meminfo", new MemBinder(this));
2543 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2544 ServiceManager.addService("dbinfo", new DbBinder(this));
2545 if (MONITOR_CPU_USAGE) {
2546 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2548 ServiceManager.addService("permission", new PermissionController(this));
2549 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2551 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2552 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2553 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2555 synchronized (this) {
2556 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2557 app.persistent = true;
2559 app.maxAdj = ProcessList.SYSTEM_ADJ;
2560 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2561 synchronized (mPidsSelfLocked) {
2562 mPidsSelfLocked.put(app.pid, app);
2564 updateLruProcessLocked(app, false, null);
2565 updateOomAdjLocked();
2567 } catch (PackageManager.NameNotFoundException e) {
2568 throw new RuntimeException(
2569 "Unable to find android system package", e);
2573 public void setWindowManager(WindowManagerService wm) {
2574 mWindowManager = wm;
2575 mStackSupervisor.setWindowManager(wm);
2576 mActivityStarter.setWindowManager(wm);
2579 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2580 mUsageStatsService = usageStatsManager;
2583 public void startObservingNativeCrashes() {
2584 final NativeCrashListener ncl = new NativeCrashListener(this);
2588 public IAppOpsService getAppOpsService() {
2589 return mAppOpsService;
2592 static class MemBinder extends Binder {
2593 ActivityManagerService mActivityManagerService;
2594 MemBinder(ActivityManagerService activityManagerService) {
2595 mActivityManagerService = activityManagerService;
2599 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2600 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2601 "meminfo", pw)) return;
2602 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2606 static class GraphicsBinder extends Binder {
2607 ActivityManagerService mActivityManagerService;
2608 GraphicsBinder(ActivityManagerService activityManagerService) {
2609 mActivityManagerService = activityManagerService;
2613 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2614 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2615 "gfxinfo", pw)) return;
2616 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2620 static class DbBinder extends Binder {
2621 ActivityManagerService mActivityManagerService;
2622 DbBinder(ActivityManagerService activityManagerService) {
2623 mActivityManagerService = activityManagerService;
2627 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2628 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2629 "dbinfo", pw)) return;
2630 mActivityManagerService.dumpDbInfo(fd, pw, args);
2634 static class CpuBinder extends Binder {
2635 ActivityManagerService mActivityManagerService;
2636 CpuBinder(ActivityManagerService activityManagerService) {
2637 mActivityManagerService = activityManagerService;
2641 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2642 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2643 "cpuinfo", pw)) return;
2644 synchronized (mActivityManagerService.mProcessCpuTracker) {
2645 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2646 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2647 SystemClock.uptimeMillis()));
2652 public static final class Lifecycle extends SystemService {
2653 private final ActivityManagerService mService;
2655 public Lifecycle(Context context) {
2657 mService = new ActivityManagerService(context);
2661 public void onStart() {
2665 public ActivityManagerService getService() {
2671 public ActivityManagerService(Injector injector) {
2672 mInjector = injector;
2673 mContext = mInjector.getContext();
2676 mActivityStarter = null;
2678 mAppOpsService = mInjector.getAppOpsService(null, null);
2679 mBatteryStatsService = null;
2680 mCompatModePackages = null;
2684 mHandlerThread = null;
2685 mIntentFirewall = null;
2686 mKeyguardController = null;
2687 mPermissionReviewRequired = false;
2688 mProcessCpuThread = null;
2689 mProcessStats = null;
2690 mProviderMap = null;
2691 mRecentTasks = null;
2693 mStackSupervisor = null;
2694 mSystemThread = null;
2695 mTaskChangeNotificationController = null;
2696 mUiHandler = injector.getUiHandler(null);
2697 mUserController = null;
2698 mVrController = null;
2701 // Note: This method is invoked on the main thread but may need to attach various
2702 // handlers to other threads. So take care to be explicit about the looper.
2703 public ActivityManagerService(Context systemContext) {
2704 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2705 mInjector = new Injector();
2706 mContext = systemContext;
2708 mFactoryTest = FactoryTest.getMode();
2709 mSystemThread = ActivityThread.currentActivityThread();
2710 mUiContext = mSystemThread.getSystemUiContext();
2712 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2714 mPermissionReviewRequired = mContext.getResources().getBoolean(
2715 com.android.internal.R.bool.config_permissionReviewRequired);
2717 mHandlerThread = new ServiceThread(TAG,
2718 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2719 mHandlerThread.start();
2720 mHandler = new MainHandler(mHandlerThread.getLooper());
2721 mUiHandler = mInjector.getUiHandler(this);
2723 mConstants = new ActivityManagerConstants(this, mHandler);
2725 /* static; one-time init here */
2726 if (sKillHandler == null) {
2727 sKillThread = new ServiceThread(TAG + ":kill",
2728 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2729 sKillThread.start();
2730 sKillHandler = new KillHandler(sKillThread.getLooper());
2733 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2734 "foreground", BROADCAST_FG_TIMEOUT, false);
2735 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2736 "background", BROADCAST_BG_TIMEOUT, true);
2737 mBroadcastQueues[0] = mFgBroadcastQueue;
2738 mBroadcastQueues[1] = mBgBroadcastQueue;
2740 mServices = new ActiveServices(this);
2741 mProviderMap = new ProviderMap(this);
2742 mAppErrors = new AppErrors(mUiContext, this);
2744 // TODO: Move creation of battery stats service outside of activity manager service.
2745 File dataDir = Environment.getDataDirectory();
2746 File systemDir = new File(dataDir, "system");
2748 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2749 mBatteryStatsService.getActiveStatistics().readLocked();
2750 mBatteryStatsService.scheduleWriteToDisk();
2751 mOnBattery = DEBUG_POWER ? true
2752 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2753 mBatteryStatsService.getActiveStatistics().setCallback(this);
2755 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2757 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2758 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2759 new IAppOpsCallback.Stub() {
2760 @Override public void opChanged(int op, int uid, String packageName) {
2761 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2762 if (mAppOpsService.checkOperation(op, uid, packageName)
2763 != AppOpsManager.MODE_ALLOWED) {
2764 runInBackgroundDisabled(uid);
2770 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2772 mUserController = new UserController(this);
2774 mVrController = new VrController(this);
2776 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2777 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2779 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2780 mUseFifoUiScheduling = true;
2783 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2784 mTempConfig.setToDefaults();
2785 mTempConfig.setLocales(LocaleList.getDefault());
2786 mConfigurationSeq = mTempConfig.seq = 1;
2787 mStackSupervisor = createStackSupervisor();
2788 mStackSupervisor.onConfigurationChanged(mTempConfig);
2789 mKeyguardController = mStackSupervisor.mKeyguardController;
2790 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2791 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2792 mTaskChangeNotificationController =
2793 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2794 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2795 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2797 mProcessCpuThread = new Thread("CpuTracker") {
2800 synchronized (mProcessCpuTracker) {
2801 mProcessCpuInitLatch.countDown();
2802 mProcessCpuTracker.init();
2807 synchronized(this) {
2808 final long now = SystemClock.uptimeMillis();
2809 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2810 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2811 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2812 // + ", write delay=" + nextWriteDelay);
2813 if (nextWriteDelay < nextCpuDelay) {
2814 nextCpuDelay = nextWriteDelay;
2816 if (nextCpuDelay > 0) {
2817 mProcessCpuMutexFree.set(true);
2818 this.wait(nextCpuDelay);
2821 } catch (InterruptedException e) {
2823 updateCpuStatsNow();
2824 } catch (Exception e) {
2825 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2831 Watchdog.getInstance().addMonitor(this);
2832 Watchdog.getInstance().addThread(mHandler);
2835 protected ActivityStackSupervisor createStackSupervisor() {
2836 return new ActivityStackSupervisor(this, mHandler.getLooper());
2839 public void setSystemServiceManager(SystemServiceManager mgr) {
2840 mSystemServiceManager = mgr;
2843 public void setInstaller(Installer installer) {
2844 mInstaller = installer;
2847 private void start() {
2848 removeAllProcessGroups();
2849 mProcessCpuThread.start();
2851 mBatteryStatsService.publish(mContext);
2852 mAppOpsService.publish(mContext);
2853 Slog.d("AppOps", "AppOpsService published");
2854 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2855 // Wait for the synchronized block started in mProcessCpuThread,
2856 // so that any other acccess to mProcessCpuTracker from main thread
2857 // will be blocked during mProcessCpuTracker initialization.
2859 mProcessCpuInitLatch.await();
2860 } catch (InterruptedException e) {
2861 Slog.wtf(TAG, "Interrupted wait during start", e);
2862 Thread.currentThread().interrupt();
2863 throw new IllegalStateException("Interrupted wait during start");
2867 void onUserStoppedLocked(int userId) {
2868 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2871 public void initPowerManagement() {
2872 mStackSupervisor.initPowerManagement();
2873 mBatteryStatsService.initPowerManagement();
2874 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2875 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2876 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2877 mVoiceWakeLock.setReferenceCounted(false);
2880 private ArraySet<String> getBackgroundLaunchBroadcasts() {
2881 if (mBackgroundLaunchBroadcasts == null) {
2882 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2884 return mBackgroundLaunchBroadcasts;
2888 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2889 throws RemoteException {
2890 if (code == SYSPROPS_TRANSACTION) {
2891 // We need to tell all apps about the system property change.
2892 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2893 synchronized(this) {
2894 final int NP = mProcessNames.getMap().size();
2895 for (int ip=0; ip<NP; ip++) {
2896 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2897 final int NA = apps.size();
2898 for (int ia=0; ia<NA; ia++) {
2899 ProcessRecord app = apps.valueAt(ia);
2900 if (app.thread != null) {
2901 procs.add(app.thread.asBinder());
2907 int N = procs.size();
2908 for (int i=0; i<N; i++) {
2909 Parcel data2 = Parcel.obtain();
2911 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2912 Binder.FLAG_ONEWAY);
2913 } catch (RemoteException e) {
2919 return super.onTransact(code, data, reply, flags);
2920 } catch (RuntimeException e) {
2921 // The activity manager only throws security exceptions, so let's
2923 if (!(e instanceof SecurityException)) {
2924 Slog.wtf(TAG, "Activity Manager Crash."
2925 + " UID:" + Binder.getCallingUid()
2926 + " PID:" + Binder.getCallingPid()
2927 + " TRANS:" + code, e);
2933 void updateCpuStats() {
2934 final long now = SystemClock.uptimeMillis();
2935 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2938 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2939 synchronized (mProcessCpuThread) {
2940 mProcessCpuThread.notify();
2945 void updateCpuStatsNow() {
2946 synchronized (mProcessCpuTracker) {
2947 mProcessCpuMutexFree.set(false);
2948 final long now = SystemClock.uptimeMillis();
2949 boolean haveNewCpuStats = false;
2951 if (MONITOR_CPU_USAGE &&
2952 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2953 mLastCpuTime.set(now);
2954 mProcessCpuTracker.update();
2955 if (mProcessCpuTracker.hasGoodLastStats()) {
2956 haveNewCpuStats = true;
2957 //Slog.i(TAG, mProcessCpu.printCurrentState());
2958 //Slog.i(TAG, "Total CPU usage: "
2959 // + mProcessCpu.getTotalCpuPercent() + "%");
2961 // Slog the cpu usage if the property is set.
2962 if ("true".equals(SystemProperties.get("events.cpu"))) {
2963 int user = mProcessCpuTracker.getLastUserTime();
2964 int system = mProcessCpuTracker.getLastSystemTime();
2965 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2966 int irq = mProcessCpuTracker.getLastIrqTime();
2967 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2968 int idle = mProcessCpuTracker.getLastIdleTime();
2970 int total = user + system + iowait + irq + softIrq + idle;
2971 if (total == 0) total = 1;
2973 EventLog.writeEvent(EventLogTags.CPU,
2974 ((user+system+iowait+irq+softIrq) * 100) / total,
2975 (user * 100) / total,
2976 (system * 100) / total,
2977 (iowait * 100) / total,
2978 (irq * 100) / total,
2979 (softIrq * 100) / total);
2984 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2985 synchronized(bstats) {
2986 synchronized(mPidsSelfLocked) {
2987 if (haveNewCpuStats) {
2988 if (bstats.startAddingCpuLocked()) {
2991 final int N = mProcessCpuTracker.countStats();
2992 for (int i=0; i<N; i++) {
2993 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2997 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2998 totalUTime += st.rel_utime;
2999 totalSTime += st.rel_stime;
3001 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3002 if (ps == null || !ps.isActive()) {
3003 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3004 pr.info.uid, pr.processName);
3006 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3007 pr.curCpuTime += st.rel_utime + st.rel_stime;
3009 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3010 if (ps == null || !ps.isActive()) {
3011 st.batteryStats = ps = bstats.getProcessStatsLocked(
3012 bstats.mapUid(st.uid), st.name);
3014 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3017 final int userTime = mProcessCpuTracker.getLastUserTime();
3018 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3019 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3020 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3021 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3022 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3023 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3024 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3029 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3030 mLastWriteTime = now;
3031 mBatteryStatsService.scheduleWriteToDisk();
3038 public void batteryNeedsCpuUpdate() {
3039 updateCpuStatsNow();
3043 public void batteryPowerChanged(boolean onBattery) {
3044 // When plugging in, update the CPU stats first before changing
3046 updateCpuStatsNow();
3047 synchronized (this) {
3048 synchronized(mPidsSelfLocked) {
3049 mOnBattery = DEBUG_POWER ? true : onBattery;
3055 public void batterySendBroadcast(Intent intent) {
3056 synchronized (this) {
3057 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3058 AppOpsManager.OP_NONE, null, false, false,
3059 -1, SYSTEM_UID, UserHandle.USER_ALL);
3064 * Initialize the application bind args. These are passed to each
3065 * process when the bindApplication() IPC is sent to the process. They're
3066 * lazily setup to make sure the services are running when they're asked for.
3068 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3069 // Isolated processes won't get this optimization, so that we don't
3070 // violate the rules about which services they have access to.
3072 if (mIsolatedAppBindArgs == null) {
3073 mIsolatedAppBindArgs = new HashMap<>();
3074 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3076 return mIsolatedAppBindArgs;
3079 if (mAppBindArgs == null) {
3080 mAppBindArgs = new HashMap<>();
3082 // Setup the application init args
3083 mAppBindArgs.put("package", ServiceManager.getService("package"));
3084 mAppBindArgs.put("window", ServiceManager.getService("window"));
3085 mAppBindArgs.put(Context.ALARM_SERVICE,
3086 ServiceManager.getService(Context.ALARM_SERVICE));
3088 return mAppBindArgs;
3092 * Update AMS states when an activity is resumed. This should only be called by
3093 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3095 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3096 final TaskRecord task = r.getTask();
3097 if (task.isApplicationTask()) {
3098 if (mCurAppTimeTracker != r.appTimeTracker) {
3099 // We are switching app tracking. Complete the current one.
3100 if (mCurAppTimeTracker != null) {
3101 mCurAppTimeTracker.stop();
3102 mHandler.obtainMessage(
3103 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3104 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3105 mCurAppTimeTracker = null;
3107 if (r.appTimeTracker != null) {
3108 mCurAppTimeTracker = r.appTimeTracker;
3109 startTimeTrackingFocusedActivityLocked();
3112 startTimeTrackingFocusedActivityLocked();
3115 r.appTimeTracker = null;
3117 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3118 // TODO: Probably not, because we don't want to resume voice on switching
3119 // back to this activity
3120 if (task.voiceInteractor != null) {
3121 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3123 finishRunningVoiceLocked();
3125 if (mLastResumedActivity != null) {
3126 final IVoiceInteractionSession session;
3128 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3129 if (lastResumedActivityTask != null
3130 && lastResumedActivityTask.voiceSession != null) {
3131 session = lastResumedActivityTask.voiceSession;
3133 session = mLastResumedActivity.voiceSession;
3136 if (session != null) {
3137 // We had been in a voice interaction session, but now focused has
3138 // move to something different. Just finish the session, we can't
3139 // return to it and retain the proper state and synchronization with
3140 // the voice interaction service.
3141 finishVoiceTask(session);
3146 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3147 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3148 mHandler.obtainMessage(
3149 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3151 mLastResumedActivity = r;
3153 mWindowManager.setFocusedApp(r.appToken, true);
3155 applyUpdateLockStateLocked(r);
3156 applyUpdateVrModeLocked(r);
3158 EventLogTags.writeAmSetResumedActivity(
3159 r == null ? -1 : r.userId,
3160 r == null ? "NULL" : r.shortComponentName,
3165 public void setFocusedStack(int stackId) {
3166 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3167 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3168 final long callingId = Binder.clearCallingIdentity();
3170 synchronized (this) {
3171 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3172 if (stack == null) {
3175 final ActivityRecord r = stack.topRunningActivityLocked();
3176 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3177 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3181 Binder.restoreCallingIdentity(callingId);
3186 public void setFocusedTask(int taskId) {
3187 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3188 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3189 final long callingId = Binder.clearCallingIdentity();
3191 synchronized (this) {
3192 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3196 final ActivityRecord r = task.topRunningActivityLocked();
3197 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3198 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3202 Binder.restoreCallingIdentity(callingId);
3206 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3208 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3209 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3210 mTaskChangeNotificationController.registerTaskStackListener(listener);
3214 * Unregister a task stack listener so that it stops receiving callbacks.
3217 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3218 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3219 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3223 public void notifyActivityDrawn(IBinder token) {
3224 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3225 synchronized (this) {
3226 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3228 r.getStack().notifyActivityDrawnLocked(r);
3233 final void applyUpdateLockStateLocked(ActivityRecord r) {
3234 // Modifications to the UpdateLock state are done on our handler, outside
3235 // the activity manager's locks. The new state is determined based on the
3236 // state *now* of the relevant activity record. The object is passed to
3237 // the handler solely for logging detail, not to be consulted/modified.
3238 final boolean nextState = r != null && r.immersive;
3239 mHandler.sendMessage(
3240 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3243 final void applyUpdateVrModeLocked(ActivityRecord r) {
3244 mHandler.sendMessage(
3245 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3248 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3249 mHandler.sendMessage(
3250 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3253 private void notifyVrManagerOfSleepState(boolean isSleeping) {
3254 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3255 if (vrService == null) {
3258 vrService.onSleepStateChanged(isSleeping);
3261 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3262 Message msg = Message.obtain();
3263 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3264 msg.obj = r.getTask().askedCompatMode ? null : r;
3265 mUiHandler.sendMessage(msg);
3268 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3269 final Configuration globalConfig = getGlobalConfiguration();
3270 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3271 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3272 final Message msg = Message.obtain();
3273 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3275 mUiHandler.sendMessage(msg);
3279 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3280 String what, Object obj, ProcessRecord srcApp) {
3281 app.lastActivityTime = now;
3283 if (app.activities.size() > 0) {
3284 // Don't want to touch dependent processes that are hosting activities.
3288 int lrui = mLruProcesses.lastIndexOf(app);
3290 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3291 + what + " " + obj + " from " + srcApp);
3295 if (lrui >= index) {
3296 // Don't want to cause this to move dependent processes *back* in the
3297 // list as if they were less frequently used.
3301 if (lrui >= mLruProcessActivityStart) {
3302 // Don't want to touch dependent processes that are hosting activities.
3306 mLruProcesses.remove(lrui);
3310 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3311 + " in LRU list: " + app);
3312 mLruProcesses.add(index, app);
3316 static void killProcessGroup(int uid, int pid) {
3317 if (sKillHandler != null) {
3318 sKillHandler.sendMessage(
3319 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3321 Slog.w(TAG, "Asked to kill process group before system bringup!");
3322 Process.killProcessGroup(uid, pid);
3326 final void removeLruProcessLocked(ProcessRecord app) {
3327 int lrui = mLruProcesses.lastIndexOf(app);
3330 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3331 killProcessQuiet(app.pid);
3332 killProcessGroup(app.uid, app.pid);
3334 if (lrui <= mLruProcessActivityStart) {
3335 mLruProcessActivityStart--;
3337 if (lrui <= mLruProcessServiceStart) {
3338 mLruProcessServiceStart--;
3340 mLruProcesses.remove(lrui);
3344 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3345 ProcessRecord client) {
3346 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3347 || app.treatLikeActivity;
3348 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3349 if (!activityChange && hasActivity) {
3350 // The process has activities, so we are only allowing activity-based adjustments
3351 // to move it. It should be kept in the front of the list with other
3352 // processes that have activities, and we don't want those to change their
3353 // order except due to activity operations.
3358 final long now = SystemClock.uptimeMillis();
3359 app.lastActivityTime = now;
3361 // First a quick reject: if the app is already at the position we will
3362 // put it, then there is nothing to do.
3364 final int N = mLruProcesses.size();
3365 if (N > 0 && mLruProcesses.get(N-1) == app) {
3366 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3370 if (mLruProcessServiceStart > 0
3371 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3372 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3377 int lrui = mLruProcesses.lastIndexOf(app);
3379 if (app.persistent && lrui >= 0) {
3380 // We don't care about the position of persistent processes, as long as
3381 // they are in the list.
3382 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3386 /* In progress: compute new position first, so we can avoid doing work
3387 if the process is not actually going to move. Not yet working.
3390 boolean inActivity = false, inService = false;
3392 // Process has activities, put it at the very tipsy-top.
3393 addIndex = mLruProcesses.size();
3394 nextIndex = mLruProcessServiceStart;
3396 } else if (hasService) {
3397 // Process has services, put it at the top of the service list.
3398 addIndex = mLruProcessActivityStart;
3399 nextIndex = mLruProcessServiceStart;
3403 // Process not otherwise of interest, it goes to the top of the non-service area.
3404 addIndex = mLruProcessServiceStart;
3405 if (client != null) {
3406 int clientIndex = mLruProcesses.lastIndexOf(client);
3407 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3409 if (clientIndex >= 0 && addIndex > clientIndex) {
3410 addIndex = clientIndex;
3413 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3416 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3417 + mLruProcessActivityStart + "): " + app);
3421 if (lrui < mLruProcessActivityStart) {
3422 mLruProcessActivityStart--;
3424 if (lrui < mLruProcessServiceStart) {
3425 mLruProcessServiceStart--;
3428 if (addIndex > lrui) {
3431 if (nextIndex > lrui) {
3435 mLruProcesses.remove(lrui);
3439 mLruProcesses.add(addIndex, app);
3441 mLruProcessActivityStart++;
3444 mLruProcessActivityStart++;
3450 final int N = mLruProcesses.size();
3451 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3452 // Process doesn't have activities, but has clients with
3453 // activities... move it up, but one below the top (the top
3454 // should always have a real activity).
3455 if (DEBUG_LRU) Slog.d(TAG_LRU,
3456 "Adding to second-top of LRU activity list: " + app);
3457 mLruProcesses.add(N - 1, app);
3458 // To keep it from spamming the LRU list (by making a bunch of clients),
3459 // we will push down any other entries owned by the app.
3460 final int uid = app.info.uid;
3461 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3462 ProcessRecord subProc = mLruProcesses.get(i);
3463 if (subProc.info.uid == uid) {
3464 // We want to push this one down the list. If the process after
3465 // it is for the same uid, however, don't do so, because we don't
3466 // want them internally to be re-ordered.
3467 if (mLruProcesses.get(i - 1).info.uid != uid) {
3468 if (DEBUG_LRU) Slog.d(TAG_LRU,
3469 "Pushing uid " + uid + " swapping at " + i + ": "
3470 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3471 ProcessRecord tmp = mLruProcesses.get(i);
3472 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3473 mLruProcesses.set(i - 1, tmp);
3477 // A gap, we can stop here.
3482 // Process has activities, put it at the very tipsy-top.
3483 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3484 mLruProcesses.add(app);
3486 nextIndex = mLruProcessServiceStart;
3487 } else if (hasService) {
3488 // Process has services, put it at the top of the service list.
3489 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3490 mLruProcesses.add(mLruProcessActivityStart, app);
3491 nextIndex = mLruProcessServiceStart;
3492 mLruProcessActivityStart++;
3494 // Process not otherwise of interest, it goes to the top of the non-service area.
3495 int index = mLruProcessServiceStart;
3496 if (client != null) {
3497 // If there is a client, don't allow the process to be moved up higher
3498 // in the list than that client.
3499 int clientIndex = mLruProcesses.lastIndexOf(client);
3500 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3501 + " when updating " + app);
3502 if (clientIndex <= lrui) {
3503 // Don't allow the client index restriction to push it down farther in the
3504 // list than it already is.
3507 if (clientIndex >= 0 && index > clientIndex) {
3508 index = clientIndex;
3511 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3512 mLruProcesses.add(index, app);
3513 nextIndex = index-1;
3514 mLruProcessActivityStart++;
3515 mLruProcessServiceStart++;
3518 // If the app is currently using a content provider or service,
3519 // bump those processes as well.
3520 for (int j=app.connections.size()-1; j>=0; j--) {
3521 ConnectionRecord cr = app.connections.valueAt(j);
3522 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3523 && cr.binding.service.app != null
3524 && cr.binding.service.app.lruSeq != mLruSeq
3525 && !cr.binding.service.app.persistent) {
3526 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3527 "service connection", cr, app);
3530 for (int j=app.conProviders.size()-1; j>=0; j--) {
3531 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3532 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3533 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3534 "provider reference", cpr, app);
3539 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3540 if (uid == SYSTEM_UID) {
3541 // The system gets to run in any process. If there are multiple
3542 // processes with the same uid, just pick the first (this
3543 // should never happen).
3544 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3545 if (procs == null) return null;
3546 final int procCount = procs.size();
3547 for (int i = 0; i < procCount; i++) {
3548 final int procUid = procs.keyAt(i);
3549 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3550 // Don't use an app process or different user process for system component.
3553 return procs.valueAt(i);
3556 ProcessRecord proc = mProcessNames.get(processName, uid);
3557 if (false && proc != null && !keepIfLarge
3558 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3559 && proc.lastCachedPss >= 4000) {
3560 // Turn this condition on to cause killing to happen regularly, for testing.
3561 if (proc.baseProcessTracker != null) {
3562 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3564 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3565 } else if (proc != null && !keepIfLarge
3566 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3567 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3568 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3569 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3570 if (proc.baseProcessTracker != null) {
3571 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3573 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3579 void notifyPackageUse(String packageName, int reason) {
3580 IPackageManager pm = AppGlobals.getPackageManager();
3582 pm.notifyPackageUse(packageName, reason);
3583 } catch (RemoteException e) {
3587 boolean isNextTransitionForward() {
3588 int transit = mWindowManager.getPendingAppTransition();
3589 return transit == TRANSIT_ACTIVITY_OPEN
3590 || transit == TRANSIT_TASK_OPEN
3591 || transit == TRANSIT_TASK_TO_FRONT;
3594 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3595 String processName, String abiOverride, int uid, Runnable crashHandler) {
3596 synchronized(this) {
3597 ApplicationInfo info = new ApplicationInfo();
3598 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3599 // For isolated processes, the former contains the parent's uid and the latter the
3600 // actual uid of the isolated process.
3601 // In the special case introduced by this method (which is, starting an isolated
3602 // process directly from the SystemServer without an actual parent app process) the
3603 // closest thing to a parent's uid is SYSTEM_UID.
3604 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3605 // the |isolated| logic in the ProcessRecord constructor.
3606 info.uid = SYSTEM_UID;
3607 info.processName = processName;
3608 info.className = entryPoint;
3609 info.packageName = "android";
3610 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3611 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3612 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3613 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3614 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3616 return proc != null ? proc.pid : 0;
3620 final ProcessRecord startProcessLocked(String processName,
3621 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3622 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3623 boolean isolated, boolean keepIfLarge) {
3624 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3625 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3626 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3627 null /* crashHandler */);
3630 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3631 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3632 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3633 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3634 long startTime = SystemClock.elapsedRealtime();
3637 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3638 checkTime(startTime, "startProcess: after getProcessRecord");
3640 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3641 // If we are in the background, then check to see if this process
3642 // is bad. If so, we will just silently fail.
3643 if (mAppErrors.isBadProcessLocked(info)) {
3644 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3645 + "/" + info.processName);
3649 // When the user is explicitly starting a process, then clear its
3650 // crash count so that we won't make it bad until they see at
3651 // least one crash dialog again, and make the process good again
3652 // if it had been bad.
3653 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3654 + "/" + info.processName);
3655 mAppErrors.resetProcessCrashTimeLocked(info);
3656 if (mAppErrors.isBadProcessLocked(info)) {
3657 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3658 UserHandle.getUserId(info.uid), info.uid,
3660 mAppErrors.clearBadProcessLocked(info);
3667 // If this is an isolated process, it can't re-use an existing process.
3671 // We don't have to do anything more if:
3672 // (1) There is an existing application record; and
3673 // (2) The caller doesn't think it is dead, OR there is no thread
3674 // object attached to it so we know it couldn't have crashed; and
3675 // (3) There is a pid assigned to it, so it is either starting or
3677 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3678 + " app=" + app + " knownToBeDead=" + knownToBeDead
3679 + " thread=" + (app != null ? app.thread : null)
3680 + " pid=" + (app != null ? app.pid : -1));
3681 if (app != null && app.pid > 0) {
3682 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3683 // We already have the app running, or are waiting for it to
3684 // come up (we have a pid but not yet its thread), so keep it.
3685 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3686 // If this is a new package in the process, add the package to the list
3687 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3688 checkTime(startTime, "startProcess: done, added package to proc");
3692 // An application record is attached to a previous process,
3694 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3695 checkTime(startTime, "startProcess: bad proc running, killing");
3696 killProcessGroup(app.uid, app.pid);
3697 handleAppDiedLocked(app, true, true);
3698 checkTime(startTime, "startProcess: done killing old proc");
3701 String hostingNameStr = hostingName != null
3702 ? hostingName.flattenToShortString() : null;
3705 checkTime(startTime, "startProcess: creating new process record");
3706 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3708 Slog.w(TAG, "Failed making new process record for "
3709 + processName + "/" + info.uid + " isolated=" + isolated);
3712 app.crashHandler = crashHandler;
3713 checkTime(startTime, "startProcess: done creating new process record");
3715 // If this is a new package in the process, add the package to the list
3716 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3717 checkTime(startTime, "startProcess: added package to existing proc");
3720 // If the system is not ready yet, then hold off on starting this
3721 // process until it is.
3722 if (!mProcessesReady
3723 && !isAllowedWhileBooting(info)
3724 && !allowWhileBooting) {
3725 if (!mProcessesOnHold.contains(app)) {
3726 mProcessesOnHold.add(app);
3728 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3729 "System not ready, putting on hold: " + app);
3730 checkTime(startTime, "startProcess: returning with proc on hold");
3734 checkTime(startTime, "startProcess: stepping in to startProcess");
3736 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3737 checkTime(startTime, "startProcess: done starting proc!");
3738 return (app.pid != 0) ? app : null;
3741 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3742 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3745 private final void startProcessLocked(ProcessRecord app,
3746 String hostingType, String hostingNameStr) {
3747 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3748 null /* entryPoint */, null /* entryPointArgs */);
3751 private final void startProcessLocked(ProcessRecord app, String hostingType,
3752 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3753 long startTime = SystemClock.elapsedRealtime();
3754 if (app.pid > 0 && app.pid != MY_PID) {
3755 checkTime(startTime, "startProcess: removing from pids map");
3756 synchronized (mPidsSelfLocked) {
3757 mPidsSelfLocked.remove(app.pid);
3758 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3760 checkTime(startTime, "startProcess: done removing from pids map");
3764 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3765 "startProcessLocked removing on hold: " + app);
3766 mProcessesOnHold.remove(app);
3768 checkTime(startTime, "startProcess: starting to update cpu stats");
3770 checkTime(startTime, "startProcess: done updating cpu stats");
3774 final int userId = UserHandle.getUserId(app.uid);
3775 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3776 } catch (RemoteException e) {
3777 throw e.rethrowAsRuntimeException();
3782 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3783 if (!app.isolated) {
3784 int[] permGids = null;
3786 checkTime(startTime, "startProcess: getting gids from package manager");
3787 final IPackageManager pm = AppGlobals.getPackageManager();
3788 permGids = pm.getPackageGids(app.info.packageName,
3789 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3790 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3791 StorageManagerInternal.class);
3792 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3793 app.info.packageName);
3794 } catch (RemoteException e) {
3795 throw e.rethrowAsRuntimeException();
3799 * Add shared application and profile GIDs so applications can share some
3800 * resources like shared libraries and access user-wide resources
3802 if (ArrayUtils.isEmpty(permGids)) {
3805 gids = new int[permGids.length + 3];
3806 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3808 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3809 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3810 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3812 checkTime(startTime, "startProcess: building args");
3813 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3814 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3815 && mTopComponent != null
3816 && app.processName.equals(mTopComponent.getPackageName())) {
3819 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3820 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3825 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3826 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3827 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3828 // Also turn on CheckJNI for debuggable apps. It's quite
3829 // awkward to turn on otherwise.
3830 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3832 // Run the app in safe mode if its manifest requests so or the
3833 // system is booted in safe mode.
3834 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3835 mSafeMode == true) {
3836 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3838 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3839 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3841 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3842 if ("true".equals(genDebugInfoProperty)) {
3843 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3845 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3846 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3848 if ("1".equals(SystemProperties.get("debug.assert"))) {
3849 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3851 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3852 // Enable all debug flags required by the native debugger.
3853 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3854 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3855 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3856 mNativeDebuggingApp = null;
3859 String invokeWith = null;
3860 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3861 // Debuggable apps may include a wrapper script with their library directory.
3862 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3863 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3865 if (new File(wrapperFileName).exists()) {
3866 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3869 StrictMode.setThreadPolicy(oldPolicy);
3873 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3874 if (requiredAbi == null) {
3875 requiredAbi = Build.SUPPORTED_ABIS[0];
3878 String instructionSet = null;
3879 if (app.info.primaryCpuAbi != null) {
3880 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3884 app.requiredAbi = requiredAbi;
3885 app.instructionSet = instructionSet;
3887 // the per-user SELinux context must be set
3888 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3889 Slog.wtf(TAG, "SELinux tag not defined",
3890 new IllegalStateException("SELinux tag not defined for "
3891 + app.info.packageName + " (uid " + app.uid + ")"));
3893 final String seInfo = app.info.seInfo
3894 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3895 // Start the process. It will either succeed and return a result containing
3896 // the PID of the new process, or else throw a RuntimeException.
3897 boolean isActivityProcess = (entryPoint == null);
3898 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3899 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3901 checkTime(startTime, "startProcess: asking zygote to start proc");
3902 ProcessStartResult startResult;
3903 if (hostingType.equals("webview_service")) {
3904 startResult = startWebView(entryPoint,
3905 app.processName, uid, uid, gids, debugFlags, mountExternal,
3906 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3907 app.info.dataDir, null, entryPointArgs);
3909 startResult = Process.start(entryPoint,
3910 app.processName, uid, uid, gids, debugFlags, mountExternal,
3911 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3912 app.info.dataDir, invokeWith, entryPointArgs);
3914 checkTime(startTime, "startProcess: returned from zygote!");
3915 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3917 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3918 checkTime(startTime, "startProcess: done updating battery stats");
3920 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3921 UserHandle.getUserId(uid), startResult.pid, uid,
3922 app.processName, hostingType,
3923 hostingNameStr != null ? hostingNameStr : "");
3926 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3927 seInfo, app.info.sourceDir, startResult.pid);
3928 } catch (RemoteException ex) {
3932 if (app.persistent) {
3933 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3936 checkTime(startTime, "startProcess: building log message");
3937 StringBuilder buf = mStringBuilder;
3939 buf.append("Start proc ");
3940 buf.append(startResult.pid);
3942 buf.append(app.processName);
3944 UserHandle.formatUid(buf, uid);
3945 if (!isActivityProcess) {
3947 buf.append(entryPoint);
3950 buf.append(" for ");
3951 buf.append(hostingType);
3952 if (hostingNameStr != null) {
3954 buf.append(hostingNameStr);
3956 Slog.i(TAG, buf.toString());
3957 app.setPid(startResult.pid);
3958 app.usingWrapper = startResult.usingWrapper;
3959 app.removed = false;
3961 app.killedByAm = false;
3962 checkTime(startTime, "startProcess: starting to update pids map");
3963 ProcessRecord oldApp;
3964 synchronized (mPidsSelfLocked) {
3965 oldApp = mPidsSelfLocked.get(startResult.pid);
3967 // If there is already an app occupying that pid that hasn't been cleaned up
3968 if (oldApp != null && !app.isolated) {
3969 // Clean up anything relating to this pid first
3970 Slog.w(TAG, "Reusing pid " + startResult.pid
3971 + " while app is still mapped to it");
3972 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3973 true /*replacingPid*/);
3975 synchronized (mPidsSelfLocked) {
3976 this.mPidsSelfLocked.put(startResult.pid, app);
3977 if (isActivityProcess) {
3978 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3980 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3981 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3984 checkTime(startTime, "startProcess: done updating pids map");
3985 } catch (RuntimeException e) {
3986 Slog.e(TAG, "Failure starting process " + app.processName, e);
3988 // Something went very wrong while trying to start this process; one
3989 // common case is when the package is frozen due to an active
3990 // upgrade. To recover, clean up any active bookkeeping related to
3991 // starting this process. (We already invoked this method once when
3992 // the package was initially frozen through KILL_APPLICATION_MSG, so
3993 // it doesn't hurt to use it again.)
3994 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3995 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3999 void updateUsageStats(ActivityRecord component, boolean resumed) {
4000 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4001 "updateUsageStats: comp=" + component + "res=" + resumed);
4002 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4004 if (mUsageStatsService != null) {
4005 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4006 UsageEvents.Event.MOVE_TO_FOREGROUND);
4008 synchronized (stats) {
4009 stats.noteActivityResumedLocked(component.app.uid);
4012 if (mUsageStatsService != null) {
4013 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4014 UsageEvents.Event.MOVE_TO_BACKGROUND);
4016 synchronized (stats) {
4017 stats.noteActivityPausedLocked(component.app.uid);
4022 Intent getHomeIntent() {
4023 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4024 intent.setComponent(mTopComponent);
4025 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4026 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4027 intent.addCategory(Intent.CATEGORY_HOME);
4032 boolean startHomeActivityLocked(int userId, String reason) {
4033 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4034 && mTopAction == null) {
4035 // We are running in factory test mode, but unable to find
4036 // the factory test app, so just sit around displaying the
4037 // error message and don't try to start anything.
4040 Intent intent = getHomeIntent();
4041 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4042 if (aInfo != null) {
4043 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4044 // Don't do this if the home app is currently being
4046 aInfo = new ActivityInfo(aInfo);
4047 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4048 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4049 aInfo.applicationInfo.uid, true);
4050 if (app == null || app.instr == null) {
4051 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4052 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4053 // For ANR debugging to verify if the user activity is the one that actually
4055 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4056 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4059 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4065 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4066 ActivityInfo ai = null;
4067 ComponentName comp = intent.getComponent();
4071 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4073 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4075 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4079 ai = info.activityInfo;
4082 } catch (RemoteException e) {
4090 * Starts the "new version setup screen" if appropriate.
4092 void startSetupActivityLocked() {
4093 // Only do this once per boot.
4094 if (mCheckedForSetup) {
4098 // We will show this screen if the current one is a different
4099 // version than the last one shown, and we are not running in
4100 // low-level factory test mode.
4101 final ContentResolver resolver = mContext.getContentResolver();
4102 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4103 Settings.Global.getInt(resolver,
4104 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4105 mCheckedForSetup = true;
4107 // See if we should be showing the platform update setup UI.
4108 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4109 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4110 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4111 if (!ris.isEmpty()) {
4112 final ResolveInfo ri = ris.get(0);
4113 String vers = ri.activityInfo.metaData != null
4114 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4116 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4117 vers = ri.activityInfo.applicationInfo.metaData.getString(
4118 Intent.METADATA_SETUP_VERSION);
4120 String lastVers = Settings.Secure.getString(
4121 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4122 if (vers != null && !vers.equals(lastVers)) {
4123 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4124 intent.setComponent(new ComponentName(
4125 ri.activityInfo.packageName, ri.activityInfo.name));
4126 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4127 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4128 null, 0, 0, 0, null, false, false, null, null, null,
4129 "startSetupActivity");
4135 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4136 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4139 void enforceNotIsolatedCaller(String caller) {
4140 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4141 throw new SecurityException("Isolated process not allowed to call " + caller);
4145 void enforceShellRestriction(String restriction, int userHandle) {
4146 if (Binder.getCallingUid() == SHELL_UID) {
4147 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4148 throw new SecurityException("Shell does not have permission to access user "
4155 public int getFrontActivityScreenCompatMode() {
4156 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4157 synchronized (this) {
4158 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4163 public void setFrontActivityScreenCompatMode(int mode) {
4164 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4165 "setFrontActivityScreenCompatMode");
4166 synchronized (this) {
4167 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4172 public int getPackageScreenCompatMode(String packageName) {
4173 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4174 synchronized (this) {
4175 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4180 public void setPackageScreenCompatMode(String packageName, int mode) {
4181 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4182 "setPackageScreenCompatMode");
4183 synchronized (this) {
4184 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4189 public boolean getPackageAskScreenCompat(String packageName) {
4190 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4191 synchronized (this) {
4192 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4197 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4198 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4199 "setPackageAskScreenCompat");
4200 synchronized (this) {
4201 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4205 private boolean hasUsageStatsPermission(String callingPackage) {
4206 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4207 Binder.getCallingUid(), callingPackage);
4208 if (mode == AppOpsManager.MODE_DEFAULT) {
4209 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4210 == PackageManager.PERMISSION_GRANTED;
4212 return mode == AppOpsManager.MODE_ALLOWED;
4216 public int getPackageProcessState(String packageName, String callingPackage) {
4217 if (!hasUsageStatsPermission(callingPackage)) {
4218 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4219 "getPackageProcessState");
4222 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4223 synchronized (this) {
4224 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4225 final ProcessRecord proc = mLruProcesses.get(i);
4226 if (procState > proc.setProcState) {
4227 if (proc.pkgList.containsKey(packageName) ||
4228 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4229 procState = proc.setProcState;
4238 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4239 throws RemoteException {
4240 synchronized (this) {
4241 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4243 throw new IllegalArgumentException("Unknown process: " + process);
4245 if (app.thread == null) {
4246 throw new IllegalArgumentException("Process has no app thread");
4248 if (app.trimMemoryLevel >= level) {
4249 throw new IllegalArgumentException(
4250 "Unable to set a higher trim level than current level");
4252 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4253 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4254 throw new IllegalArgumentException("Unable to set a background trim level "
4255 + "on a foreground process");
4257 app.thread.scheduleTrimMemory(level);
4258 app.trimMemoryLevel = level;
4263 private void dispatchProcessesChanged() {
4265 synchronized (this) {
4266 N = mPendingProcessChanges.size();
4267 if (mActiveProcessChanges.length < N) {
4268 mActiveProcessChanges = new ProcessChangeItem[N];
4270 mPendingProcessChanges.toArray(mActiveProcessChanges);
4271 mPendingProcessChanges.clear();
4272 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4273 "*** Delivering " + N + " process changes");
4276 int i = mProcessObservers.beginBroadcast();
4279 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4280 if (observer != null) {
4282 for (int j=0; j<N; j++) {
4283 ProcessChangeItem item = mActiveProcessChanges[j];
4284 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4285 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4286 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4287 + item.uid + ": " + item.foregroundActivities);
4288 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4289 item.foregroundActivities);
4292 } catch (RemoteException e) {
4296 mProcessObservers.finishBroadcast();
4298 synchronized (this) {
4299 for (int j=0; j<N; j++) {
4300 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4305 private void dispatchProcessDied(int pid, int uid) {
4306 int i = mProcessObservers.beginBroadcast();
4309 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4310 if (observer != null) {
4312 observer.onProcessDied(pid, uid);
4313 } catch (RemoteException e) {
4317 mProcessObservers.finishBroadcast();
4321 void dispatchUidsChanged() {
4323 synchronized (this) {
4324 N = mPendingUidChanges.size();
4325 if (mActiveUidChanges.length < N) {
4326 mActiveUidChanges = new UidRecord.ChangeItem[N];
4328 for (int i=0; i<N; i++) {
4329 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4330 mActiveUidChanges[i] = change;
4331 if (change.uidRecord != null) {
4332 change.uidRecord.pendingChange = null;
4333 change.uidRecord = null;
4336 mPendingUidChanges.clear();
4337 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4338 "*** Delivering " + N + " uid changes");
4341 int i = mUidObservers.beginBroadcast();
4344 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4345 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4347 mUidObservers.finishBroadcast();
4349 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4350 for (int j = 0; j < N; ++j) {
4351 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4352 if (item.change == UidRecord.CHANGE_GONE
4353 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4354 mValidateUids.remove(item.uid);
4356 UidRecord validateUid = mValidateUids.get(item.uid);
4357 if (validateUid == null) {
4358 validateUid = new UidRecord(item.uid);
4359 mValidateUids.put(item.uid, validateUid);
4361 if (item.change == UidRecord.CHANGE_IDLE) {
4362 validateUid.idle = true;
4363 } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4364 validateUid.idle = false;
4366 validateUid.curProcState = validateUid.setProcState = item.processState;
4367 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4372 synchronized (this) {
4373 for (int j = 0; j < N; j++) {
4374 mAvailUidChanges.add(mActiveUidChanges[j]);
4379 private void dispatchUidsChangedForObserver(IUidObserver observer,
4380 UidObserverRegistration reg, int changesSize) {
4381 if (observer == null) {
4385 for (int j = 0; j < changesSize; j++) {
4386 UidRecord.ChangeItem item = mActiveUidChanges[j];
4387 final int change = item.change;
4388 if (change == UidRecord.CHANGE_IDLE
4389 || change == UidRecord.CHANGE_GONE_IDLE) {
4390 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4391 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4392 "UID idle uid=" + item.uid);
4393 observer.onUidIdle(item.uid, item.ephemeral);
4395 } else if (change == UidRecord.CHANGE_ACTIVE) {
4396 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4397 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4398 "UID active uid=" + item.uid);
4399 observer.onUidActive(item.uid);
4402 if (change == UidRecord.CHANGE_GONE
4403 || change == UidRecord.CHANGE_GONE_IDLE) {
4404 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4405 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4406 "UID gone uid=" + item.uid);
4407 observer.onUidGone(item.uid, item.ephemeral);
4409 if (reg.lastProcStates != null) {
4410 reg.lastProcStates.delete(item.uid);
4413 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4414 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4415 "UID CHANGED uid=" + item.uid
4416 + ": " + item.processState);
4417 boolean doReport = true;
4418 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4419 final int lastState = reg.lastProcStates.get(item.uid,
4420 ActivityManager.PROCESS_STATE_UNKNOWN);
4421 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4422 final boolean lastAboveCut = lastState <= reg.cutpoint;
4423 final boolean newAboveCut = item.processState <= reg.cutpoint;
4424 doReport = lastAboveCut != newAboveCut;
4426 doReport = item.processState
4427 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4431 if (reg.lastProcStates != null) {
4432 reg.lastProcStates.put(item.uid, item.processState);
4434 observer.onUidStateChanged(item.uid, item.processState,
4440 } catch (RemoteException e) {
4445 public final int startActivity(IApplicationThread caller, String callingPackage,
4446 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4447 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4448 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4449 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4450 UserHandle.getCallingUserId());
4453 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4454 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4455 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4456 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4457 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4459 // TODO: Switch to user app stacks here.
4460 String mimeType = intent.getType();
4461 final Uri data = intent.getData();
4462 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4463 mimeType = getProviderMimeType(data, userId);
4465 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4467 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4468 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
4469 null, null, 0, 0, null, null, null, null, false, userId, container, null,
4474 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4475 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4476 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4477 enforceNotIsolatedCaller("startActivity");
4478 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4479 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4480 // TODO: Switch to user app stacks here.
4481 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4482 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4483 profilerInfo, null, null, bOptions, false, userId, null, null,
4484 "startActivityAsUser");
4488 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4489 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4490 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4493 // This is very dangerous -- it allows you to perform a start activity (including
4494 // permission grants) as any app that may launch one of your own activities. So
4495 // we will only allow this to be done from activities that are part of the core framework,
4496 // and then only when they are running as the system.
4497 final ActivityRecord sourceRecord;
4498 final int targetUid;
4499 final String targetPackage;
4500 synchronized (this) {
4501 if (resultTo == null) {
4502 throw new SecurityException("Must be called from an activity");
4504 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4505 if (sourceRecord == null) {
4506 throw new SecurityException("Called with bad activity token: " + resultTo);
4508 if (!sourceRecord.info.packageName.equals("android")) {
4509 throw new SecurityException(
4510 "Must be called from an activity that is declared in the android package");
4512 if (sourceRecord.app == null) {
4513 throw new SecurityException("Called without a process attached to activity");
4515 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4516 // This is still okay, as long as this activity is running under the
4517 // uid of the original calling activity.
4518 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4519 throw new SecurityException(
4520 "Calling activity in uid " + sourceRecord.app.uid
4521 + " must be system uid or original calling uid "
4522 + sourceRecord.launchedFromUid);
4525 if (ignoreTargetSecurity) {
4526 if (intent.getComponent() == null) {
4527 throw new SecurityException(
4528 "Component must be specified with ignoreTargetSecurity");
4530 if (intent.getSelector() != null) {
4531 throw new SecurityException(
4532 "Selector not allowed with ignoreTargetSecurity");
4535 targetUid = sourceRecord.launchedFromUid;
4536 targetPackage = sourceRecord.launchedFromPackage;
4539 if (userId == UserHandle.USER_NULL) {
4540 userId = UserHandle.getUserId(sourceRecord.app.uid);
4543 // TODO: Switch to user app stacks here.
4545 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4546 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4547 null, null, bOptions, ignoreTargetSecurity, userId, null, null,
4548 "startActivityAsCaller");
4550 } catch (SecurityException e) {
4551 // XXX need to figure out how to propagate to original app.
4552 // A SecurityException here is generally actually a fault of the original
4553 // calling activity (such as a fairly granting permissions), so propagate it
4556 StringBuilder msg = new StringBuilder();
4557 msg.append("While launching");
4558 msg.append(intent.toString());
4560 msg.append(e.getMessage());
4567 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4568 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4569 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4570 enforceNotIsolatedCaller("startActivityAndWait");
4571 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4572 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4573 WaitResult res = new WaitResult();
4574 // TODO: Switch to user app stacks here.
4575 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4576 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4577 bOptions, false, userId, null, null, "startActivityAndWait");
4582 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4583 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4584 int startFlags, Configuration config, Bundle bOptions, int userId) {
4585 enforceNotIsolatedCaller("startActivityWithConfig");
4586 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4587 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4588 // TODO: Switch to user app stacks here.
4589 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4590 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4591 null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
4596 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4597 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4598 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4599 throws TransactionTooLargeException {
4600 enforceNotIsolatedCaller("startActivityIntentSender");
4601 // Refuse possible leaked file descriptors
4602 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4603 throw new IllegalArgumentException("File descriptors passed in Intent");
4606 if (!(target instanceof PendingIntentRecord)) {
4607 throw new IllegalArgumentException("Bad PendingIntent object");
4610 PendingIntentRecord pir = (PendingIntentRecord)target;
4612 synchronized (this) {
4613 // If this is coming from the currently resumed activity, it is
4614 // effectively saying that app switches are allowed at this point.
4615 final ActivityStack stack = getFocusedStack();
4616 if (stack.mResumedActivity != null &&
4617 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4618 mAppSwitchesAllowedTime = 0;
4621 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4622 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4627 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4628 Intent intent, String resolvedType, IVoiceInteractionSession session,
4629 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4630 Bundle bOptions, int userId) {
4631 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4632 != PackageManager.PERMISSION_GRANTED) {
4633 String msg = "Permission Denial: startVoiceActivity() from pid="
4634 + Binder.getCallingPid()
4635 + ", uid=" + Binder.getCallingUid()
4636 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4638 throw new SecurityException(msg);
4640 if (session == null || interactor == null) {
4641 throw new NullPointerException("null session or interactor");
4643 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4644 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4645 // TODO: Switch to user app stacks here.
4646 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4647 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4648 null, bOptions, false, userId, null, null, "startVoiceActivity");
4652 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4653 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4654 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4655 != PackageManager.PERMISSION_GRANTED) {
4656 final String msg = "Permission Denial: startAssistantActivity() from pid="
4657 + Binder.getCallingPid()
4658 + ", uid=" + Binder.getCallingUid()
4659 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4661 throw new SecurityException(msg);
4663 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4664 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4665 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4666 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4667 userId, null, null, "startAssistantActivity");
4671 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4672 throws RemoteException {
4673 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4674 synchronized (this) {
4675 ActivityRecord activity = getFocusedStack().topActivity();
4676 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4677 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4679 if (mRunningVoice != null || activity.getTask().voiceSession != null
4680 || activity.voiceSession != null) {
4681 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4684 if (activity.pendingVoiceInteractionStart) {
4685 Slog.w(TAG, "Pending start of voice interaction already.");
4688 activity.pendingVoiceInteractionStart = true;
4690 LocalServices.getService(VoiceInteractionManagerInternal.class)
4691 .startLocalVoiceInteraction(callingActivity, options);
4695 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4696 LocalServices.getService(VoiceInteractionManagerInternal.class)
4697 .stopLocalVoiceInteraction(callingActivity);
4701 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4702 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4703 .supportsLocalVoiceInteraction();
4706 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4707 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4708 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4709 if (activityToCallback == null) return;
4710 activityToCallback.setVoiceSessionLocked(voiceSession);
4712 // Inform the activity
4714 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4716 long token = Binder.clearCallingIdentity();
4718 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4720 Binder.restoreCallingIdentity(token);
4722 // TODO: VI Should we cache the activity so that it's easier to find later
4723 // rather than scan through all the stacks and activities?
4724 } catch (RemoteException re) {
4725 activityToCallback.clearVoiceSessionLocked();
4726 // TODO: VI Should this terminate the voice session?
4731 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4732 synchronized (this) {
4733 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4735 mVoiceWakeLock.acquire();
4737 mVoiceWakeLock.release();
4744 public boolean startNextMatchingActivity(IBinder callingActivity,
4745 Intent intent, Bundle bOptions) {
4746 // Refuse possible leaked file descriptors
4747 if (intent != null && intent.hasFileDescriptors() == true) {
4748 throw new IllegalArgumentException("File descriptors passed in Intent");
4750 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4752 synchronized (this) {
4753 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4755 ActivityOptions.abort(options);
4758 if (r.app == null || r.app.thread == null) {
4759 // The caller is not running... d'oh!
4760 ActivityOptions.abort(options);
4763 intent = new Intent(intent);
4764 // The caller is not allowed to change the data.
4765 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4766 // And we are resetting to find the next component...
4767 intent.setComponent(null);
4769 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4771 ActivityInfo aInfo = null;
4773 List<ResolveInfo> resolves =
4774 AppGlobals.getPackageManager().queryIntentActivities(
4775 intent, r.resolvedType,
4776 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4777 UserHandle.getCallingUserId()).getList();
4779 // Look for the original activity in the list...
4780 final int N = resolves != null ? resolves.size() : 0;
4781 for (int i=0; i<N; i++) {
4782 ResolveInfo rInfo = resolves.get(i);
4783 if (rInfo.activityInfo.packageName.equals(r.packageName)
4784 && rInfo.activityInfo.name.equals(r.info.name)) {
4785 // We found the current one... the next matching is
4789 aInfo = resolves.get(i).activityInfo;
4792 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4793 + "/" + r.info.name);
4794 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4795 ? "null" : aInfo.packageName + "/" + aInfo.name));
4800 } catch (RemoteException e) {
4803 if (aInfo == null) {
4804 // Nobody who is next!
4805 ActivityOptions.abort(options);
4806 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4810 intent.setComponent(new ComponentName(
4811 aInfo.applicationInfo.packageName, aInfo.name));
4812 intent.setFlags(intent.getFlags()&~(
4813 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4814 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4815 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4816 Intent.FLAG_ACTIVITY_NEW_TASK));
4818 // Okay now we need to start the new activity, replacing the
4819 // currently running activity. This is a little tricky because
4820 // we want to start the new one as if the current one is finished,
4821 // but not finish the current one first so that there is no flicker.
4823 final boolean wasFinishing = r.finishing;
4826 // Propagate reply information over to the new activity.
4827 final ActivityRecord resultTo = r.resultTo;
4828 final String resultWho = r.resultWho;
4829 final int requestCode = r.requestCode;
4831 if (resultTo != null) {
4832 resultTo.removeResultsLocked(r, resultWho, requestCode);
4835 final long origId = Binder.clearCallingIdentity();
4836 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4837 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4838 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4839 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4840 false, false, null, null, null, "startNextMatchingActivity");
4841 Binder.restoreCallingIdentity(origId);
4843 r.finishing = wasFinishing;
4844 if (res != ActivityManager.START_SUCCESS) {
4852 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4853 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4854 String msg = "Permission Denial: startActivityFromRecents called without " +
4855 START_TASKS_FROM_RECENTS;
4857 throw new SecurityException(msg);
4859 final long origId = Binder.clearCallingIdentity();
4861 synchronized (this) {
4862 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4865 Binder.restoreCallingIdentity(origId);
4869 final int startActivityInPackage(int uid, String callingPackage,
4870 Intent intent, String resolvedType, IBinder resultTo,
4871 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4872 IActivityContainer container, TaskRecord inTask, String reason) {
4874 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4875 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4877 // TODO: Switch to user app stacks here.
4878 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4879 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4880 null, null, null, bOptions, false, userId, container, inTask, reason);
4885 public final int startActivities(IApplicationThread caller, String callingPackage,
4886 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4888 final String reason = "startActivities";
4889 enforceNotIsolatedCaller(reason);
4890 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4891 userId, false, ALLOW_FULL_ONLY, reason, null);
4892 // TODO: Switch to user app stacks here.
4893 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4894 resolvedTypes, resultTo, bOptions, userId, reason);
4898 final int startActivitiesInPackage(int uid, String callingPackage,
4899 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4900 Bundle bOptions, int userId) {
4902 final String reason = "startActivityInPackage";
4903 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4904 userId, false, ALLOW_FULL_ONLY, reason, null);
4905 // TODO: Switch to user app stacks here.
4906 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4907 resultTo, bOptions, userId, reason);
4912 public void reportActivityFullyDrawn(IBinder token) {
4913 synchronized (this) {
4914 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4918 r.reportFullyDrawnLocked();
4923 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4924 synchronized (this) {
4925 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4929 final long origId = Binder.clearCallingIdentity();
4931 r.setRequestedOrientation(requestedOrientation);
4933 Binder.restoreCallingIdentity(origId);
4939 public int getRequestedOrientation(IBinder token) {
4940 synchronized (this) {
4941 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4943 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4945 return r.getRequestedOrientation();
4950 public final void requestActivityRelaunch(IBinder token) {
4951 synchronized(this) {
4952 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4956 final long origId = Binder.clearCallingIdentity();
4958 r.forceNewConfig = true;
4959 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4960 true /* preserveWindow */);
4962 Binder.restoreCallingIdentity(origId);
4968 * This is the internal entry point for handling Activity.finish().
4970 * @param token The Binder token referencing the Activity we want to finish.
4971 * @param resultCode Result code, if any, from this Activity.
4972 * @param resultData Result data (Intent), if any, from this Activity.
4973 * @param finishTask Whether to finish the task associated with this Activity.
4975 * @return Returns true if the activity successfully finished, or false if it is still running.
4978 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4980 // Refuse possible leaked file descriptors
4981 if (resultData != null && resultData.hasFileDescriptors() == true) {
4982 throw new IllegalArgumentException("File descriptors passed in Intent");
4985 synchronized(this) {
4986 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4990 // Keep track of the root activity of the task before we finish it
4991 TaskRecord tr = r.getTask();
4992 ActivityRecord rootR = tr.getRootActivity();
4993 if (rootR == null) {
4994 Slog.w(TAG, "Finishing task with all activities already finished");
4996 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4998 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4999 mStackSupervisor.isLastLockedTask(tr)) {
5000 Slog.i(TAG, "Not finishing task in lock task mode");
5001 mStackSupervisor.showLockTaskToast();
5004 if (mController != null) {
5005 // Find the first activity that is not finishing.
5006 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5008 // ask watcher if this is allowed
5009 boolean resumeOK = true;
5011 resumeOK = mController.activityResuming(next.packageName);
5012 } catch (RemoteException e) {
5014 Watchdog.getInstance().setActivityController(null);
5018 Slog.i(TAG, "Not finishing activity because controller resumed");
5023 final long origId = Binder.clearCallingIdentity();
5026 final boolean finishWithRootActivity =
5027 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5028 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5029 || (finishWithRootActivity && r == rootR)) {
5030 // If requested, remove the task that is associated to this activity only if it
5031 // was the root activity in the task. The result code and data is ignored
5032 // because we don't support returning them across task boundaries. Also, to
5033 // keep backwards compatibility we remove the task from recents when finishing
5034 // task with root activity.
5035 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5037 Slog.i(TAG, "Removing task failed to finish activity");
5040 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5041 resultData, "app-request", true);
5043 Slog.i(TAG, "Failed to finish by app-request");
5048 Binder.restoreCallingIdentity(origId);
5054 public final void finishHeavyWeightApp() {
5055 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5056 != PackageManager.PERMISSION_GRANTED) {
5057 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5058 + Binder.getCallingPid()
5059 + ", uid=" + Binder.getCallingUid()
5060 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5062 throw new SecurityException(msg);
5065 synchronized(this) {
5066 if (mHeavyWeightProcess == null) {
5070 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5071 for (int i = 0; i < activities.size(); i++) {
5072 ActivityRecord r = activities.get(i);
5073 if (!r.finishing && r.isInStackLocked()) {
5074 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5075 null, "finish-heavy", true);
5079 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5080 mHeavyWeightProcess.userId, 0));
5081 mHeavyWeightProcess = null;
5086 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5088 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5089 != PackageManager.PERMISSION_GRANTED) {
5090 String msg = "Permission Denial: crashApplication() from pid="
5091 + Binder.getCallingPid()
5092 + ", uid=" + Binder.getCallingUid()
5093 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5095 throw new SecurityException(msg);
5098 synchronized(this) {
5099 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5104 public final void finishSubActivity(IBinder token, String resultWho,
5106 synchronized(this) {
5107 final long origId = Binder.clearCallingIdentity();
5108 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5110 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5112 Binder.restoreCallingIdentity(origId);
5117 public boolean finishActivityAffinity(IBinder token) {
5118 synchronized(this) {
5119 final long origId = Binder.clearCallingIdentity();
5121 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5126 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5128 final TaskRecord task = r.getTask();
5129 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5130 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5131 mStackSupervisor.showLockTaskToast();
5134 return task.getStack().finishActivityAffinityLocked(r);
5136 Binder.restoreCallingIdentity(origId);
5142 public void finishVoiceTask(IVoiceInteractionSession session) {
5143 synchronized (this) {
5144 final long origId = Binder.clearCallingIdentity();
5146 // TODO: VI Consider treating local voice interactions and voice tasks
5148 mStackSupervisor.finishVoiceTask(session);
5150 Binder.restoreCallingIdentity(origId);
5157 public boolean releaseActivityInstance(IBinder token) {
5158 synchronized(this) {
5159 final long origId = Binder.clearCallingIdentity();
5161 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5165 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5167 Binder.restoreCallingIdentity(origId);
5173 public void releaseSomeActivities(IApplicationThread appInt) {
5174 synchronized(this) {
5175 final long origId = Binder.clearCallingIdentity();
5177 ProcessRecord app = getRecordForAppLocked(appInt);
5178 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5180 Binder.restoreCallingIdentity(origId);
5186 public boolean willActivityBeVisible(IBinder token) {
5187 synchronized(this) {
5188 ActivityStack stack = ActivityRecord.getStackLocked(token);
5189 if (stack != null) {
5190 return stack.willActivityBeVisibleLocked(token);
5197 public void overridePendingTransition(IBinder token, String packageName,
5198 int enterAnim, int exitAnim) {
5199 synchronized(this) {
5200 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5205 final long origId = Binder.clearCallingIdentity();
5207 if (self.state == ActivityState.RESUMED
5208 || self.state == ActivityState.PAUSING) {
5209 mWindowManager.overridePendingAppTransition(packageName,
5210 enterAnim, exitAnim, null);
5213 Binder.restoreCallingIdentity(origId);
5218 * Main function for removing an existing process from the activity manager
5219 * as a result of that process going away. Clears out all connections
5222 private final void handleAppDiedLocked(ProcessRecord app,
5223 boolean restarting, boolean allowRestart) {
5225 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5226 false /*replacingPid*/);
5227 if (!kept && !restarting) {
5228 removeLruProcessLocked(app);
5230 ProcessList.remove(pid);
5234 if (mProfileProc == app) {
5235 clearProfilerLocked();
5238 // Remove this application's activities from active lists.
5239 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5241 app.activities.clear();
5243 if (app.instr != null) {
5244 Slog.w(TAG, "Crash of app " + app.processName
5245 + " running instrumentation " + app.instr.mClass);
5246 Bundle info = new Bundle();
5247 info.putString("shortMsg", "Process crashed.");
5248 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5251 mWindowManager.deferSurfaceLayout();
5253 if (!restarting && hasVisibleActivities
5254 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5255 // If there was nothing to resume, and we are not already restarting this process, but
5256 // there is a visible activity that is hosted by the process... then make sure all
5257 // visible activities are running, taking care of restarting this process.
5258 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5261 mWindowManager.continueSurfaceLayout();
5265 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5266 final IBinder threadBinder = thread.asBinder();
5267 // Find the application record.
5268 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5269 final ProcessRecord rec = mLruProcesses.get(i);
5270 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5277 final ProcessRecord getRecordForAppLocked(
5278 IApplicationThread thread) {
5279 if (thread == null) {
5283 int appIndex = getLRURecordIndexForAppLocked(thread);
5284 if (appIndex >= 0) {
5285 return mLruProcesses.get(appIndex);
5288 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5289 // double-check that.
5290 final IBinder threadBinder = thread.asBinder();
5291 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5292 for (int i = pmap.size()-1; i >= 0; i--) {
5293 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5294 for (int j = procs.size()-1; j >= 0; j--) {
5295 final ProcessRecord proc = procs.valueAt(j);
5296 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5297 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5307 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5308 // If there are no longer any background processes running,
5309 // and the app that died was not running instrumentation,
5310 // then tell everyone we are now low on memory.
5311 boolean haveBg = false;
5312 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5313 ProcessRecord rec = mLruProcesses.get(i);
5314 if (rec.thread != null
5315 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5322 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5324 long now = SystemClock.uptimeMillis();
5325 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5328 mLastMemUsageReportTime = now;
5331 final ArrayList<ProcessMemInfo> memInfos
5332 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5333 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5334 long now = SystemClock.uptimeMillis();
5335 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5336 ProcessRecord rec = mLruProcesses.get(i);
5337 if (rec == dyingProc || rec.thread == null) {
5341 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5342 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5344 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5345 // The low memory report is overriding any current
5346 // state for a GC request. Make sure to do
5347 // heavy/important/visible/foreground processes first.
5348 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5349 rec.lastRequestedGc = 0;
5351 rec.lastRequestedGc = rec.lastLowMemory;
5353 rec.reportLowMemory = true;
5354 rec.lastLowMemory = now;
5355 mProcessesToGc.remove(rec);
5356 addProcessToGcListLocked(rec);
5360 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5361 mHandler.sendMessage(msg);
5363 scheduleAppGcsLocked();
5367 final void appDiedLocked(ProcessRecord app) {
5368 appDiedLocked(app, app.pid, app.thread, false);
5371 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5372 boolean fromBinderDied) {
5373 // First check if this ProcessRecord is actually active for the pid.
5374 synchronized (mPidsSelfLocked) {
5375 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5376 if (curProc != app) {
5377 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5382 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5383 synchronized (stats) {
5384 stats.noteProcessDiedLocked(app.info.uid, pid);
5388 if (!fromBinderDied) {
5389 killProcessQuiet(pid);
5391 killProcessGroup(app.uid, pid);
5395 // Clean up already done if the process has been re-started.
5396 if (app.pid == pid && app.thread != null &&
5397 app.thread.asBinder() == thread.asBinder()) {
5398 boolean doLowMem = app.instr == null;
5399 boolean doOomAdj = doLowMem;
5400 if (!app.killedByAm) {
5401 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5402 + ProcessList.makeOomAdjString(app.setAdj)
5403 + ProcessList.makeProcStateString(app.setProcState));
5404 mAllowLowerMemLevel = true;
5406 // Note that we always want to do oom adj to update our state with the
5407 // new number of procs.
5408 mAllowLowerMemLevel = false;
5411 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5412 app.setAdj, app.setProcState);
5413 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5414 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5415 handleAppDiedLocked(app, false, true);
5418 updateOomAdjLocked();
5421 doLowMemReportIfNeededLocked(app);
5423 } else if (app.pid != pid) {
5424 // A new process has already been started.
5425 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5426 + ") has died and restarted (pid " + app.pid + ").");
5427 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5428 } else if (DEBUG_PROCESSES) {
5429 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5430 + thread.asBinder());
5435 * If a stack trace dump file is configured, dump process stack traces.
5436 * @param clearTraces causes the dump file to be erased prior to the new
5437 * traces being written, if true; when false, the new traces will be
5438 * appended to any existing file content.
5439 * @param firstPids of dalvik VM processes to dump stack traces for first
5440 * @param lastPids of dalvik VM processes to dump stack traces for last
5441 * @param nativePids optional list of native pids to dump stack crawls
5443 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5444 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5445 ArrayList<Integer> nativePids) {
5446 ArrayList<Integer> extraPids = null;
5448 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5449 // of the top users at the time of the request.
5450 if (processCpuTracker != null) {
5451 processCpuTracker.init();
5454 } catch (InterruptedException ignored) {
5457 processCpuTracker.update();
5459 // We'll take the stack crawls of just the top apps using CPU.
5460 final int N = processCpuTracker.countWorkingStats();
5461 extraPids = new ArrayList<>();
5462 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5463 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5464 if (lastPids.indexOfKey(stats.pid) >= 0) {
5465 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5467 extraPids.add(stats.pid);
5468 } else if (DEBUG_ANR) {
5469 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5475 boolean useTombstonedForJavaTraces = false;
5478 final String tracesDir = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5479 if (tracesDir.isEmpty()) {
5480 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5481 // dumping scheme. All traces are written to a global trace file (usually
5482 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5483 // the file if requested.
5485 // This mode of operation will be removed in the near future.
5488 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5489 if (globalTracesPath.isEmpty()) {
5490 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5494 tracesFile = new File(globalTracesPath);
5496 if (clearTraces && tracesFile.exists()) {
5497 tracesFile.delete();
5500 tracesFile.createNewFile();
5501 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5502 } catch (IOException e) {
5503 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5507 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5508 // Each set of ANR traces is written to a separate file and dumpstate will process
5509 // all such files and add them to a captured bug report if they're recent enough.
5511 // NOTE: We should consider creating the file in native code atomically once we've
5512 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5515 tracesFile = File.createTempFile("anr_", "", new File(tracesDir));
5516 FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5517 } catch (IOException ioe) {
5518 Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
5522 useTombstonedForJavaTraces = true;
5525 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5526 useTombstonedForJavaTraces);
5531 * Legacy code, do not use. Existing users will be deleted.
5536 public static class DumpStackFileObserver extends FileObserver {
5537 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5538 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5540 private final String mTracesPath;
5541 private boolean mClosed;
5543 public DumpStackFileObserver(String tracesPath) {
5544 super(tracesPath, FileObserver.CLOSE_WRITE);
5545 mTracesPath = tracesPath;
5549 public synchronized void onEvent(int event, String path) {
5554 public long dumpWithTimeout(int pid, long timeout) {
5555 sendSignal(pid, SIGNAL_QUIT);
5556 final long start = SystemClock.elapsedRealtime();
5558 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5559 synchronized (this) {
5561 wait(waitTime); // Wait for traces file to be closed.
5562 } catch (InterruptedException e) {
5567 // This avoids a corner case of passing a negative time to the native
5568 // trace in case we've already hit the overall timeout.
5569 final long timeWaited = SystemClock.elapsedRealtime() - start;
5570 if (timeWaited >= timeout) {
5575 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5576 ". Attempting native stack collection.");
5578 final long nativeDumpTimeoutMs = Math.min(
5579 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5581 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5582 (int) (nativeDumpTimeoutMs / 1000));
5585 final long end = SystemClock.elapsedRealtime();
5588 return (end - start);
5593 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5594 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5595 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5596 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5599 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5600 final long timeStart = SystemClock.elapsedRealtime();
5601 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5602 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5603 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5606 return SystemClock.elapsedRealtime() - timeStart;
5609 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5610 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5611 boolean useTombstonedForJavaTraces) {
5613 // We don't need any sort of inotify based monitoring when we're dumping traces via
5614 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5615 // control of all writes to the file in question.
5616 final DumpStackFileObserver observer;
5617 if (useTombstonedForJavaTraces) {
5620 // Use a FileObserver to detect when traces finish writing.
5621 // The order of traces is considered important to maintain for legibility.
5622 observer = new DumpStackFileObserver(tracesFile);
5625 // We must complete all stack dumps within 20 seconds.
5626 long remainingTime = 20 * 1000;
5628 if (observer != null) {
5629 observer.startWatching();
5632 // First collect all of the stacks of the most important pids.
5633 if (firstPids != null) {
5634 int num = firstPids.size();
5635 for (int i = 0; i < num; i++) {
5636 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5637 + firstPids.get(i));
5638 final long timeTaken;
5639 if (useTombstonedForJavaTraces) {
5640 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5642 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5645 remainingTime -= timeTaken;
5646 if (remainingTime <= 0) {
5647 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5648 "); deadline exceeded.");
5653 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5658 // Next collect the stacks of the native pids
5659 if (nativePids != null) {
5660 for (int pid : nativePids) {
5661 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5662 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5664 final long start = SystemClock.elapsedRealtime();
5665 Debug.dumpNativeBacktraceToFileTimeout(
5666 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5667 final long timeTaken = SystemClock.elapsedRealtime() - start;
5669 remainingTime -= timeTaken;
5670 if (remainingTime <= 0) {
5671 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5672 "); deadline exceeded.");
5677 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5682 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5683 if (extraPids != null) {
5684 for (int pid : extraPids) {
5685 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5687 final long timeTaken;
5688 if (useTombstonedForJavaTraces) {
5689 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5691 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5694 remainingTime -= timeTaken;
5695 if (remainingTime <= 0) {
5696 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5697 "); deadline exceeded.");
5702 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5707 if (observer != null) {
5708 observer.stopWatching();
5713 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5714 if (true || IS_USER_BUILD) {
5717 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5718 if (tracesPath == null || tracesPath.length() == 0) {
5722 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5723 StrictMode.allowThreadDiskWrites();
5725 final File tracesFile = new File(tracesPath);
5726 final File tracesDir = tracesFile.getParentFile();
5727 final File tracesTmp = new File(tracesDir, "__tmp__");
5729 if (tracesFile.exists()) {
5731 tracesFile.renameTo(tracesTmp);
5733 StringBuilder sb = new StringBuilder();
5734 Time tobj = new Time();
5735 tobj.set(System.currentTimeMillis());
5736 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5738 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5739 sb.append(" since ");
5741 FileOutputStream fos = new FileOutputStream(tracesFile);
5742 fos.write(sb.toString().getBytes());
5744 fos.write("\n*** No application process!".getBytes());
5747 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5748 } catch (IOException e) {
5749 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5754 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5755 firstPids.add(app.pid);
5756 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5759 File lastTracesFile = null;
5760 File curTracesFile = null;
5761 for (int i=9; i>=0; i--) {
5762 String name = String.format(Locale.US, "slow%02d.txt", i);
5763 curTracesFile = new File(tracesDir, name);
5764 if (curTracesFile.exists()) {
5765 if (lastTracesFile != null) {
5766 curTracesFile.renameTo(lastTracesFile);
5768 curTracesFile.delete();
5771 lastTracesFile = curTracesFile;
5773 tracesFile.renameTo(curTracesFile);
5774 if (tracesTmp.exists()) {
5775 tracesTmp.renameTo(tracesFile);
5778 StrictMode.setThreadPolicy(oldPolicy);
5782 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5783 if (!mLaunchWarningShown) {
5784 mLaunchWarningShown = true;
5785 mUiHandler.post(new Runnable() {
5788 synchronized (ActivityManagerService.this) {
5789 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5791 mUiHandler.postDelayed(new Runnable() {
5794 synchronized (ActivityManagerService.this) {
5796 mLaunchWarningShown = false;
5807 public boolean clearApplicationUserData(final String packageName,
5808 final IPackageDataObserver observer, int userId) {
5809 enforceNotIsolatedCaller("clearApplicationUserData");
5810 int uid = Binder.getCallingUid();
5811 int pid = Binder.getCallingPid();
5812 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5813 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5816 long callingId = Binder.clearCallingIdentity();
5818 IPackageManager pm = AppGlobals.getPackageManager();
5820 synchronized(this) {
5821 if (getPackageManagerInternalLocked().isPackageDataProtected(
5822 userId, packageName)) {
5823 throw new SecurityException(
5824 "Cannot clear data for a protected package: " + packageName);
5828 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5829 } catch (RemoteException e) {
5832 Slog.w(TAG, "Invalid packageName: " + packageName);
5833 if (observer != null) {
5835 observer.onRemoveCompleted(packageName, false);
5836 } catch (RemoteException e) {
5837 Slog.i(TAG, "Observer no longer exists.");
5842 if (uid == pkgUid || checkComponentPermission(
5843 android.Manifest.permission.CLEAR_APP_USER_DATA,
5845 == PackageManager.PERMISSION_GRANTED) {
5846 forceStopPackageLocked(packageName, pkgUid, "clear data");
5848 throw new SecurityException("PID " + pid + " does not have permission "
5849 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5850 + " of package " + packageName);
5853 // Remove all tasks match the cleared application package and user
5854 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5855 final TaskRecord tr = mRecentTasks.get(i);
5856 final String taskPackageName =
5857 tr.getBaseIntent().getComponent().getPackageName();
5858 if (tr.userId != userId) continue;
5859 if (!taskPackageName.equals(packageName)) continue;
5860 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5864 final int pkgUidF = pkgUid;
5865 final int userIdF = userId;
5866 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5868 public void onRemoveCompleted(String packageName, boolean succeeded)
5869 throws RemoteException {
5870 synchronized (ActivityManagerService.this) {
5871 finishForceStopPackageLocked(packageName, pkgUidF);
5874 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5875 Uri.fromParts("package", packageName, null));
5876 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5877 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5878 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5879 broadcastIntentInPackage("android", SYSTEM_UID, intent,
5880 null, null, 0, null, null, null, null, false, false, userIdF);
5882 if (observer != null) {
5883 observer.onRemoveCompleted(packageName, succeeded);
5889 // Clear application user data
5890 pm.clearApplicationUserData(packageName, localObserver, userId);
5892 synchronized(this) {
5893 // Remove all permissions granted from/to this package
5894 removeUriPermissionsForPackageLocked(packageName, userId, true);
5897 // Reset notification settings.
5898 INotificationManager inm = NotificationManager.getService();
5899 inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5900 } catch (RemoteException e) {
5903 Binder.restoreCallingIdentity(callingId);
5909 public void killBackgroundProcesses(final String packageName, int userId) {
5910 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5911 != PackageManager.PERMISSION_GRANTED &&
5912 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5913 != PackageManager.PERMISSION_GRANTED) {
5914 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5915 + Binder.getCallingPid()
5916 + ", uid=" + Binder.getCallingUid()
5917 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5919 throw new SecurityException(msg);
5922 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5923 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5924 long callingId = Binder.clearCallingIdentity();
5926 IPackageManager pm = AppGlobals.getPackageManager();
5927 synchronized(this) {
5930 appId = UserHandle.getAppId(
5931 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5932 } catch (RemoteException e) {
5935 Slog.w(TAG, "Invalid packageName: " + packageName);
5938 killPackageProcessesLocked(packageName, appId, userId,
5939 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5942 Binder.restoreCallingIdentity(callingId);
5947 public void killAllBackgroundProcesses() {
5948 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5949 != PackageManager.PERMISSION_GRANTED) {
5950 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5951 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5952 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5954 throw new SecurityException(msg);
5957 final long callingId = Binder.clearCallingIdentity();
5959 synchronized (this) {
5960 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5961 final int NP = mProcessNames.getMap().size();
5962 for (int ip = 0; ip < NP; ip++) {
5963 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5964 final int NA = apps.size();
5965 for (int ia = 0; ia < NA; ia++) {
5966 final ProcessRecord app = apps.valueAt(ia);
5967 if (app.persistent) {
5968 // We don't kill persistent processes.
5973 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5980 final int N = procs.size();
5981 for (int i = 0; i < N; i++) {
5982 removeProcessLocked(procs.get(i), false, true, "kill all background");
5985 mAllowLowerMemLevel = true;
5987 updateOomAdjLocked();
5988 doLowMemReportIfNeededLocked(null);
5991 Binder.restoreCallingIdentity(callingId);
5996 * Kills all background processes, except those matching any of the
5997 * specified properties.
5999 * @param minTargetSdk the target SDK version at or above which to preserve
6000 * processes, or {@code -1} to ignore the target SDK
6001 * @param maxProcState the process state at or below which to preserve
6002 * processes, or {@code -1} to ignore the process state
6004 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6005 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6006 != PackageManager.PERMISSION_GRANTED) {
6007 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6008 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6009 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6011 throw new SecurityException(msg);
6014 final long callingId = Binder.clearCallingIdentity();
6016 synchronized (this) {
6017 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6018 final int NP = mProcessNames.getMap().size();
6019 for (int ip = 0; ip < NP; ip++) {
6020 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6021 final int NA = apps.size();
6022 for (int ia = 0; ia < NA; ia++) {
6023 final ProcessRecord app = apps.valueAt(ia);
6026 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6027 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6034 final int N = procs.size();
6035 for (int i = 0; i < N; i++) {
6036 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6040 Binder.restoreCallingIdentity(callingId);
6045 public void forceStopPackage(final String packageName, int userId) {
6046 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6047 != PackageManager.PERMISSION_GRANTED) {
6048 String msg = "Permission Denial: forceStopPackage() from pid="
6049 + Binder.getCallingPid()
6050 + ", uid=" + Binder.getCallingUid()
6051 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6053 throw new SecurityException(msg);
6055 final int callingPid = Binder.getCallingPid();
6056 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6057 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6058 long callingId = Binder.clearCallingIdentity();
6060 IPackageManager pm = AppGlobals.getPackageManager();
6061 synchronized(this) {
6062 int[] users = userId == UserHandle.USER_ALL
6063 ? mUserController.getUsers() : new int[] { userId };
6064 for (int user : users) {
6067 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6069 } catch (RemoteException e) {
6072 Slog.w(TAG, "Invalid packageName: " + packageName);
6076 pm.setPackageStoppedState(packageName, true, user);
6077 } catch (RemoteException e) {
6078 } catch (IllegalArgumentException e) {
6079 Slog.w(TAG, "Failed trying to unstop package "
6080 + packageName + ": " + e);
6082 if (mUserController.isUserRunningLocked(user, 0)) {
6083 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6084 finishForceStopPackageLocked(packageName, pkgUid);
6089 Binder.restoreCallingIdentity(callingId);
6094 public void addPackageDependency(String packageName) {
6095 synchronized (this) {
6096 int callingPid = Binder.getCallingPid();
6097 if (callingPid == myPid()) {
6102 synchronized (mPidsSelfLocked) {
6103 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6106 if (proc.pkgDeps == null) {
6107 proc.pkgDeps = new ArraySet<String>(1);
6109 proc.pkgDeps.add(packageName);
6115 * The pkg name and app id have to be specified.
6118 public void killApplication(String pkg, int appId, int userId, String reason) {
6122 // Make sure the uid is valid.
6124 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6127 int callerUid = Binder.getCallingUid();
6128 // Only the system server can kill an application
6129 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6130 // Post an aysnc message to kill the application
6131 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6134 Bundle bundle = new Bundle();
6135 bundle.putString("pkg", pkg);
6136 bundle.putString("reason", reason);
6138 mHandler.sendMessage(msg);
6140 throw new SecurityException(callerUid + " cannot kill pkg: " +
6146 public void closeSystemDialogs(String reason) {
6147 enforceNotIsolatedCaller("closeSystemDialogs");
6149 final int pid = Binder.getCallingPid();
6150 final int uid = Binder.getCallingUid();
6151 final long origId = Binder.clearCallingIdentity();
6153 synchronized (this) {
6154 // Only allow this from foreground processes, so that background
6155 // applications can't abuse it to prevent system UI from being shown.
6156 if (uid >= FIRST_APPLICATION_UID) {
6158 synchronized (mPidsSelfLocked) {
6159 proc = mPidsSelfLocked.get(pid);
6161 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6162 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6163 + " from background process " + proc);
6167 closeSystemDialogsLocked(reason);
6170 Binder.restoreCallingIdentity(origId);
6174 void closeSystemDialogsLocked(String reason) {
6175 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6176 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6177 | Intent.FLAG_RECEIVER_FOREGROUND);
6178 if (reason != null) {
6179 intent.putExtra("reason", reason);
6181 mWindowManager.closeSystemDialogs(reason);
6183 mStackSupervisor.closeSystemDialogsLocked();
6185 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6186 AppOpsManager.OP_NONE, null, false, false,
6187 -1, SYSTEM_UID, UserHandle.USER_ALL);
6191 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6192 enforceNotIsolatedCaller("getProcessMemoryInfo");
6193 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6194 for (int i=pids.length-1; i>=0; i--) {
6197 synchronized (this) {
6198 synchronized (mPidsSelfLocked) {
6199 proc = mPidsSelfLocked.get(pids[i]);
6200 oomAdj = proc != null ? proc.setAdj : 0;
6203 infos[i] = new Debug.MemoryInfo();
6204 Debug.getMemoryInfo(pids[i], infos[i]);
6206 synchronized (this) {
6207 if (proc.thread != null && proc.setAdj == oomAdj) {
6208 // Record this for posterity if the process has been stable.
6209 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6210 infos[i].getTotalUss(), false, proc.pkgList);
6219 public long[] getProcessPss(int[] pids) {
6220 enforceNotIsolatedCaller("getProcessPss");
6221 long[] pss = new long[pids.length];
6222 for (int i=pids.length-1; i>=0; i--) {
6225 synchronized (this) {
6226 synchronized (mPidsSelfLocked) {
6227 proc = mPidsSelfLocked.get(pids[i]);
6228 oomAdj = proc != null ? proc.setAdj : 0;
6231 long[] tmpUss = new long[1];
6232 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6234 synchronized (this) {
6235 if (proc.thread != null && proc.setAdj == oomAdj) {
6236 // Record this for posterity if the process has been stable.
6237 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6246 public void killApplicationProcess(String processName, int uid) {
6247 if (processName == null) {
6251 int callerUid = Binder.getCallingUid();
6252 // Only the system server can kill an application
6253 if (callerUid == SYSTEM_UID) {
6254 synchronized (this) {
6255 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6256 if (app != null && app.thread != null) {
6258 app.thread.scheduleSuicide();
6259 } catch (RemoteException e) {
6260 // If the other end already died, then our work here is done.
6263 Slog.w(TAG, "Process/uid not found attempting kill of "
6264 + processName + " / " + uid);
6268 throw new SecurityException(callerUid + " cannot kill app process: " +
6273 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6274 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6275 false, true, false, false, UserHandle.getUserId(uid), reason);
6278 private void finishForceStopPackageLocked(final String packageName, int uid) {
6279 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6280 Uri.fromParts("package", packageName, null));
6281 if (!mProcessesReady) {
6282 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6283 | Intent.FLAG_RECEIVER_FOREGROUND);
6285 intent.putExtra(Intent.EXTRA_UID, uid);
6286 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6287 broadcastIntentLocked(null, null, intent,
6288 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6289 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6293 private final boolean killPackageProcessesLocked(String packageName, int appId,
6294 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6295 boolean doit, boolean evenPersistent, String reason) {
6296 ArrayList<ProcessRecord> procs = new ArrayList<>();
6298 // Remove all processes this package may have touched: all with the
6299 // same UID (except for the system or root user), and all whose name
6300 // matches the package name.
6301 final int NP = mProcessNames.getMap().size();
6302 for (int ip=0; ip<NP; ip++) {
6303 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6304 final int NA = apps.size();
6305 for (int ia=0; ia<NA; ia++) {
6306 ProcessRecord app = apps.valueAt(ia);
6307 if (app.persistent && !evenPersistent) {
6308 // we don't kill persistent processes
6318 // Skip process if it doesn't meet our oom adj requirement.
6319 if (app.setAdj < minOomAdj) {
6323 // If no package is specified, we call all processes under the
6325 if (packageName == null) {
6326 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6329 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6332 // Package has been specified, we want to hit all processes
6333 // that match it. We need to qualify this by the processes
6334 // that are running under the specified app and user ID.
6336 final boolean isDep = app.pkgDeps != null
6337 && app.pkgDeps.contains(packageName);
6338 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6341 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6344 if (!app.pkgList.containsKey(packageName) && !isDep) {
6349 // Process has passed all conditions, kill it!
6358 int N = procs.size();
6359 for (int i=0; i<N; i++) {
6360 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6362 updateOomAdjLocked();
6366 private void cleanupDisabledPackageComponentsLocked(
6367 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6369 Set<String> disabledClasses = null;
6370 boolean packageDisabled = false;
6371 IPackageManager pm = AppGlobals.getPackageManager();
6373 if (changedClasses == null) {
6374 // Nothing changed...
6378 // Determine enable/disable state of the package and its components.
6379 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6380 for (int i = changedClasses.length - 1; i >= 0; i--) {
6381 final String changedClass = changedClasses[i];
6383 if (changedClass.equals(packageName)) {
6385 // Entire package setting changed
6386 enabled = pm.getApplicationEnabledSetting(packageName,
6387 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6388 } catch (Exception e) {
6389 // No such package/component; probably racing with uninstall. In any
6390 // event it means we have nothing further to do here.
6393 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6394 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6395 if (packageDisabled) {
6396 // Entire package is disabled.
6397 // No need to continue to check component states.
6398 disabledClasses = null;
6403 enabled = pm.getComponentEnabledSetting(
6404 new ComponentName(packageName, changedClass),
6405 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6406 } catch (Exception e) {
6407 // As above, probably racing with uninstall.
6410 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6411 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6412 if (disabledClasses == null) {
6413 disabledClasses = new ArraySet<>(changedClasses.length);
6415 disabledClasses.add(changedClass);
6420 if (!packageDisabled && disabledClasses == null) {
6421 // Nothing to do here...
6425 // Clean-up disabled activities.
6426 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6427 packageName, disabledClasses, true, false, userId) && mBooted) {
6428 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6429 mStackSupervisor.scheduleIdleLocked();
6432 // Clean-up disabled tasks
6433 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6435 // Clean-up disabled services.
6436 mServices.bringDownDisabledPackageServicesLocked(
6437 packageName, disabledClasses, userId, false, killProcess, true);
6439 // Clean-up disabled providers.
6440 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6441 mProviderMap.collectPackageProvidersLocked(
6442 packageName, disabledClasses, true, false, userId, providers);
6443 for (int i = providers.size() - 1; i >= 0; i--) {
6444 removeDyingProviderLocked(null, providers.get(i), true);
6447 // Clean-up disabled broadcast receivers.
6448 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6449 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6450 packageName, disabledClasses, userId, true);
6455 final boolean clearBroadcastQueueForUserLocked(int userId) {
6456 boolean didSomething = false;
6457 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6458 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6459 null, null, userId, true);
6461 return didSomething;
6464 final boolean forceStopPackageLocked(String packageName, int appId,
6465 boolean callerWillRestart, boolean purgeCache, boolean doit,
6466 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6469 if (userId == UserHandle.USER_ALL && packageName == null) {
6470 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6473 if (appId < 0 && packageName != null) {
6475 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6476 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6477 } catch (RemoteException e) {
6482 if (packageName != null) {
6483 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6484 + " user=" + userId + ": " + reason);
6486 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6489 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6492 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6493 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6494 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6496 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6498 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6499 packageName, null, doit, evenPersistent, userId)) {
6503 didSomething = true;
6506 if (mServices.bringDownDisabledPackageServicesLocked(
6507 packageName, null, userId, evenPersistent, true, doit)) {
6511 didSomething = true;
6514 if (packageName == null) {
6515 // Remove all sticky broadcasts from this user.
6516 mStickyBroadcasts.remove(userId);
6519 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6520 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6521 userId, providers)) {
6525 didSomething = true;
6527 for (i = providers.size() - 1; i >= 0; i--) {
6528 removeDyingProviderLocked(null, providers.get(i), true);
6531 // Remove transient permissions granted from/to this package/user
6532 removeUriPermissionsForPackageLocked(packageName, userId, false);
6535 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6536 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6537 packageName, null, userId, doit);
6541 if (packageName == null || uninstalling) {
6542 // Remove pending intents. For now we only do this when force
6543 // stopping users, because we have some problems when doing this
6544 // for packages -- app widgets are not currently cleaned up for
6545 // such packages, so they can be left with bad pending intents.
6546 if (mIntentSenderRecords.size() > 0) {
6547 Iterator<WeakReference<PendingIntentRecord>> it
6548 = mIntentSenderRecords.values().iterator();
6549 while (it.hasNext()) {
6550 WeakReference<PendingIntentRecord> wpir = it.next();
6555 PendingIntentRecord pir = wpir.get();
6560 if (packageName == null) {
6561 // Stopping user, remove all objects for the user.
6562 if (pir.key.userId != userId) {
6563 // Not the same user, skip it.
6567 if (UserHandle.getAppId(pir.uid) != appId) {
6568 // Different app id, skip it.
6571 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6572 // Different user, skip it.
6575 if (!pir.key.packageName.equals(packageName)) {
6576 // Different package, skip it.
6583 didSomething = true;
6585 makeIntentSenderCanceledLocked(pir);
6586 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6587 pir.key.activity.pendingResults.remove(pir.ref);
6594 if (purgeCache && packageName != null) {
6595 AttributeCache ac = AttributeCache.instance();
6597 ac.removePackage(packageName);
6601 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6602 mStackSupervisor.scheduleIdleLocked();
6606 return didSomething;
6609 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6610 return removeProcessNameLocked(name, uid, null);
6613 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6614 final ProcessRecord expecting) {
6615 ProcessRecord old = mProcessNames.get(name, uid);
6616 // Only actually remove when the currently recorded value matches the
6617 // record that we expected; if it doesn't match then we raced with a
6618 // newly created process and we don't want to destroy the new one.
6619 if ((expecting == null) || (old == expecting)) {
6620 mProcessNames.remove(name, uid);
6622 if (old != null && old.uidRecord != null) {
6623 old.uidRecord.numProcs--;
6624 if (old.uidRecord.numProcs == 0) {
6625 // No more processes using this uid, tell clients it is gone.
6626 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6627 "No more processes in " + old.uidRecord);
6628 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6629 EventLogTags.writeAmUidStopped(uid);
6630 mActiveUids.remove(uid);
6631 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6633 old.uidRecord = null;
6635 mIsolatedProcesses.remove(uid);
6639 private final void addProcessNameLocked(ProcessRecord proc) {
6640 // We shouldn't already have a process under this name, but just in case we
6641 // need to clean up whatever may be there now.
6642 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6643 if (old == proc && proc.persistent) {
6644 // We are re-adding a persistent process. Whatevs! Just leave it there.
6645 Slog.w(TAG, "Re-adding persistent process " + proc);
6646 } else if (old != null) {
6647 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6649 UidRecord uidRec = mActiveUids.get(proc.uid);
6650 if (uidRec == null) {
6651 uidRec = new UidRecord(proc.uid);
6652 // This is the first appearance of the uid, report it now!
6653 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6654 "Creating new process uid: " + uidRec);
6655 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6656 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6657 uidRec.setWhitelist = uidRec.curWhitelist = true;
6659 uidRec.updateHasInternetPermission();
6660 mActiveUids.put(proc.uid, uidRec);
6661 EventLogTags.writeAmUidRunning(uidRec.uid);
6662 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6663 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6665 proc.uidRecord = uidRec;
6667 // Reset render thread tid if it was already set, so new process can set it again.
6668 proc.renderThreadTid = 0;
6670 mProcessNames.put(proc.processName, proc.uid, proc);
6671 if (proc.isolated) {
6672 mIsolatedProcesses.put(proc.uid, proc);
6676 boolean removeProcessLocked(ProcessRecord app,
6677 boolean callerWillRestart, boolean allowRestart, String reason) {
6678 final String name = app.processName;
6679 final int uid = app.uid;
6680 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6681 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6683 ProcessRecord old = mProcessNames.get(name, uid);
6685 // This process is no longer active, so nothing to do.
6686 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6689 removeProcessNameLocked(name, uid);
6690 if (mHeavyWeightProcess == app) {
6691 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6692 mHeavyWeightProcess.userId, 0));
6693 mHeavyWeightProcess = null;
6695 boolean needRestart = false;
6696 if (app.pid > 0 && app.pid != MY_PID) {
6698 synchronized (mPidsSelfLocked) {
6699 mPidsSelfLocked.remove(pid);
6700 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6702 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6704 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6705 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6707 boolean willRestart = false;
6708 if (app.persistent && !app.isolated) {
6709 if (!callerWillRestart) {
6715 app.kill(reason, true);
6716 handleAppDiedLocked(app, willRestart, allowRestart);
6718 removeLruProcessLocked(app);
6719 addAppLocked(app.info, null, false, null /* ABI override */);
6722 mRemovedProcesses.add(app);
6728 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6729 cleanupAppInLaunchingProvidersLocked(app, true);
6730 removeProcessLocked(app, false, true, "timeout publishing content providers");
6733 private final void processStartTimedOutLocked(ProcessRecord app) {
6734 final int pid = app.pid;
6735 boolean gone = false;
6736 synchronized (mPidsSelfLocked) {
6737 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6738 if (knownApp != null && knownApp.thread == null) {
6739 mPidsSelfLocked.remove(pid);
6745 Slog.w(TAG, "Process " + app + " failed to attach");
6746 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6747 pid, app.uid, app.processName);
6748 removeProcessNameLocked(app.processName, app.uid);
6749 if (mHeavyWeightProcess == app) {
6750 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6751 mHeavyWeightProcess.userId, 0));
6752 mHeavyWeightProcess = null;
6754 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6756 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6758 // Take care of any launching providers waiting for this process.
6759 cleanupAppInLaunchingProvidersLocked(app, true);
6760 // Take care of any services that are waiting for the process.
6761 mServices.processStartTimedOutLocked(app);
6762 app.kill("start timeout", true);
6763 removeLruProcessLocked(app);
6764 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6765 Slog.w(TAG, "Unattached app died before backup, skipping");
6766 mHandler.post(new Runnable() {
6770 IBackupManager bm = IBackupManager.Stub.asInterface(
6771 ServiceManager.getService(Context.BACKUP_SERVICE));
6772 bm.agentDisconnected(app.info.packageName);
6773 } catch (RemoteException e) {
6774 // Can't happen; the backup manager is local
6779 if (isPendingBroadcastProcessLocked(pid)) {
6780 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6781 skipPendingBroadcastLocked(pid);
6784 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6788 private final boolean attachApplicationLocked(IApplicationThread thread,
6791 // Find the application record that is being attached... either via
6792 // the pid if we are running in multiple processes, or just pull the
6793 // next app record if we are emulating process with anonymous threads.
6795 long startTime = SystemClock.uptimeMillis();
6796 if (pid != MY_PID && pid >= 0) {
6797 synchronized (mPidsSelfLocked) {
6798 app = mPidsSelfLocked.get(pid);
6805 Slog.w(TAG, "No pending application record for pid " + pid
6806 + " (IApplicationThread " + thread + "); dropping process");
6807 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6808 if (pid > 0 && pid != MY_PID) {
6809 killProcessQuiet(pid);
6810 //TODO: killProcessGroup(app.info.uid, pid);
6813 thread.scheduleExit();
6814 } catch (Exception e) {
6815 // Ignore exceptions.
6821 // If this application record is still attached to a previous
6822 // process, clean it up now.
6823 if (app.thread != null) {
6824 handleAppDiedLocked(app, true, true);
6827 // Tell the process all about itself.
6829 if (DEBUG_ALL) Slog.v(
6830 TAG, "Binding process pid " + pid + " to record " + app);
6832 final String processName = app.processName;
6834 AppDeathRecipient adr = new AppDeathRecipient(
6836 thread.asBinder().linkToDeath(adr, 0);
6837 app.deathRecipient = adr;
6838 } catch (RemoteException e) {
6839 app.resetPackageList(mProcessStats);
6840 startProcessLocked(app, "link fail", processName);
6844 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6846 app.makeActive(thread, mProcessStats);
6847 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6848 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6849 app.forcingToImportant = null;
6850 updateProcessForegroundLocked(app, false, false);
6851 app.hasShownUi = false;
6852 app.debugging = false;
6854 app.killedByAm = false;
6858 // We carefully use the same state that PackageManager uses for
6859 // filtering, since we use this flag to decide if we need to install
6860 // providers when user is unlocked later
6861 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6863 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6865 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6866 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6868 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6869 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6871 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6874 checkTime(startTime, "attachApplicationLocked: before bindApplication");
6877 Slog.i(TAG, "Launching preboot mode app: " + app);
6880 if (DEBUG_ALL) Slog.v(
6881 TAG, "New app record " + app
6882 + " thread=" + thread.asBinder() + " pid=" + pid);
6884 int testMode = ApplicationThreadConstants.DEBUG_OFF;
6885 if (mDebugApp != null && mDebugApp.equals(processName)) {
6886 testMode = mWaitForDebugger
6887 ? ApplicationThreadConstants.DEBUG_WAIT
6888 : ApplicationThreadConstants.DEBUG_ON;
6889 app.debugging = true;
6890 if (mDebugTransient) {
6891 mDebugApp = mOrigDebugApp;
6892 mWaitForDebugger = mOrigWaitForDebugger;
6895 String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6896 ParcelFileDescriptor profileFd = null;
6897 int samplingInterval = 0;
6898 boolean profileAutoStop = false;
6899 boolean profileStreamingOutput = false;
6900 if (mProfileApp != null && mProfileApp.equals(processName)) {
6902 profileFile = mProfileFile;
6903 profileFd = mProfileFd;
6904 samplingInterval = mSamplingInterval;
6905 profileAutoStop = mAutoStopProfiler;
6906 profileStreamingOutput = mStreamingOutput;
6908 boolean enableTrackAllocation = false;
6909 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6910 enableTrackAllocation = true;
6911 mTrackAllocationApp = null;
6914 // If the app is being launched for restore or full backup, set it up specially
6915 boolean isRestrictedBackupMode = false;
6916 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6917 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6918 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6919 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6920 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6923 if (app.instr != null) {
6924 notifyPackageUse(app.instr.mClass.getPackageName(),
6925 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6927 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6928 + processName + " with config " + getGlobalConfiguration());
6929 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6930 app.compat = compatibilityInfoForPackageLocked(appInfo);
6931 if (profileFd != null) {
6932 profileFd = profileFd.dup();
6934 ProfilerInfo profilerInfo = profileFile == null ? null
6935 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6936 profileStreamingOutput);
6938 // We deprecated Build.SERIAL and it is not accessible to
6939 // apps that target the v2 security sandbox. Since access to
6940 // the serial is now behind a permission we push down the value.
6941 String buildSerial = Build.UNKNOWN;
6942 if (appInfo.targetSandboxVersion != 2) {
6943 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6944 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6948 // Check if this is a secondary process that should be incorporated into some
6949 // currently active instrumentation. (Note we do this AFTER all of the profiling
6950 // stuff above because profiling can currently happen only in the primary
6951 // instrumentation process.)
6952 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6953 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6954 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6955 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6956 if (aInstr.mTargetProcesses.length == 0) {
6957 // This is the wildcard mode, where every process brought up for
6958 // the target instrumentation should be included.
6959 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6961 aInstr.mRunningProcesses.add(app);
6964 for (String proc : aInstr.mTargetProcesses) {
6965 if (proc.equals(app.processName)) {
6967 aInstr.mRunningProcesses.add(app);
6976 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6977 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6978 if (app.instr != null) {
6979 thread.bindApplication(processName, appInfo, providers,
6981 profilerInfo, app.instr.mArguments,
6983 app.instr.mUiAutomationConnection, testMode,
6984 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6985 isRestrictedBackupMode || !normalMode, app.persistent,
6986 new Configuration(getGlobalConfiguration()), app.compat,
6987 getCommonServicesLocked(app.isolated),
6988 mCoreSettingsObserver.getCoreSettingsLocked(),
6991 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6992 null, null, null, testMode,
6993 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6994 isRestrictedBackupMode || !normalMode, app.persistent,
6995 new Configuration(getGlobalConfiguration()), app.compat,
6996 getCommonServicesLocked(app.isolated),
6997 mCoreSettingsObserver.getCoreSettingsLocked(),
7001 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7002 updateLruProcessLocked(app, false, null);
7003 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7004 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7005 } catch (Exception e) {
7006 // todo: Yikes! What should we do? For now we will try to
7007 // start another process, but that could easily get us in
7008 // an infinite loop of restarting processes...
7009 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7011 app.resetPackageList(mProcessStats);
7012 app.unlinkDeathRecipient();
7013 startProcessLocked(app, "bind fail", processName);
7017 // Remove this record from the list of starting applications.
7018 mPersistentStartingProcesses.remove(app);
7019 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7020 "Attach application locked removing on hold: " + app);
7021 mProcessesOnHold.remove(app);
7023 boolean badApp = false;
7024 boolean didSomething = false;
7026 // See if the top visible activity is waiting to run in this process...
7029 if (mStackSupervisor.attachApplicationLocked(app)) {
7030 didSomething = true;
7032 } catch (Exception e) {
7033 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7038 // Find any services that should be running in this process...
7041 didSomething |= mServices.attachApplicationLocked(app, processName);
7042 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7043 } catch (Exception e) {
7044 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7049 // Check if a next-broadcast receiver is in this process...
7050 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7052 didSomething |= sendPendingBroadcastsLocked(app);
7053 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7054 } catch (Exception e) {
7055 // If the app died trying to launch the receiver we declare it 'bad'
7056 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7061 // Check whether the next backup agent is in this process...
7062 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7063 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7064 "New app is backup target, launching agent for " + app);
7065 notifyPackageUse(mBackupTarget.appInfo.packageName,
7066 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7068 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7069 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7070 mBackupTarget.backupMode);
7071 } catch (Exception e) {
7072 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7078 app.kill("error during init", true);
7079 handleAppDiedLocked(app, false, true);
7083 if (!didSomething) {
7084 updateOomAdjLocked();
7085 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7092 public final void attachApplication(IApplicationThread thread) {
7093 synchronized (this) {
7094 int callingPid = Binder.getCallingPid();
7095 final long origId = Binder.clearCallingIdentity();
7096 attachApplicationLocked(thread, callingPid);
7097 Binder.restoreCallingIdentity(origId);
7102 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7103 final long origId = Binder.clearCallingIdentity();
7104 synchronized (this) {
7105 ActivityStack stack = ActivityRecord.getStackLocked(token);
7106 if (stack != null) {
7108 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7109 false /* processPausingActivities */, config);
7110 if (stopProfiling) {
7111 if ((mProfileProc == r.app) && (mProfileFd != null)) {
7114 } catch (IOException e) {
7116 clearProfilerLocked();
7121 Binder.restoreCallingIdentity(origId);
7124 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7125 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7126 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7129 void enableScreenAfterBoot() {
7130 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7131 SystemClock.uptimeMillis());
7132 mWindowManager.enableScreenAfterBoot();
7134 synchronized (this) {
7135 updateEventDispatchingLocked();
7140 public void showBootMessage(final CharSequence msg, final boolean always) {
7141 if (Binder.getCallingUid() != myUid()) {
7142 throw new SecurityException();
7144 mWindowManager.showBootMessage(msg, always);
7148 public void keyguardGoingAway(int flags) {
7149 enforceNotIsolatedCaller("keyguardGoingAway");
7150 final long token = Binder.clearCallingIdentity();
7152 synchronized (this) {
7153 mKeyguardController.keyguardGoingAway(flags);
7156 Binder.restoreCallingIdentity(token);
7161 * @return whther the keyguard is currently locked.
7163 boolean isKeyguardLocked() {
7164 return mKeyguardController.isKeyguardLocked();
7167 final void finishBooting() {
7168 synchronized (this) {
7169 if (!mBootAnimationComplete) {
7170 mCallFinishBooting = true;
7173 mCallFinishBooting = false;
7176 ArraySet<String> completedIsas = new ArraySet<String>();
7177 for (String abi : Build.SUPPORTED_ABIS) {
7178 zygoteProcess.establishZygoteConnectionForAbi(abi);
7179 final String instructionSet = VMRuntime.getInstructionSet(abi);
7180 if (!completedIsas.contains(instructionSet)) {
7182 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7183 } catch (InstallerException e) {
7184 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7185 e.getMessage() +")");
7187 completedIsas.add(instructionSet);
7191 IntentFilter pkgFilter = new IntentFilter();
7192 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7193 pkgFilter.addDataScheme("package");
7194 mContext.registerReceiver(new BroadcastReceiver() {
7196 public void onReceive(Context context, Intent intent) {
7197 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7199 for (String pkg : pkgs) {
7200 synchronized (ActivityManagerService.this) {
7201 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7202 0, "query restart")) {
7203 setResultCode(Activity.RESULT_OK);
7212 IntentFilter dumpheapFilter = new IntentFilter();
7213 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7214 mContext.registerReceiver(new BroadcastReceiver() {
7216 public void onReceive(Context context, Intent intent) {
7217 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7218 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7220 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7225 // Let system services know.
7226 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7228 synchronized (this) {
7229 // Ensure that any processes we had put on hold are now started
7231 final int NP = mProcessesOnHold.size();
7233 ArrayList<ProcessRecord> procs =
7234 new ArrayList<ProcessRecord>(mProcessesOnHold);
7235 for (int ip=0; ip<NP; ip++) {
7236 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7238 startProcessLocked(procs.get(ip), "on-hold", null);
7242 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7243 // Start looking for apps that are abusing wake locks.
7244 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7245 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7246 // Tell anyone interested that we are done booting!
7247 SystemProperties.set("sys.boot_completed", "1");
7249 // And trigger dev.bootcomplete if we are not showing encryption progress
7250 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7251 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7252 SystemProperties.set("dev.bootcomplete", "1");
7254 mUserController.sendBootCompletedLocked(
7255 new IIntentReceiver.Stub() {
7257 public void performReceive(Intent intent, int resultCode,
7258 String data, Bundle extras, boolean ordered,
7259 boolean sticky, int sendingUser) {
7260 synchronized (ActivityManagerService.this) {
7261 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7266 scheduleStartProfilesLocked();
7272 public void bootAnimationComplete() {
7273 final boolean callFinishBooting;
7274 synchronized (this) {
7275 callFinishBooting = mCallFinishBooting;
7276 mBootAnimationComplete = true;
7278 if (callFinishBooting) {
7279 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7281 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7285 final void ensureBootCompleted() {
7287 boolean enableScreen;
7288 synchronized (this) {
7291 enableScreen = !mBooted;
7296 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7298 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7302 enableScreenAfterBoot();
7307 public final void activityResumed(IBinder token) {
7308 final long origId = Binder.clearCallingIdentity();
7309 synchronized(this) {
7310 ActivityRecord.activityResumedLocked(token);
7311 mWindowManager.notifyAppResumedFinished(token);
7313 Binder.restoreCallingIdentity(origId);
7317 public final void activityPaused(IBinder token) {
7318 final long origId = Binder.clearCallingIdentity();
7319 synchronized(this) {
7320 ActivityStack stack = ActivityRecord.getStackLocked(token);
7321 if (stack != null) {
7322 stack.activityPausedLocked(token, false);
7325 Binder.restoreCallingIdentity(origId);
7329 public final void activityStopped(IBinder token, Bundle icicle,
7330 PersistableBundle persistentState, CharSequence description) {
7331 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7333 // Refuse possible leaked file descriptors
7334 if (icicle != null && icicle.hasFileDescriptors()) {
7335 throw new IllegalArgumentException("File descriptors passed in Bundle");
7338 final long origId = Binder.clearCallingIdentity();
7340 synchronized (this) {
7341 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7343 r.activityStoppedLocked(icicle, persistentState, description);
7349 Binder.restoreCallingIdentity(origId);
7353 public final void activityDestroyed(IBinder token) {
7354 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7355 synchronized (this) {
7356 ActivityStack stack = ActivityRecord.getStackLocked(token);
7357 if (stack != null) {
7358 stack.activityDestroyedLocked(token, "activityDestroyed");
7364 public final void activityRelaunched(IBinder token) {
7365 final long origId = Binder.clearCallingIdentity();
7366 synchronized (this) {
7367 mStackSupervisor.activityRelaunchedLocked(token);
7369 Binder.restoreCallingIdentity(origId);
7373 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7374 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7375 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7376 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7377 synchronized (this) {
7378 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7379 if (record == null) {
7380 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7381 + "found for: " + token);
7383 record.setSizeConfigurations(horizontalSizeConfiguration,
7384 verticalSizeConfigurations, smallestSizeConfigurations);
7389 public final void backgroundResourcesReleased(IBinder token) {
7390 final long origId = Binder.clearCallingIdentity();
7392 synchronized (this) {
7393 ActivityStack stack = ActivityRecord.getStackLocked(token);
7394 if (stack != null) {
7395 stack.backgroundResourcesReleased();
7399 Binder.restoreCallingIdentity(origId);
7404 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7405 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7409 public final void notifyEnterAnimationComplete(IBinder token) {
7410 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7414 public String getCallingPackage(IBinder token) {
7415 synchronized (this) {
7416 ActivityRecord r = getCallingRecordLocked(token);
7417 return r != null ? r.info.packageName : null;
7422 public ComponentName getCallingActivity(IBinder token) {
7423 synchronized (this) {
7424 ActivityRecord r = getCallingRecordLocked(token);
7425 return r != null ? r.intent.getComponent() : null;
7429 private ActivityRecord getCallingRecordLocked(IBinder token) {
7430 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7438 public ComponentName getActivityClassForToken(IBinder token) {
7439 synchronized(this) {
7440 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7444 return r.intent.getComponent();
7449 public String getPackageForToken(IBinder token) {
7450 synchronized(this) {
7451 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7455 return r.packageName;
7460 public boolean isRootVoiceInteraction(IBinder token) {
7461 synchronized(this) {
7462 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7466 return r.rootVoiceInteraction;
7471 public IIntentSender getIntentSender(int type,
7472 String packageName, IBinder token, String resultWho,
7473 int requestCode, Intent[] intents, String[] resolvedTypes,
7474 int flags, Bundle bOptions, int userId) {
7475 enforceNotIsolatedCaller("getIntentSender");
7476 // Refuse possible leaked file descriptors
7477 if (intents != null) {
7478 if (intents.length < 1) {
7479 throw new IllegalArgumentException("Intents array length must be >= 1");
7481 for (int i=0; i<intents.length; i++) {
7482 Intent intent = intents[i];
7483 if (intent != null) {
7484 if (intent.hasFileDescriptors()) {
7485 throw new IllegalArgumentException("File descriptors passed in Intent");
7487 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7488 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7489 throw new IllegalArgumentException(
7490 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7492 intents[i] = new Intent(intent);
7495 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7496 throw new IllegalArgumentException(
7497 "Intent array length does not match resolvedTypes length");
7500 if (bOptions != null) {
7501 if (bOptions.hasFileDescriptors()) {
7502 throw new IllegalArgumentException("File descriptors passed in options");
7506 synchronized(this) {
7507 int callingUid = Binder.getCallingUid();
7508 int origUserId = userId;
7509 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7510 type == ActivityManager.INTENT_SENDER_BROADCAST,
7511 ALLOW_NON_FULL, "getIntentSender", null);
7512 if (origUserId == UserHandle.USER_CURRENT) {
7513 // We don't want to evaluate this until the pending intent is
7514 // actually executed. However, we do want to always do the
7515 // security checking for it above.
7516 userId = UserHandle.USER_CURRENT;
7519 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7520 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7521 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7522 if (!UserHandle.isSameApp(callingUid, uid)) {
7523 String msg = "Permission Denial: getIntentSender() from pid="
7524 + Binder.getCallingPid()
7525 + ", uid=" + Binder.getCallingUid()
7526 + ", (need uid=" + uid + ")"
7527 + " is not allowed to send as package " + packageName;
7529 throw new SecurityException(msg);
7533 return getIntentSenderLocked(type, packageName, callingUid, userId,
7534 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7536 } catch (RemoteException e) {
7537 throw new SecurityException(e);
7542 IIntentSender getIntentSenderLocked(int type, String packageName,
7543 int callingUid, int userId, IBinder token, String resultWho,
7544 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7546 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7547 ActivityRecord activity = null;
7548 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7549 activity = ActivityRecord.isInStackLocked(token);
7550 if (activity == null) {
7551 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7554 if (activity.finishing) {
7555 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7560 // We're going to be splicing together extras before sending, so we're
7561 // okay poking into any contained extras.
7562 if (intents != null) {
7563 for (int i = 0; i < intents.length; i++) {
7564 intents[i].setDefusable(true);
7567 Bundle.setDefusable(bOptions, true);
7569 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7570 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7571 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7572 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7573 |PendingIntent.FLAG_UPDATE_CURRENT);
7575 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7576 type, packageName, activity, resultWho,
7577 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7578 WeakReference<PendingIntentRecord> ref;
7579 ref = mIntentSenderRecords.get(key);
7580 PendingIntentRecord rec = ref != null ? ref.get() : null;
7582 if (!cancelCurrent) {
7583 if (updateCurrent) {
7584 if (rec.key.requestIntent != null) {
7585 rec.key.requestIntent.replaceExtras(intents != null ?
7586 intents[intents.length - 1] : null);
7588 if (intents != null) {
7589 intents[intents.length-1] = rec.key.requestIntent;
7590 rec.key.allIntents = intents;
7591 rec.key.allResolvedTypes = resolvedTypes;
7593 rec.key.allIntents = null;
7594 rec.key.allResolvedTypes = null;
7599 makeIntentSenderCanceledLocked(rec);
7600 mIntentSenderRecords.remove(key);
7605 rec = new PendingIntentRecord(this, key, callingUid);
7606 mIntentSenderRecords.put(key, rec.ref);
7607 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7608 if (activity.pendingResults == null) {
7609 activity.pendingResults
7610 = new HashSet<WeakReference<PendingIntentRecord>>();
7612 activity.pendingResults.add(rec.ref);
7618 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7619 Intent intent, String resolvedType,
7620 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7621 if (target instanceof PendingIntentRecord) {
7622 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7623 whitelistToken, finishedReceiver, requiredPermission, options);
7625 if (intent == null) {
7626 // Weird case: someone has given us their own custom IIntentSender, and now
7627 // they have someone else trying to send to it but of course this isn't
7628 // really a PendingIntent, so there is no base Intent, and the caller isn't
7629 // supplying an Intent... but we never want to dispatch a null Intent to
7630 // a receiver, so um... let's make something up.
7631 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7632 intent = new Intent(Intent.ACTION_MAIN);
7635 target.send(code, intent, resolvedType, whitelistToken, null,
7636 requiredPermission, options);
7637 } catch (RemoteException e) {
7639 // Platform code can rely on getting a result back when the send is done, but if
7640 // this intent sender is from outside of the system we can't rely on it doing that.
7641 // So instead we don't give it the result receiver, and instead just directly
7642 // report the finish immediately.
7643 if (finishedReceiver != null) {
7645 finishedReceiver.performReceive(intent, 0,
7646 null, null, false, false, UserHandle.getCallingUserId());
7647 } catch (RemoteException e) {
7655 public void cancelIntentSender(IIntentSender sender) {
7656 if (!(sender instanceof PendingIntentRecord)) {
7659 synchronized(this) {
7660 PendingIntentRecord rec = (PendingIntentRecord)sender;
7662 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7663 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7664 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7665 String msg = "Permission Denial: cancelIntentSender() from pid="
7666 + Binder.getCallingPid()
7667 + ", uid=" + Binder.getCallingUid()
7668 + " is not allowed to cancel package "
7669 + rec.key.packageName;
7671 throw new SecurityException(msg);
7673 } catch (RemoteException e) {
7674 throw new SecurityException(e);
7676 cancelIntentSenderLocked(rec, true);
7680 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7681 makeIntentSenderCanceledLocked(rec);
7682 mIntentSenderRecords.remove(rec.key);
7683 if (cleanActivity && rec.key.activity != null) {
7684 rec.key.activity.pendingResults.remove(rec.ref);
7688 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7689 rec.canceled = true;
7690 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7691 if (callbacks != null) {
7692 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7697 public String getPackageForIntentSender(IIntentSender pendingResult) {
7698 if (!(pendingResult instanceof PendingIntentRecord)) {
7702 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7703 return res.key.packageName;
7704 } catch (ClassCastException e) {
7710 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7711 if (!(sender instanceof PendingIntentRecord)) {
7714 synchronized(this) {
7715 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7720 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7721 IResultReceiver receiver) {
7722 if (!(sender instanceof PendingIntentRecord)) {
7725 synchronized(this) {
7726 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7731 public int getUidForIntentSender(IIntentSender sender) {
7732 if (sender instanceof PendingIntentRecord) {
7734 PendingIntentRecord res = (PendingIntentRecord)sender;
7736 } catch (ClassCastException e) {
7743 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7744 if (!(pendingResult instanceof PendingIntentRecord)) {
7748 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7749 if (res.key.allIntents == null) {
7752 for (int i=0; i<res.key.allIntents.length; i++) {
7753 Intent intent = res.key.allIntents[i];
7754 if (intent.getPackage() != null && intent.getComponent() != null) {
7759 } catch (ClassCastException e) {
7765 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7766 if (!(pendingResult instanceof PendingIntentRecord)) {
7770 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7771 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7775 } catch (ClassCastException e) {
7781 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7782 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7783 "getIntentForIntentSender()");
7784 if (!(pendingResult instanceof PendingIntentRecord)) {
7788 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7789 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7790 } catch (ClassCastException e) {
7796 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7797 if (!(pendingResult instanceof PendingIntentRecord)) {
7801 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7802 synchronized (this) {
7803 return getTagForIntentSenderLocked(res, prefix);
7805 } catch (ClassCastException e) {
7810 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7811 final Intent intent = res.key.requestIntent;
7812 if (intent != null) {
7813 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7814 || res.lastTagPrefix.equals(prefix))) {
7817 res.lastTagPrefix = prefix;
7818 final StringBuilder sb = new StringBuilder(128);
7819 if (prefix != null) {
7822 if (intent.getAction() != null) {
7823 sb.append(intent.getAction());
7824 } else if (intent.getComponent() != null) {
7825 intent.getComponent().appendShortString(sb);
7829 return res.lastTag = sb.toString();
7835 public void setProcessLimit(int max) {
7836 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7837 "setProcessLimit()");
7838 synchronized (this) {
7839 mConstants.setOverrideMaxCachedProcesses(max);
7845 public int getProcessLimit() {
7846 synchronized (this) {
7847 return mConstants.getOverrideMaxCachedProcesses();
7851 void importanceTokenDied(ImportanceToken token) {
7852 synchronized (ActivityManagerService.this) {
7853 synchronized (mPidsSelfLocked) {
7855 = mImportantProcesses.get(token.pid);
7859 mImportantProcesses.remove(token.pid);
7860 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7864 pr.forcingToImportant = null;
7865 updateProcessForegroundLocked(pr, false, false);
7867 updateOomAdjLocked();
7872 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7873 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7874 "setProcessImportant()");
7875 synchronized(this) {
7876 boolean changed = false;
7878 synchronized (mPidsSelfLocked) {
7879 ProcessRecord pr = mPidsSelfLocked.get(pid);
7880 if (pr == null && isForeground) {
7881 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7884 ImportanceToken oldToken = mImportantProcesses.get(pid);
7885 if (oldToken != null) {
7886 oldToken.token.unlinkToDeath(oldToken, 0);
7887 mImportantProcesses.remove(pid);
7889 pr.forcingToImportant = null;
7893 if (isForeground && token != null) {
7894 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7896 public void binderDied() {
7897 importanceTokenDied(this);
7901 token.linkToDeath(newToken, 0);
7902 mImportantProcesses.put(pid, newToken);
7903 pr.forcingToImportant = newToken;
7905 } catch (RemoteException e) {
7906 // If the process died while doing this, we will later
7907 // do the cleanup with the process death link.
7913 updateOomAdjLocked();
7919 public boolean isAppForeground(int uid) throws RemoteException {
7920 synchronized (this) {
7921 UidRecord uidRec = mActiveUids.get(uid);
7922 if (uidRec == null || uidRec.idle) {
7925 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7929 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7930 // be guarded by permission checking.
7931 int getUidState(int uid) {
7932 synchronized (this) {
7933 return getUidStateLocked(uid);
7937 int getUidStateLocked(int uid) {
7938 UidRecord uidRec = mActiveUids.get(uid);
7939 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7943 public boolean isInMultiWindowMode(IBinder token) {
7944 final long origId = Binder.clearCallingIdentity();
7946 synchronized(this) {
7947 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7951 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7952 return !r.getTask().mFullscreen;
7955 Binder.restoreCallingIdentity(origId);
7960 public boolean isInPictureInPictureMode(IBinder token) {
7961 final long origId = Binder.clearCallingIdentity();
7963 synchronized(this) {
7964 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7967 Binder.restoreCallingIdentity(origId);
7971 private boolean isInPictureInPictureMode(ActivityRecord r) {
7972 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7973 r.getStack().isInStackLocked(r) == null) {
7977 // If we are animating to fullscreen then we have already dispatched the PIP mode
7978 // changed, so we should reflect that check here as well.
7979 final PinnedActivityStack stack = r.getStack();
7980 final PinnedStackWindowController windowController = stack.getWindowContainerController();
7981 return !windowController.isAnimatingBoundsToFullscreen();
7985 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7986 final long origId = Binder.clearCallingIdentity();
7988 synchronized(this) {
7989 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7990 "enterPictureInPictureMode", token, params);
7992 // If the activity is already in picture in picture mode, then just return early
7993 if (isInPictureInPictureMode(r)) {
7997 // Activity supports picture-in-picture, now check that we can enter PiP at this
7999 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8000 false /* noThrow */, false /* beforeStopping */)) {
8004 final Runnable enterPipRunnable = () -> {
8005 // Only update the saved args from the args that are set
8006 r.pictureInPictureArgs.copyOnlySet(params);
8007 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8008 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8009 // Adjust the source bounds by the insets for the transition down
8010 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8011 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8012 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8013 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8014 stack.setPictureInPictureAspectRatio(aspectRatio);
8015 stack.setPictureInPictureActions(actions);
8017 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8018 r.supportsPictureInPictureWhilePausing);
8019 logPictureInPictureArgs(params);
8022 if (isKeyguardLocked()) {
8023 // If the keyguard is showing or occluded, then try and dismiss it before
8024 // entering picture-in-picture (this will prompt the user to authenticate if the
8025 // device is currently locked).
8027 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8029 public void onDismissError() throws RemoteException {
8034 public void onDismissSucceeded() throws RemoteException {
8035 mHandler.post(enterPipRunnable);
8039 public void onDismissCancelled() throws RemoteException {
8043 } catch (RemoteException e) {
8047 // Enter picture in picture immediately otherwise
8048 enterPipRunnable.run();
8053 Binder.restoreCallingIdentity(origId);
8058 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8059 final long origId = Binder.clearCallingIdentity();
8061 synchronized(this) {
8062 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8063 "setPictureInPictureParams", token, params);
8065 // Only update the saved args from the args that are set
8066 r.pictureInPictureArgs.copyOnlySet(params);
8067 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8068 // If the activity is already in picture-in-picture, update the pinned stack now
8069 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8070 // be used the next time the activity enters PiP
8071 final PinnedActivityStack stack = r.getStack();
8072 if (!stack.isAnimatingBoundsToFullscreen()) {
8073 stack.setPictureInPictureAspectRatio(
8074 r.pictureInPictureArgs.getAspectRatio());
8075 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8078 logPictureInPictureArgs(params);
8081 Binder.restoreCallingIdentity(origId);
8086 public int getMaxNumPictureInPictureActions(IBinder token) {
8087 // Currently, this is a static constant, but later, we may change this to be dependent on
8088 // the context of the activity
8092 private void logPictureInPictureArgs(PictureInPictureParams params) {
8093 if (params.hasSetActions()) {
8094 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8095 params.getActions().size());
8097 if (params.hasSetAspectRatio()) {
8098 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8099 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8100 MetricsLogger.action(lm);
8105 * Checks the state of the system and the activity associated with the given {@param token} to
8106 * verify that picture-in-picture is supported for that activity.
8108 * @return the activity record for the given {@param token} if all the checks pass.
8110 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8111 IBinder token, PictureInPictureParams params) {
8112 if (!mSupportsPictureInPicture) {
8113 throw new IllegalStateException(caller
8114 + ": Device doesn't support picture-in-picture mode.");
8117 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8119 throw new IllegalStateException(caller
8120 + ": Can't find activity for token=" + token);
8123 if (!r.supportsPictureInPicture()) {
8124 throw new IllegalStateException(caller
8125 + ": Current activity does not support picture-in-picture.");
8128 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8129 throw new IllegalStateException(caller
8130 + ": Activities on the home, assistant, or recents stack not supported");
8133 if (params.hasSetAspectRatio()
8134 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8135 params.getAspectRatio())) {
8136 final float minAspectRatio = mContext.getResources().getFloat(
8137 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8138 final float maxAspectRatio = mContext.getResources().getFloat(
8139 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8140 throw new IllegalArgumentException(String.format(caller
8141 + ": Aspect ratio is too extreme (must be between %f and %f).",
8142 minAspectRatio, maxAspectRatio));
8145 // Truncate the number of actions if necessary
8146 params.truncateActions(getMaxNumPictureInPictureActions(token));
8151 // =========================================================
8153 // =========================================================
8155 static class ProcessInfoService extends IProcessInfoService.Stub {
8156 final ActivityManagerService mActivityManagerService;
8157 ProcessInfoService(ActivityManagerService activityManagerService) {
8158 mActivityManagerService = activityManagerService;
8162 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8163 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8164 /*in*/ pids, /*out*/ states, null);
8168 public void getProcessStatesAndOomScoresFromPids(
8169 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8170 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8171 /*in*/ pids, /*out*/ states, /*out*/ scores);
8176 * For each PID in the given input array, write the current process state
8177 * for that process into the states array, or -1 to indicate that no
8178 * process with the given PID exists. If scores array is provided, write
8179 * the oom score for the process into the scores array, with INVALID_ADJ
8180 * indicating the PID doesn't exist.
8182 public void getProcessStatesAndOomScoresForPIDs(
8183 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8184 if (scores != null) {
8185 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8186 "getProcessStatesAndOomScoresForPIDs()");
8190 throw new NullPointerException("pids");
8191 } else if (states == null) {
8192 throw new NullPointerException("states");
8193 } else if (pids.length != states.length) {
8194 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8195 } else if (scores != null && pids.length != scores.length) {
8196 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8199 synchronized (mPidsSelfLocked) {
8200 for (int i = 0; i < pids.length; i++) {
8201 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8202 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8204 if (scores != null) {
8205 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8211 // =========================================================
8213 // =========================================================
8215 static class PermissionController extends IPermissionController.Stub {
8216 ActivityManagerService mActivityManagerService;
8217 PermissionController(ActivityManagerService activityManagerService) {
8218 mActivityManagerService = activityManagerService;
8222 public boolean checkPermission(String permission, int pid, int uid) {
8223 return mActivityManagerService.checkPermission(permission, pid,
8224 uid) == PackageManager.PERMISSION_GRANTED;
8228 public String[] getPackagesForUid(int uid) {
8229 return mActivityManagerService.mContext.getPackageManager()
8230 .getPackagesForUid(uid);
8234 public boolean isRuntimePermission(String permission) {
8236 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8237 .getPermissionInfo(permission, 0);
8238 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8239 == PermissionInfo.PROTECTION_DANGEROUS;
8240 } catch (NameNotFoundException nnfe) {
8241 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8247 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8249 public int checkComponentPermission(String permission, int pid, int uid,
8250 int owningUid, boolean exported) {
8251 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8252 owningUid, exported);
8256 public Object getAMSLock() {
8257 return ActivityManagerService.this;
8262 * This can be called with or without the global lock held.
8264 int checkComponentPermission(String permission, int pid, int uid,
8265 int owningUid, boolean exported) {
8266 if (pid == MY_PID) {
8267 return PackageManager.PERMISSION_GRANTED;
8269 return ActivityManager.checkComponentPermission(permission, uid,
8270 owningUid, exported);
8274 * As the only public entry point for permissions checking, this method
8275 * can enforce the semantic that requesting a check on a null global
8276 * permission is automatically denied. (Internally a null permission
8277 * string is used when calling {@link #checkComponentPermission} in cases
8278 * when only uid-based security is needed.)
8280 * This can be called with or without the global lock held.
8283 public int checkPermission(String permission, int pid, int uid) {
8284 if (permission == null) {
8285 return PackageManager.PERMISSION_DENIED;
8287 return checkComponentPermission(permission, pid, uid, -1, true);
8291 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8292 if (permission == null) {
8293 return PackageManager.PERMISSION_DENIED;
8296 // We might be performing an operation on behalf of an indirect binder
8297 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8298 // client identity accordingly before proceeding.
8299 Identity tlsIdentity = sCallerIdentity.get();
8300 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8301 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8302 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8303 uid = tlsIdentity.uid;
8304 pid = tlsIdentity.pid;
8307 return checkComponentPermission(permission, pid, uid, -1, true);
8311 * Binder IPC calls go through the public entry point.
8312 * This can be called with or without the global lock held.
8314 int checkCallingPermission(String permission) {
8315 return checkPermission(permission,
8316 Binder.getCallingPid(),
8317 UserHandle.getAppId(Binder.getCallingUid()));
8321 * This can be called with or without the global lock held.
8323 void enforceCallingPermission(String permission, String func) {
8324 if (checkCallingPermission(permission)
8325 == PackageManager.PERMISSION_GRANTED) {
8329 String msg = "Permission Denial: " + func + " from pid="
8330 + Binder.getCallingPid()
8331 + ", uid=" + Binder.getCallingUid()
8332 + " requires " + permission;
8334 throw new SecurityException(msg);
8338 * Determine if UID is holding permissions required to access {@link Uri} in
8339 * the given {@link ProviderInfo}. Final permission checking is always done
8340 * in {@link ContentProvider}.
8342 private final boolean checkHoldingPermissionsLocked(
8343 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8344 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8345 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8346 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8347 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8348 != PERMISSION_GRANTED) {
8352 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8355 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8356 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8357 if (pi.applicationInfo.uid == uid) {
8359 } else if (!pi.exported) {
8363 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8364 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8366 // check if target holds top-level <provider> permissions
8367 if (!readMet && pi.readPermission != null && considerUidPermissions
8368 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8371 if (!writeMet && pi.writePermission != null && considerUidPermissions
8372 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8376 // track if unprotected read/write is allowed; any denied
8377 // <path-permission> below removes this ability
8378 boolean allowDefaultRead = pi.readPermission == null;
8379 boolean allowDefaultWrite = pi.writePermission == null;
8381 // check if target holds any <path-permission> that match uri
8382 final PathPermission[] pps = pi.pathPermissions;
8384 final String path = grantUri.uri.getPath();
8386 while (i > 0 && (!readMet || !writeMet)) {
8388 PathPermission pp = pps[i];
8389 if (pp.match(path)) {
8391 final String pprperm = pp.getReadPermission();
8392 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8393 "Checking read perm for " + pprperm + " for " + pp.getPath()
8394 + ": match=" + pp.match(path)
8395 + " check=" + pm.checkUidPermission(pprperm, uid));
8396 if (pprperm != null) {
8397 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8398 == PERMISSION_GRANTED) {
8401 allowDefaultRead = false;
8406 final String ppwperm = pp.getWritePermission();
8407 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8408 "Checking write perm " + ppwperm + " for " + pp.getPath()
8409 + ": match=" + pp.match(path)
8410 + " check=" + pm.checkUidPermission(ppwperm, uid));
8411 if (ppwperm != null) {
8412 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8413 == PERMISSION_GRANTED) {
8416 allowDefaultWrite = false;
8424 // grant unprotected <provider> read/write, if not blocked by
8425 // <path-permission> above
8426 if (allowDefaultRead) readMet = true;
8427 if (allowDefaultWrite) writeMet = true;
8429 } catch (RemoteException e) {
8433 return readMet && writeMet;
8436 public boolean isAppStartModeDisabled(int uid, String packageName) {
8437 synchronized (this) {
8438 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8439 == ActivityManager.APP_START_MODE_DISABLED;
8443 // Unified app-op and target sdk check
8444 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8445 // Apps that target O+ are always subject to background check
8446 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8447 if (DEBUG_BACKGROUND_CHECK) {
8448 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8450 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8452 // ...and legacy apps get an AppOp check
8453 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8455 if (DEBUG_BACKGROUND_CHECK) {
8456 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8459 case AppOpsManager.MODE_ALLOWED:
8460 return ActivityManager.APP_START_MODE_NORMAL;
8461 case AppOpsManager.MODE_IGNORED:
8462 return ActivityManager.APP_START_MODE_DELAYED;
8464 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8468 // Service launch is available to apps with run-in-background exemptions but
8469 // some other background operations are not. If we're doing a check
8470 // of service-launch policy, allow those callers to proceed unrestricted.
8471 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8473 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8474 if (DEBUG_BACKGROUND_CHECK) {
8475 Slog.i(TAG, "App " + uid + "/" + packageName
8476 + " is persistent; not restricted in background");
8478 return ActivityManager.APP_START_MODE_NORMAL;
8481 // Non-persistent but background whitelisted?
8482 if (uidOnBackgroundWhitelist(uid)) {
8483 if (DEBUG_BACKGROUND_CHECK) {
8484 Slog.i(TAG, "App " + uid + "/" + packageName
8485 + " on background whitelist; not restricted in background");
8487 return ActivityManager.APP_START_MODE_NORMAL;
8490 // Is this app on the battery whitelist?
8491 if (isOnDeviceIdleWhitelistLocked(uid)) {
8492 if (DEBUG_BACKGROUND_CHECK) {
8493 Slog.i(TAG, "App " + uid + "/" + packageName
8494 + " on idle whitelist; not restricted in background");
8496 return ActivityManager.APP_START_MODE_NORMAL;
8499 // None of the service-policy criteria apply, so we apply the common criteria
8500 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8503 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8504 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8505 UidRecord uidRec = mActiveUids.get(uid);
8506 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8507 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8508 + (uidRec != null ? uidRec.idle : false));
8509 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8511 if (uidRec == null) {
8512 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8513 UserHandle.getUserId(uid), packageName);
8515 ephemeral = uidRec.ephemeral;
8519 // We are hard-core about ephemeral apps not running in the background.
8520 return ActivityManager.APP_START_MODE_DISABLED;
8523 // The caller is only interested in whether app starts are completely
8524 // disabled for the given package (that is, it is an instant app). So
8525 // we don't need to go further, which is all just seeing if we should
8526 // apply a "delayed" mode for a regular app.
8527 return ActivityManager.APP_START_MODE_NORMAL;
8529 final int startMode = (alwaysRestrict)
8530 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8531 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8533 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8534 + " pkg=" + packageName + " startMode=" + startMode
8535 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8536 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8537 // This is an old app that has been forced into a "compatible as possible"
8538 // mode of background check. To increase compatibility, we will allow other
8539 // foreground apps to cause its services to start.
8540 if (callingPid >= 0) {
8542 synchronized (mPidsSelfLocked) {
8543 proc = mPidsSelfLocked.get(callingPid);
8546 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8547 // Whoever is instigating this is in the foreground, so we will allow it
8549 return ActivityManager.APP_START_MODE_NORMAL;
8556 return ActivityManager.APP_START_MODE_NORMAL;
8559 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8560 final int appId = UserHandle.getAppId(uid);
8561 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8562 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8563 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8566 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8567 ProviderInfo pi = null;
8568 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8573 pi = AppGlobals.getPackageManager().resolveContentProvider(
8574 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8576 } catch (RemoteException ex) {
8582 void grantEphemeralAccessLocked(int userId, Intent intent,
8583 int targetAppId, int ephemeralAppId) {
8584 getPackageManagerInternalLocked().
8585 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8588 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8589 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8590 if (targetUris != null) {
8591 return targetUris.get(grantUri);
8596 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8597 String targetPkg, int targetUid, GrantUri grantUri) {
8598 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8599 if (targetUris == null) {
8600 targetUris = Maps.newArrayMap();
8601 mGrantedUriPermissions.put(targetUid, targetUris);
8604 UriPermission perm = targetUris.get(grantUri);
8606 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8607 targetUris.put(grantUri, perm);
8613 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8614 final int modeFlags) {
8615 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8616 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8617 : UriPermission.STRENGTH_OWNED;
8619 // Root gets to do everything.
8624 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8625 if (perms == null) return false;
8627 // First look for exact match
8628 final UriPermission exactPerm = perms.get(grantUri);
8629 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8633 // No exact match, look for prefixes
8634 final int N = perms.size();
8635 for (int i = 0; i < N; i++) {
8636 final UriPermission perm = perms.valueAt(i);
8637 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8638 && perm.getStrength(modeFlags) >= minStrength) {
8647 * @param uri This uri must NOT contain an embedded userId.
8648 * @param userId The userId in which the uri is to be resolved.
8651 public int checkUriPermission(Uri uri, int pid, int uid,
8652 final int modeFlags, int userId, IBinder callerToken) {
8653 enforceNotIsolatedCaller("checkUriPermission");
8655 // Another redirected-binder-call permissions check as in
8656 // {@link checkPermissionWithToken}.
8657 Identity tlsIdentity = sCallerIdentity.get();
8658 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8659 uid = tlsIdentity.uid;
8660 pid = tlsIdentity.pid;
8663 // Our own process gets to do everything.
8664 if (pid == MY_PID) {
8665 return PackageManager.PERMISSION_GRANTED;
8667 synchronized (this) {
8668 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8669 ? PackageManager.PERMISSION_GRANTED
8670 : PackageManager.PERMISSION_DENIED;
8675 * Check if the targetPkg can be granted permission to access uri by
8676 * the callingUid using the given modeFlags. Throws a security exception
8677 * if callingUid is not allowed to do this. Returns the uid of the target
8678 * if the URI permission grant should be performed; returns -1 if it is not
8679 * needed (for example targetPkg already has permission to access the URI).
8680 * If you already know the uid of the target, you can supply it in
8681 * lastTargetUid else set that to -1.
8683 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8684 final int modeFlags, int lastTargetUid) {
8685 if (!Intent.isAccessUriMode(modeFlags)) {
8689 if (targetPkg != null) {
8690 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8691 "Checking grant " + targetPkg + " permission to " + grantUri);
8694 final IPackageManager pm = AppGlobals.getPackageManager();
8696 // If this is not a content: uri, we can't do anything with it.
8697 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8698 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8699 "Can't grant URI permission for non-content URI: " + grantUri);
8703 // Bail early if system is trying to hand out permissions directly; it
8704 // must always grant permissions on behalf of someone explicit.
8705 final int callingAppId = UserHandle.getAppId(callingUid);
8706 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8707 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8708 // Exempted authority for cropping user photos in Settings app
8710 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8711 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8716 final String authority = grantUri.uri.getAuthority();
8717 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8718 MATCH_DEBUG_TRIAGED_MISSING);
8720 Slog.w(TAG, "No content provider found for permission check: " +
8721 grantUri.uri.toSafeString());
8725 int targetUid = lastTargetUid;
8726 if (targetUid < 0 && targetPkg != null) {
8728 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8729 UserHandle.getUserId(callingUid));
8730 if (targetUid < 0) {
8731 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8732 "Can't grant URI permission no uid for: " + targetPkg);
8735 } catch (RemoteException ex) {
8740 // If we're extending a persistable grant, then we always need to create
8741 // the grant data structure so that take/release APIs work
8742 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8746 if (targetUid >= 0) {
8747 // First... does the target actually need this permission?
8748 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8749 // No need to grant the target this permission.
8750 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8751 "Target " + targetPkg + " already has full permission to " + grantUri);
8755 // First... there is no target package, so can anyone access it?
8756 boolean allowed = pi.exported;
8757 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8758 if (pi.readPermission != null) {
8762 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8763 if (pi.writePermission != null) {
8772 /* There is a special cross user grant if:
8773 * - The target is on another user.
8774 * - Apps on the current user can access the uri without any uid permissions.
8775 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8776 * grant uri permissions.
8778 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8779 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8780 modeFlags, false /*without considering the uid permissions*/);
8782 // Second... is the provider allowing granting of URI permissions?
8783 if (!specialCrossUserGrant) {
8784 if (!pi.grantUriPermissions) {
8785 throw new SecurityException("Provider " + pi.packageName
8787 + " does not allow granting of Uri permissions (uri "
8790 if (pi.uriPermissionPatterns != null) {
8791 final int N = pi.uriPermissionPatterns.length;
8792 boolean allowed = false;
8793 for (int i=0; i<N; i++) {
8794 if (pi.uriPermissionPatterns[i] != null
8795 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8801 throw new SecurityException("Provider " + pi.packageName
8803 + " does not allow granting of permission to path of Uri "
8809 // Third... does the caller itself have permission to access
8811 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8812 // Require they hold a strong enough Uri permission
8813 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8814 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8815 throw new SecurityException(
8816 "UID " + callingUid + " does not have permission to " + grantUri
8817 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8818 + "or related APIs");
8820 throw new SecurityException(
8821 "UID " + callingUid + " does not have permission to " + grantUri);
8829 * @param uri This uri must NOT contain an embedded userId.
8830 * @param userId The userId in which the uri is to be resolved.
8833 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8834 final int modeFlags, int userId) {
8835 enforceNotIsolatedCaller("checkGrantUriPermission");
8836 synchronized(this) {
8837 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8838 new GrantUri(userId, uri, false), modeFlags, -1);
8842 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8843 final int modeFlags, UriPermissionOwner owner) {
8844 if (!Intent.isAccessUriMode(modeFlags)) {
8848 // So here we are: the caller has the assumed permission
8849 // to the uri, and the target doesn't. Let's now give this to
8852 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8853 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8855 final String authority = grantUri.uri.getAuthority();
8856 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8857 MATCH_DEBUG_TRIAGED_MISSING);
8859 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8863 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8864 grantUri.prefix = true;
8866 final UriPermission perm = findOrCreateUriPermissionLocked(
8867 pi.packageName, targetPkg, targetUid, grantUri);
8868 perm.grantModes(modeFlags, owner);
8871 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8872 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8873 if (targetPkg == null) {
8874 throw new NullPointerException("targetPkg");
8877 final IPackageManager pm = AppGlobals.getPackageManager();
8879 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8880 } catch (RemoteException ex) {
8884 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8886 if (targetUid < 0) {
8890 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8894 static class NeededUriGrants extends ArrayList<GrantUri> {
8895 final String targetPkg;
8896 final int targetUid;
8899 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8900 this.targetPkg = targetPkg;
8901 this.targetUid = targetUid;
8907 * Like checkGrantUriPermissionLocked, but takes an Intent.
8909 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8910 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8911 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8912 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8913 + " clip=" + (intent != null ? intent.getClipData() : null)
8914 + " from " + intent + "; flags=0x"
8915 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8917 if (targetPkg == null) {
8918 throw new NullPointerException("targetPkg");
8921 if (intent == null) {
8924 Uri data = intent.getData();
8925 ClipData clip = intent.getClipData();
8926 if (data == null && clip == null) {
8929 // Default userId for uris in the intent (if they don't specify it themselves)
8930 int contentUserHint = intent.getContentUserHint();
8931 if (contentUserHint == UserHandle.USER_CURRENT) {
8932 contentUserHint = UserHandle.getUserId(callingUid);
8934 final IPackageManager pm = AppGlobals.getPackageManager();
8936 if (needed != null) {
8937 targetUid = needed.targetUid;
8940 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8942 } catch (RemoteException ex) {
8945 if (targetUid < 0) {
8946 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8947 "Can't grant URI permission no uid for: " + targetPkg
8948 + " on user " + targetUserId);
8953 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8954 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8956 if (targetUid > 0) {
8957 if (needed == null) {
8958 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8960 needed.add(grantUri);
8964 for (int i=0; i<clip.getItemCount(); i++) {
8965 Uri uri = clip.getItemAt(i).getUri();
8967 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8968 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8970 if (targetUid > 0) {
8971 if (needed == null) {
8972 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8974 needed.add(grantUri);
8977 Intent clipIntent = clip.getItemAt(i).getIntent();
8978 if (clipIntent != null) {
8979 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8980 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8981 if (newNeeded != null) {
8993 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8995 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8996 UriPermissionOwner owner) {
8997 if (needed != null) {
8998 for (int i=0; i<needed.size(); i++) {
8999 GrantUri grantUri = needed.get(i);
9000 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9001 grantUri, needed.flags, owner);
9006 void grantUriPermissionFromIntentLocked(int callingUid,
9007 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9008 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9009 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9010 if (needed == null) {
9014 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9018 * @param uri This uri must NOT contain an embedded userId.
9019 * @param userId The userId in which the uri is to be resolved.
9022 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9023 final int modeFlags, int userId) {
9024 enforceNotIsolatedCaller("grantUriPermission");
9025 GrantUri grantUri = new GrantUri(userId, uri, false);
9026 synchronized(this) {
9027 final ProcessRecord r = getRecordForAppLocked(caller);
9029 throw new SecurityException("Unable to find app for caller "
9031 + " when granting permission to uri " + grantUri);
9033 if (targetPkg == null) {
9034 throw new IllegalArgumentException("null target");
9036 if (grantUri == null) {
9037 throw new IllegalArgumentException("null uri");
9040 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9041 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9042 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9043 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9045 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9046 UserHandle.getUserId(r.uid));
9050 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9051 if (perm.modeFlags == 0) {
9052 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9054 if (perms != null) {
9055 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9056 "Removing " + perm.targetUid + " permission to " + perm.uri);
9058 perms.remove(perm.uri);
9059 if (perms.isEmpty()) {
9060 mGrantedUriPermissions.remove(perm.targetUid);
9066 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9067 final int modeFlags) {
9068 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9069 "Revoking all granted permissions to " + grantUri);
9071 final IPackageManager pm = AppGlobals.getPackageManager();
9072 final String authority = grantUri.uri.getAuthority();
9073 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9074 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9076 Slog.w(TAG, "No content provider found for permission revoke: "
9077 + grantUri.toSafeString());
9081 // Does the caller have this permission on the URI?
9082 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9083 // If they don't have direct access to the URI, then revoke any
9084 // ownerless URI permissions that have been granted to them.
9085 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9086 if (perms != null) {
9087 boolean persistChanged = false;
9088 for (int i = perms.size()-1; i >= 0; i--) {
9089 final UriPermission perm = perms.valueAt(i);
9090 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9093 if (perm.uri.sourceUserId == grantUri.sourceUserId
9094 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9095 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9096 "Revoking non-owned " + perm.targetUid
9097 + " permission to " + perm.uri);
9098 persistChanged |= perm.revokeModes(
9099 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9100 if (perm.modeFlags == 0) {
9105 if (perms.isEmpty()) {
9106 mGrantedUriPermissions.remove(callingUid);
9108 if (persistChanged) {
9109 schedulePersistUriGrants();
9115 boolean persistChanged = false;
9117 // Go through all of the permissions and remove any that match.
9118 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9119 final int targetUid = mGrantedUriPermissions.keyAt(i);
9120 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9122 for (int j = perms.size()-1; j >= 0; j--) {
9123 final UriPermission perm = perms.valueAt(j);
9124 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9127 if (perm.uri.sourceUserId == grantUri.sourceUserId
9128 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9129 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9130 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9131 persistChanged |= perm.revokeModes(
9132 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9133 targetPackage == null);
9134 if (perm.modeFlags == 0) {
9140 if (perms.isEmpty()) {
9141 mGrantedUriPermissions.removeAt(i);
9145 if (persistChanged) {
9146 schedulePersistUriGrants();
9151 * @param uri This uri must NOT contain an embedded userId.
9152 * @param userId The userId in which the uri is to be resolved.
9155 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9156 final int modeFlags, int userId) {
9157 enforceNotIsolatedCaller("revokeUriPermission");
9158 synchronized(this) {
9159 final ProcessRecord r = getRecordForAppLocked(caller);
9161 throw new SecurityException("Unable to find app for caller "
9163 + " when revoking permission to uri " + uri);
9166 Slog.w(TAG, "revokeUriPermission: null uri");
9170 if (!Intent.isAccessUriMode(modeFlags)) {
9174 final String authority = uri.getAuthority();
9175 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9176 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9178 Slog.w(TAG, "No content provider found for permission revoke: "
9179 + uri.toSafeString());
9183 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9189 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9192 * @param packageName Package name to match, or {@code null} to apply to all
9194 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9196 * @param persistable If persistable grants should be removed.
9198 private void removeUriPermissionsForPackageLocked(
9199 String packageName, int userHandle, boolean persistable) {
9200 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9201 throw new IllegalArgumentException("Must narrow by either package or user");
9204 boolean persistChanged = false;
9206 int N = mGrantedUriPermissions.size();
9207 for (int i = 0; i < N; i++) {
9208 final int targetUid = mGrantedUriPermissions.keyAt(i);
9209 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9211 // Only inspect grants matching user
9212 if (userHandle == UserHandle.USER_ALL
9213 || userHandle == UserHandle.getUserId(targetUid)) {
9214 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9215 final UriPermission perm = it.next();
9217 // Only inspect grants matching package
9218 if (packageName == null || perm.sourcePkg.equals(packageName)
9219 || perm.targetPkg.equals(packageName)) {
9220 // Hacky solution as part of fixing a security bug; ignore
9221 // grants associated with DownloadManager so we don't have
9222 // to immediately launch it to regrant the permissions
9223 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9224 && !persistable) continue;
9226 persistChanged |= perm.revokeModes(persistable
9227 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9229 // Only remove when no modes remain; any persisted grants
9230 // will keep this alive.
9231 if (perm.modeFlags == 0) {
9237 if (perms.isEmpty()) {
9238 mGrantedUriPermissions.remove(targetUid);
9245 if (persistChanged) {
9246 schedulePersistUriGrants();
9251 public IBinder newUriPermissionOwner(String name) {
9252 enforceNotIsolatedCaller("newUriPermissionOwner");
9253 synchronized(this) {
9254 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9255 return owner.getExternalTokenLocked();
9260 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9261 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9262 synchronized(this) {
9263 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9265 throw new IllegalArgumentException("Activity does not exist; token="
9268 return r.getUriPermissionsLocked().getExternalTokenLocked();
9272 * @param uri This uri must NOT contain an embedded userId.
9273 * @param sourceUserId The userId in which the uri is to be resolved.
9274 * @param targetUserId The userId of the app that receives the grant.
9277 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9278 final int modeFlags, int sourceUserId, int targetUserId) {
9279 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9280 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9281 "grantUriPermissionFromOwner", null);
9282 synchronized(this) {
9283 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9284 if (owner == null) {
9285 throw new IllegalArgumentException("Unknown owner: " + token);
9287 if (fromUid != Binder.getCallingUid()) {
9288 if (Binder.getCallingUid() != myUid()) {
9289 // Only system code can grant URI permissions on behalf
9291 throw new SecurityException("nice try");
9294 if (targetPkg == null) {
9295 throw new IllegalArgumentException("null target");
9298 throw new IllegalArgumentException("null uri");
9301 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9302 modeFlags, owner, targetUserId);
9307 * @param uri This uri must NOT contain an embedded userId.
9308 * @param userId The userId in which the uri is to be resolved.
9311 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9312 synchronized(this) {
9313 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9314 if (owner == null) {
9315 throw new IllegalArgumentException("Unknown owner: " + token);
9319 owner.removeUriPermissionsLocked(mode);
9321 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9322 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9327 private void schedulePersistUriGrants() {
9328 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9329 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9330 10 * DateUtils.SECOND_IN_MILLIS);
9334 private void writeGrantedUriPermissions() {
9335 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9337 // Snapshot permissions so we can persist without lock
9338 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9339 synchronized (this) {
9340 final int size = mGrantedUriPermissions.size();
9341 for (int i = 0; i < size; i++) {
9342 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9343 for (UriPermission perm : perms.values()) {
9344 if (perm.persistedModeFlags != 0) {
9345 persist.add(perm.snapshot());
9351 FileOutputStream fos = null;
9353 fos = mGrantFile.startWrite();
9355 XmlSerializer out = new FastXmlSerializer();
9356 out.setOutput(fos, StandardCharsets.UTF_8.name());
9357 out.startDocument(null, true);
9358 out.startTag(null, TAG_URI_GRANTS);
9359 for (UriPermission.Snapshot perm : persist) {
9360 out.startTag(null, TAG_URI_GRANT);
9361 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9362 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9363 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9364 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9365 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9366 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9367 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9368 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9369 out.endTag(null, TAG_URI_GRANT);
9371 out.endTag(null, TAG_URI_GRANTS);
9374 mGrantFile.finishWrite(fos);
9375 } catch (IOException e) {
9377 mGrantFile.failWrite(fos);
9382 private void readGrantedUriPermissionsLocked() {
9383 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9385 final long now = System.currentTimeMillis();
9387 FileInputStream fis = null;
9389 fis = mGrantFile.openRead();
9390 final XmlPullParser in = Xml.newPullParser();
9391 in.setInput(fis, StandardCharsets.UTF_8.name());
9394 while ((type = in.next()) != END_DOCUMENT) {
9395 final String tag = in.getName();
9396 if (type == START_TAG) {
9397 if (TAG_URI_GRANT.equals(tag)) {
9398 final int sourceUserId;
9399 final int targetUserId;
9400 final int userHandle = readIntAttribute(in,
9401 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9402 if (userHandle != UserHandle.USER_NULL) {
9403 // For backwards compatibility.
9404 sourceUserId = userHandle;
9405 targetUserId = userHandle;
9407 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9408 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9410 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9411 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9412 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9413 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9414 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9415 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9417 // Sanity check that provider still belongs to source package
9418 // Both direct boot aware and unaware packages are fine as we
9419 // will do filtering at query time to avoid multiple parsing.
9420 final ProviderInfo pi = getProviderInfoLocked(
9421 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9422 | MATCH_DIRECT_BOOT_UNAWARE);
9423 if (pi != null && sourcePkg.equals(pi.packageName)) {
9426 targetUid = AppGlobals.getPackageManager().getPackageUid(
9427 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9428 } catch (RemoteException e) {
9430 if (targetUid != -1) {
9431 final UriPermission perm = findOrCreateUriPermissionLocked(
9432 sourcePkg, targetPkg, targetUid,
9433 new GrantUri(sourceUserId, uri, prefix));
9434 perm.initPersistedModes(modeFlags, createdTime);
9437 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9438 + " but instead found " + pi);
9443 } catch (FileNotFoundException e) {
9444 // Missing grants is okay
9445 } catch (IOException e) {
9446 Slog.wtf(TAG, "Failed reading Uri grants", e);
9447 } catch (XmlPullParserException e) {
9448 Slog.wtf(TAG, "Failed reading Uri grants", e);
9450 IoUtils.closeQuietly(fis);
9455 * @param uri This uri must NOT contain an embedded userId.
9456 * @param userId The userId in which the uri is to be resolved.
9459 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9460 enforceNotIsolatedCaller("takePersistableUriPermission");
9462 Preconditions.checkFlagsArgument(modeFlags,
9463 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9465 synchronized (this) {
9466 final int callingUid = Binder.getCallingUid();
9467 boolean persistChanged = false;
9468 GrantUri grantUri = new GrantUri(userId, uri, false);
9470 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9471 new GrantUri(userId, uri, false));
9472 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9473 new GrantUri(userId, uri, true));
9475 final boolean exactValid = (exactPerm != null)
9476 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9477 final boolean prefixValid = (prefixPerm != null)
9478 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9480 if (!(exactValid || prefixValid)) {
9481 throw new SecurityException("No persistable permission grants found for UID "
9482 + callingUid + " and Uri " + grantUri.toSafeString());
9486 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9489 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9492 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9494 if (persistChanged) {
9495 schedulePersistUriGrants();
9501 * @param uri This uri must NOT contain an embedded userId.
9502 * @param userId The userId in which the uri is to be resolved.
9505 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9506 enforceNotIsolatedCaller("releasePersistableUriPermission");
9508 Preconditions.checkFlagsArgument(modeFlags,
9509 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9511 synchronized (this) {
9512 final int callingUid = Binder.getCallingUid();
9513 boolean persistChanged = false;
9515 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9516 new GrantUri(userId, uri, false));
9517 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9518 new GrantUri(userId, uri, true));
9519 if (exactPerm == null && prefixPerm == null) {
9520 throw new SecurityException("No permission grants found for UID " + callingUid
9521 + " and Uri " + uri.toSafeString());
9524 if (exactPerm != null) {
9525 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9526 removeUriPermissionIfNeededLocked(exactPerm);
9528 if (prefixPerm != null) {
9529 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9530 removeUriPermissionIfNeededLocked(prefixPerm);
9533 if (persistChanged) {
9534 schedulePersistUriGrants();
9540 * Prune any older {@link UriPermission} for the given UID until outstanding
9541 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9543 * @return if any mutations occured that require persisting.
9545 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9546 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9547 if (perms == null) return false;
9548 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9550 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9551 for (UriPermission perm : perms.values()) {
9552 if (perm.persistedModeFlags != 0) {
9553 persisted.add(perm);
9557 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9558 if (trimCount <= 0) return false;
9560 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9561 for (int i = 0; i < trimCount; i++) {
9562 final UriPermission perm = persisted.get(i);
9564 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9565 "Trimming grant created at " + perm.persistedCreateTime);
9567 perm.releasePersistableModes(~0);
9568 removeUriPermissionIfNeededLocked(perm);
9575 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9576 String packageName, boolean incoming) {
9577 enforceNotIsolatedCaller("getPersistedUriPermissions");
9578 Preconditions.checkNotNull(packageName, "packageName");
9580 final int callingUid = Binder.getCallingUid();
9581 final int callingUserId = UserHandle.getUserId(callingUid);
9582 final IPackageManager pm = AppGlobals.getPackageManager();
9584 final int packageUid = pm.getPackageUid(packageName,
9585 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9586 if (packageUid != callingUid) {
9587 throw new SecurityException(
9588 "Package " + packageName + " does not belong to calling UID " + callingUid);
9590 } catch (RemoteException e) {
9591 throw new SecurityException("Failed to verify package name ownership");
9594 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9595 synchronized (this) {
9597 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9599 if (perms == null) {
9600 Slog.w(TAG, "No permission grants found for " + packageName);
9602 for (UriPermission perm : perms.values()) {
9603 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9604 result.add(perm.buildPersistedPublicApiObject());
9609 final int size = mGrantedUriPermissions.size();
9610 for (int i = 0; i < size; i++) {
9611 final ArrayMap<GrantUri, UriPermission> perms =
9612 mGrantedUriPermissions.valueAt(i);
9613 for (UriPermission perm : perms.values()) {
9614 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9615 result.add(perm.buildPersistedPublicApiObject());
9621 return new ParceledListSlice<android.content.UriPermission>(result);
9625 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9626 String packageName, int userId) {
9627 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9628 "getGrantedUriPermissions");
9630 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9631 synchronized (this) {
9632 final int size = mGrantedUriPermissions.size();
9633 for (int i = 0; i < size; i++) {
9634 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9635 for (UriPermission perm : perms.values()) {
9636 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9637 && perm.persistedModeFlags != 0) {
9638 result.add(perm.buildPersistedPublicApiObject());
9643 return new ParceledListSlice<android.content.UriPermission>(result);
9647 public void clearGrantedUriPermissions(String packageName, int userId) {
9648 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9649 "clearGrantedUriPermissions");
9650 removeUriPermissionsForPackageLocked(packageName, userId, true);
9654 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9655 synchronized (this) {
9657 who != null ? getRecordForAppLocked(who) : null;
9658 if (app == null) return;
9660 Message msg = Message.obtain();
9661 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9663 msg.arg1 = waiting ? 1 : 0;
9664 mUiHandler.sendMessage(msg);
9669 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9670 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9671 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9672 outInfo.availMem = getFreeMemory();
9673 outInfo.totalMem = getTotalMemory();
9674 outInfo.threshold = homeAppMem;
9675 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9676 outInfo.hiddenAppThreshold = cachedAppMem;
9677 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9678 ProcessList.SERVICE_ADJ);
9679 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9680 ProcessList.VISIBLE_APP_ADJ);
9681 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9682 ProcessList.FOREGROUND_APP_ADJ);
9685 // =========================================================
9687 // =========================================================
9690 public List<IBinder> getAppTasks(String callingPackage) {
9691 int callingUid = Binder.getCallingUid();
9692 long ident = Binder.clearCallingIdentity();
9694 synchronized(this) {
9695 ArrayList<IBinder> list = new ArrayList<IBinder>();
9697 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9699 final int N = mRecentTasks.size();
9700 for (int i = 0; i < N; i++) {
9701 TaskRecord tr = mRecentTasks.get(i);
9702 // Skip tasks that do not match the caller. We don't need to verify
9703 // callingPackage, because we are also limiting to callingUid and know
9704 // that will limit to the correct security sandbox.
9705 if (tr.effectiveUid != callingUid) {
9708 Intent intent = tr.getBaseIntent();
9709 if (intent == null ||
9710 !callingPackage.equals(intent.getComponent().getPackageName())) {
9713 ActivityManager.RecentTaskInfo taskInfo =
9714 createRecentTaskInfoFromTaskRecord(tr);
9715 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9716 list.add(taskImpl.asBinder());
9719 Binder.restoreCallingIdentity(ident);
9726 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9727 final int callingUid = Binder.getCallingUid();
9728 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9730 synchronized(this) {
9731 if (DEBUG_ALL) Slog.v(
9732 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9734 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9737 // TODO: Improve with MRU list from all ActivityStacks.
9738 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9745 * Creates a new RecentTaskInfo from a TaskRecord.
9747 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9748 // Update the task description to reflect any changes in the task stack
9749 tr.updateTaskDescription();
9751 // Compose the recent task info
9752 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9753 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9754 rti.persistentId = tr.taskId;
9755 rti.baseIntent = new Intent(tr.getBaseIntent());
9756 rti.origActivity = tr.origActivity;
9757 rti.realActivity = tr.realActivity;
9758 rti.description = tr.lastDescription;
9759 rti.stackId = tr.getStackId();
9760 rti.userId = tr.userId;
9761 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9762 rti.firstActiveTime = tr.firstActiveTime;
9763 rti.lastActiveTime = tr.lastActiveTime;
9764 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9765 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9766 rti.numActivities = 0;
9767 if (tr.mBounds != null) {
9768 rti.bounds = new Rect(tr.mBounds);
9770 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9771 rti.resizeMode = tr.mResizeMode;
9773 ActivityRecord base = null;
9774 ActivityRecord top = null;
9777 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9778 tmp = tr.mActivities.get(i);
9779 if (tmp.finishing) {
9783 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9786 rti.numActivities++;
9789 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9790 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9795 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9796 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9797 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9799 if (checkPermission(android.Manifest.permission.GET_TASKS,
9800 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9801 // Temporary compatibility: some existing apps on the system image may
9802 // still be requesting the old permission and not switched to the new
9803 // one; if so, we'll still allow them full access. This means we need
9804 // to see if they are holding the old permission and are a system app.
9806 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9808 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9809 + " is using old GET_TASKS but privileged; allowing");
9811 } catch (RemoteException e) {
9816 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9817 + " does not hold REAL_GET_TASKS; limiting output");
9823 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9825 final int callingUid = Binder.getCallingUid();
9826 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9827 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9829 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9830 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9831 synchronized (this) {
9832 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9834 final boolean detailed = checkCallingPermission(
9835 android.Manifest.permission.GET_DETAILED_TASKS)
9836 == PackageManager.PERMISSION_GRANTED;
9838 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9839 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9840 return ParceledListSlice.emptyList();
9842 mRecentTasks.loadUserRecentsLocked(userId);
9844 final int recentsCount = mRecentTasks.size();
9845 ArrayList<ActivityManager.RecentTaskInfo> res =
9846 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9848 final Set<Integer> includedUsers;
9849 if (includeProfiles) {
9850 includedUsers = mUserController.getProfileIds(userId);
9852 includedUsers = new HashSet<>();
9854 includedUsers.add(Integer.valueOf(userId));
9856 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9857 TaskRecord tr = mRecentTasks.get(i);
9858 // Only add calling user or related users recent tasks
9859 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9860 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9864 if (tr.realActivitySuspended) {
9865 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9869 // Return the entry if desired by the caller. We always return
9870 // the first entry, because callers always expect this to be the
9871 // foreground app. We may filter others if the caller has
9872 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9873 // we should exclude the entry.
9877 || (tr.intent == null)
9878 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9881 // If the caller doesn't have the GET_TASKS permission, then only
9882 // allow them to see a small subset of tasks -- their own and home.
9883 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9884 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9888 final ActivityStack stack = tr.getStack();
9889 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9890 if (stack != null && stack.isHomeOrRecentsStack()) {
9891 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9892 "Skipping, home or recents stack task: " + tr);
9896 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9897 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9898 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9899 "Skipping, top task in docked stack: " + tr);
9903 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9904 if (stack != null && stack.isPinnedStack()) {
9905 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9906 "Skipping, pinned stack task: " + tr);
9910 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9911 // Don't include auto remove tasks that are finished or finishing.
9912 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9913 "Skipping, auto-remove without activity: " + tr);
9916 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9917 && !tr.isAvailable) {
9918 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9919 "Skipping, unavail real act: " + tr);
9923 if (!tr.mUserSetupComplete) {
9924 // Don't include task launched while user is not done setting-up.
9925 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9926 "Skipping, user setup not complete: " + tr);
9930 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9932 rti.baseIntent.replaceExtras((Bundle)null);
9939 return new ParceledListSlice<>(res);
9944 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9945 synchronized (this) {
9946 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9947 "getTaskThumbnail()");
9948 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9949 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9951 return tr.getTaskThumbnailLocked();
9958 public ActivityManager.TaskDescription getTaskDescription(int id) {
9959 synchronized (this) {
9960 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9961 "getTaskDescription()");
9962 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9963 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9965 return tr.lastTaskDescription;
9972 public int addAppTask(IBinder activityToken, Intent intent,
9973 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9974 final int callingUid = Binder.getCallingUid();
9975 final long callingIdent = Binder.clearCallingIdentity();
9978 synchronized (this) {
9979 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9981 throw new IllegalArgumentException("Activity does not exist; token="
9984 ComponentName comp = intent.getComponent();
9986 throw new IllegalArgumentException("Intent " + intent
9987 + " must specify explicit component");
9989 if (thumbnail.getWidth() != mThumbnailWidth
9990 || thumbnail.getHeight() != mThumbnailHeight) {
9991 throw new IllegalArgumentException("Bad thumbnail size: got "
9992 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9993 + mThumbnailWidth + "x" + mThumbnailHeight);
9995 if (intent.getSelector() != null) {
9996 intent.setSelector(null);
9998 if (intent.getSourceBounds() != null) {
9999 intent.setSourceBounds(null);
10001 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10002 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10003 // The caller has added this as an auto-remove task... that makes no
10004 // sense, so turn off auto-remove.
10005 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10008 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10009 mLastAddedTaskActivity = null;
10011 ActivityInfo ainfo = mLastAddedTaskActivity;
10012 if (ainfo == null) {
10013 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10014 comp, 0, UserHandle.getUserId(callingUid));
10015 if (ainfo.applicationInfo.uid != callingUid) {
10016 throw new SecurityException(
10017 "Can't add task for another application: target uid="
10018 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10022 TaskRecord task = new TaskRecord(this,
10023 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10024 ainfo, intent, description, new TaskThumbnailInfo());
10026 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10027 if (trimIdx >= 0) {
10028 // If this would have caused a trim, then we'll abort because that
10029 // means it would be added at the end of the list but then just removed.
10030 return INVALID_TASK_ID;
10033 final int N = mRecentTasks.size();
10034 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10035 final TaskRecord tr = mRecentTasks.remove(N - 1);
10036 tr.removedFromRecents();
10039 task.inRecents = true;
10040 mRecentTasks.add(task);
10041 r.getStack().addTask(task, false, "addAppTask");
10043 task.setLastThumbnailLocked(thumbnail);
10044 task.freeLastThumbnail();
10045 return task.taskId;
10048 Binder.restoreCallingIdentity(callingIdent);
10053 public Point getAppTaskThumbnailSize() {
10054 synchronized (this) {
10055 return new Point(mThumbnailWidth, mThumbnailHeight);
10060 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10061 synchronized (this) {
10062 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10064 r.setTaskDescription(td);
10065 final TaskRecord task = r.getTask();
10066 task.updateTaskDescription();
10067 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10073 public void setTaskResizeable(int taskId, int resizeableMode) {
10074 synchronized (this) {
10075 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10076 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10077 if (task == null) {
10078 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10081 task.setResizeMode(resizeableMode);
10086 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10087 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10088 long ident = Binder.clearCallingIdentity();
10090 synchronized (this) {
10091 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10092 if (task == null) {
10093 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10096 // Place the task in the right stack if it isn't there already based on
10097 // the requested bounds.
10098 // The stack transition logic is:
10099 // - a null bounds on a freeform task moves that task to fullscreen
10100 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10101 // that task to freeform
10102 // - otherwise the task is not moved
10103 int stackId = task.getStackId();
10104 if (!StackId.isTaskResizeAllowed(stackId)) {
10105 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10107 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10108 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10109 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10110 stackId = FREEFORM_WORKSPACE_STACK_ID;
10113 // Reparent the task to the right stack if necessary
10114 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10115 if (stackId != task.getStackId()) {
10116 // Defer resume until the task is resized below
10117 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10118 DEFER_RESUME, "resizeTask");
10119 preserveWindow = false;
10122 // After reparenting (which only resizes the task to the stack bounds), resize the
10123 // task to the actual bounds provided
10124 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10127 Binder.restoreCallingIdentity(ident);
10132 public Rect getTaskBounds(int taskId) {
10133 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10134 long ident = Binder.clearCallingIdentity();
10135 Rect rect = new Rect();
10137 synchronized (this) {
10138 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10139 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10140 if (task == null) {
10141 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10144 if (task.getStack() != null) {
10145 // Return the bounds from window manager since it will be adjusted for various
10146 // things like the presense of a docked stack for tasks that aren't resizeable.
10147 task.getWindowContainerBounds(rect);
10149 // Task isn't in window manager yet since it isn't associated with a stack.
10150 // Return the persist value from activity manager
10151 if (task.mBounds != null) {
10152 rect.set(task.mBounds);
10153 } else if (task.mLastNonFullscreenBounds != null) {
10154 rect.set(task.mLastNonFullscreenBounds);
10159 Binder.restoreCallingIdentity(ident);
10165 public void cancelTaskWindowTransition(int taskId) {
10166 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10167 final long ident = Binder.clearCallingIdentity();
10169 synchronized (this) {
10170 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10171 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10172 if (task == null) {
10173 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10176 task.cancelWindowTransition();
10179 Binder.restoreCallingIdentity(ident);
10184 public void cancelTaskThumbnailTransition(int taskId) {
10185 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10186 final long ident = Binder.clearCallingIdentity();
10188 synchronized (this) {
10189 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10190 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10191 if (task == null) {
10192 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10195 task.cancelThumbnailTransition();
10198 Binder.restoreCallingIdentity(ident);
10203 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10204 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10205 final long ident = Binder.clearCallingIdentity();
10207 final TaskRecord task;
10208 synchronized (this) {
10209 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10210 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10211 if (task == null) {
10212 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10216 // Don't call this while holding the lock as this operation might hit the disk.
10217 return task.getSnapshot(reducedResolution);
10219 Binder.restoreCallingIdentity(ident);
10224 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10225 if (userId != UserHandle.getCallingUserId()) {
10226 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10227 "getTaskDescriptionIcon");
10229 final File passedIconFile = new File(filePath);
10230 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10231 passedIconFile.getName());
10232 if (!legitIconFile.getPath().equals(filePath)
10233 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10234 throw new IllegalArgumentException("Bad file path: " + filePath
10235 + " passed for userId " + userId);
10237 return mRecentTasks.getTaskDescriptionIcon(filePath);
10241 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10242 throws RemoteException {
10243 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10244 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10245 activityOptions.getCustomInPlaceResId() == 0) {
10246 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10247 "with valid animation");
10249 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10250 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10251 activityOptions.getCustomInPlaceResId());
10252 mWindowManager.executeAppTransition();
10255 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10256 // Remove all tasks with activities in the specified package from the list of recent tasks
10257 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10258 TaskRecord tr = mRecentTasks.get(i);
10259 if (tr.userId != userId) continue;
10261 ComponentName cn = tr.intent.getComponent();
10262 if (cn != null && cn.getPackageName().equals(packageName)) {
10263 // If the package name matches, remove the task.
10264 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10269 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10272 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10273 TaskRecord tr = mRecentTasks.get(i);
10274 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10278 ComponentName cn = tr.intent.getComponent();
10279 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10280 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10281 if (sameComponent) {
10282 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10288 public void removeStack(int stackId) {
10289 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10290 if (StackId.isHomeOrRecentsStack(stackId)) {
10291 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10294 synchronized (this) {
10295 final long ident = Binder.clearCallingIdentity();
10297 mStackSupervisor.removeStackLocked(stackId);
10299 Binder.restoreCallingIdentity(ident);
10305 public void moveStackToDisplay(int stackId, int displayId) {
10306 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10308 synchronized (this) {
10309 final long ident = Binder.clearCallingIdentity();
10311 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10312 + " to displayId=" + displayId);
10313 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10315 Binder.restoreCallingIdentity(ident);
10321 public boolean removeTask(int taskId) {
10322 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10323 synchronized (this) {
10324 final long ident = Binder.clearCallingIdentity();
10326 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10328 Binder.restoreCallingIdentity(ident);
10334 * TODO: Add mController hook
10337 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10338 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10340 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10341 synchronized(this) {
10342 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10346 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10347 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10349 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10350 Binder.getCallingUid(), -1, -1, "Task to front")) {
10351 ActivityOptions.abort(options);
10354 final long origId = Binder.clearCallingIdentity();
10356 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10357 if (task == null) {
10358 Slog.d(TAG, "Could not find task for id: "+ taskId);
10361 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10362 mStackSupervisor.showLockTaskToast();
10363 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10366 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10367 if (prev != null) {
10368 task.setTaskToReturnTo(prev);
10370 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10371 false /* forceNonResizable */);
10373 final ActivityRecord topActivity = task.getTopActivity();
10374 if (topActivity != null) {
10376 // We are reshowing a task, use a starting window to hide the initial draw delay
10377 // so the transition can start earlier.
10378 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10379 true /* taskSwitch */, fromRecents);
10382 Binder.restoreCallingIdentity(origId);
10384 ActivityOptions.abort(options);
10388 * Attempts to move a task backwards in z-order (the order of activities within the task is
10391 * There are several possible results of this call:
10392 * - if the task is locked, then we will show the lock toast
10393 * - if there is a task behind the provided task, then that task is made visible and resumed as
10394 * this task is moved to the back
10395 * - otherwise, if there are no other tasks in the stack:
10396 * - if this task is in the pinned stack, then we remove the stack completely, which will
10397 * have the effect of moving the task to the top or bottom of the fullscreen stack
10398 * (depending on whether it is visible)
10399 * - otherwise, we simply return home and hide this task
10401 * @param token A reference to the activity we wish to move
10402 * @param nonRoot If false then this only works if the activity is the root
10403 * of a task; if true it will work for any activity in a task.
10404 * @return Returns true if the move completed, false if not.
10407 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10408 enforceNotIsolatedCaller("moveActivityTaskToBack");
10409 synchronized(this) {
10410 final long origId = Binder.clearCallingIdentity();
10412 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10413 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10414 if (task != null) {
10415 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10418 Binder.restoreCallingIdentity(origId);
10425 public void moveTaskBackwards(int task) {
10426 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10427 "moveTaskBackwards()");
10429 synchronized(this) {
10430 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10431 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10434 final long origId = Binder.clearCallingIdentity();
10435 moveTaskBackwardsLocked(task);
10436 Binder.restoreCallingIdentity(origId);
10440 private final void moveTaskBackwardsLocked(int task) {
10441 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10445 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10446 IActivityContainerCallback callback) throws RemoteException {
10447 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10448 synchronized (this) {
10449 if (parentActivityToken == null) {
10450 throw new IllegalArgumentException("parent token must not be null");
10452 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10456 if (callback == null) {
10457 throw new IllegalArgumentException("callback must not be null");
10459 return mStackSupervisor.createVirtualActivityContainer(r, callback);
10464 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10465 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10466 synchronized (this) {
10467 final int stackId = mStackSupervisor.getNextStackId();
10468 final ActivityStack stack =
10469 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10470 if (stack == null) {
10473 return stack.mActivityContainer;
10478 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10479 synchronized (this) {
10480 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10481 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10482 return stack.mActivityContainer.getDisplayId();
10484 return DEFAULT_DISPLAY;
10489 public int getActivityStackId(IBinder token) throws RemoteException {
10490 synchronized (this) {
10491 ActivityStack stack = ActivityRecord.getStackLocked(token);
10492 if (stack == null) {
10493 return INVALID_STACK_ID;
10495 return stack.mStackId;
10500 public void exitFreeformMode(IBinder token) throws RemoteException {
10501 synchronized (this) {
10502 long ident = Binder.clearCallingIdentity();
10504 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10506 throw new IllegalArgumentException(
10507 "exitFreeformMode: No activity record matching token=" + token);
10510 final ActivityStack stack = r.getStack();
10511 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10512 throw new IllegalStateException(
10513 "exitFreeformMode: You can only go fullscreen from freeform.");
10516 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10517 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10518 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10520 Binder.restoreCallingIdentity(ident);
10526 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10527 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10528 if (StackId.isHomeOrRecentsStack(stackId)) {
10529 throw new IllegalArgumentException(
10530 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10532 synchronized (this) {
10533 long ident = Binder.clearCallingIdentity();
10535 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10536 if (task == null) {
10537 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10541 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10542 + " to stackId=" + stackId + " toTop=" + toTop);
10543 if (stackId == DOCKED_STACK_ID) {
10544 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10545 null /* initialBounds */);
10547 task.reparent(stackId, toTop,
10548 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10550 Binder.restoreCallingIdentity(ident);
10556 public void swapDockedAndFullscreenStack() throws RemoteException {
10557 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10558 synchronized (this) {
10559 long ident = Binder.clearCallingIdentity();
10561 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10562 FULLSCREEN_WORKSPACE_STACK_ID);
10563 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10565 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10566 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10568 if (topTask == null || tasks == null || tasks.size() == 0) {
10570 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10574 // TODO: App transition
10575 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10577 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10578 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10579 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10580 final int size = tasks.size();
10581 for (int i = 0; i < size; i++) {
10582 final int id = tasks.get(i).taskId;
10583 if (id == topTask.taskId) {
10587 // Defer the resume until after all the tasks have been moved
10588 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10589 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10590 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10593 // Because we deferred the resume to avoid conflicts with stack switches while
10594 // resuming, we need to do it after all the tasks are moved.
10595 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10596 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10598 mWindowManager.executeAppTransition();
10600 Binder.restoreCallingIdentity(ident);
10606 * Moves the input task to the docked stack.
10608 * @param taskId Id of task to move.
10609 * @param createMode The mode the docked stack should be created in if it doesn't exist
10611 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10613 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10614 * @param toTop If the task and stack should be moved to the top.
10615 * @param animate Whether we should play an animation for the moving the task
10616 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10617 * docked stack. Pass {@code null} to use default bounds.
10620 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10621 Rect initialBounds) {
10622 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10623 synchronized (this) {
10624 long ident = Binder.clearCallingIdentity();
10626 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10627 if (task == null) {
10628 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10632 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10633 + " to createMode=" + createMode + " toTop=" + toTop);
10634 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10636 // Defer resuming until we move the home stack to the front below
10637 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10638 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10639 "moveTaskToDockedStack");
10641 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10645 Binder.restoreCallingIdentity(ident);
10651 * Moves the top activity in the input stackId to the pinned stack.
10653 * @param stackId Id of stack to move the top activity to pinned stack.
10654 * @param bounds Bounds to use for pinned stack.
10656 * @return True if the top activity of the input stack was successfully moved to the pinned
10660 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10661 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10662 synchronized (this) {
10663 if (!mSupportsPictureInPicture) {
10664 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10665 + "Device doesn't support picture-in-picture mode");
10668 long ident = Binder.clearCallingIdentity();
10670 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10672 Binder.restoreCallingIdentity(ident);
10678 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10679 boolean preserveWindows, boolean animate, int animationDuration) {
10680 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10681 long ident = Binder.clearCallingIdentity();
10683 synchronized (this) {
10685 if (stackId == PINNED_STACK_ID) {
10686 final PinnedActivityStack pinnedStack =
10687 mStackSupervisor.getStack(PINNED_STACK_ID);
10688 if (pinnedStack != null) {
10689 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10690 destBounds, animationDuration, false /* fromFullscreen */);
10693 throw new IllegalArgumentException("Stack: " + stackId
10694 + " doesn't support animated resize.");
10697 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10698 null /* tempTaskInsetBounds */, preserveWindows,
10699 allowResizeInDockedMode, !DEFER_RESUME);
10703 Binder.restoreCallingIdentity(ident);
10708 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10709 Rect tempDockedTaskInsetBounds,
10710 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10711 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10712 "resizeDockedStack()");
10713 long ident = Binder.clearCallingIdentity();
10715 synchronized (this) {
10716 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10717 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10721 Binder.restoreCallingIdentity(ident);
10726 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10727 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10728 "resizePinnedStack()");
10729 final long ident = Binder.clearCallingIdentity();
10731 synchronized (this) {
10732 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10735 Binder.restoreCallingIdentity(ident);
10740 * Try to place task to provided position. The final position might be different depending on
10741 * current user and stacks state. The task will be moved to target stack if it's currently in
10745 public void positionTaskInStack(int taskId, int stackId, int position) {
10746 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10747 if (StackId.isHomeOrRecentsStack(stackId)) {
10748 throw new IllegalArgumentException(
10749 "positionTaskInStack: Attempt to change the position of task "
10750 + taskId + " in/to home/recents stack");
10752 synchronized (this) {
10753 long ident = Binder.clearCallingIdentity();
10755 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10756 + taskId + " in stackId=" + stackId + " at position=" + position);
10757 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10758 if (task == null) {
10759 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10763 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10766 // TODO: Have the callers of this API call a separate reparent method if that is
10767 // what they intended to do vs. having this method also do reparenting.
10768 if (task.getStack() == stack) {
10769 // Change position in current stack.
10770 stack.positionChildAt(task, position);
10772 // Reparent to new stack.
10773 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10774 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10777 Binder.restoreCallingIdentity(ident);
10783 public List<StackInfo> getAllStackInfos() {
10784 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10785 long ident = Binder.clearCallingIdentity();
10787 synchronized (this) {
10788 return mStackSupervisor.getAllStackInfosLocked();
10791 Binder.restoreCallingIdentity(ident);
10796 public StackInfo getStackInfo(int stackId) {
10797 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10798 long ident = Binder.clearCallingIdentity();
10800 synchronized (this) {
10801 return mStackSupervisor.getStackInfoLocked(stackId);
10804 Binder.restoreCallingIdentity(ident);
10809 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10810 synchronized(this) {
10811 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10816 public void updateDeviceOwner(String packageName) {
10817 final int callingUid = Binder.getCallingUid();
10818 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10819 throw new SecurityException("updateDeviceOwner called from non-system process");
10821 synchronized (this) {
10822 mDeviceOwnerName = packageName;
10827 public void updateLockTaskPackages(int userId, String[] packages) {
10828 final int callingUid = Binder.getCallingUid();
10829 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10830 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10831 "updateLockTaskPackages()");
10833 synchronized (this) {
10834 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10835 Arrays.toString(packages));
10836 mLockTaskPackages.put(userId, packages);
10837 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10842 void startLockTaskModeLocked(TaskRecord task) {
10843 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10844 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10848 // When a task is locked, dismiss the pinned stack if it exists
10849 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10851 if (pinnedStack != null) {
10852 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10855 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10856 // is initiated by system after the pinning request was shown and locked mode is initiated
10857 // by an authorized app directly
10858 final int callingUid = Binder.getCallingUid();
10859 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10860 long ident = Binder.clearCallingIdentity();
10862 if (!isSystemInitiated) {
10863 task.mLockTaskUid = callingUid;
10864 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10865 // startLockTask() called by app and task mode is lockTaskModeDefault.
10866 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10867 StatusBarManagerInternal statusBarManager =
10868 LocalServices.getService(StatusBarManagerInternal.class);
10869 if (statusBarManager != null) {
10870 statusBarManager.showScreenPinningRequest(task.taskId);
10875 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10876 if (stack == null || task != stack.topTask()) {
10877 throw new IllegalArgumentException("Invalid task, not in foreground");
10880 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10882 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10883 ActivityManager.LOCK_TASK_MODE_PINNED :
10884 ActivityManager.LOCK_TASK_MODE_LOCKED,
10885 "startLockTask", true);
10887 Binder.restoreCallingIdentity(ident);
10892 public void startLockTaskModeById(int taskId) {
10893 synchronized (this) {
10894 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10895 if (task != null) {
10896 startLockTaskModeLocked(task);
10902 public void startLockTaskModeByToken(IBinder token) {
10903 synchronized (this) {
10904 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10908 final TaskRecord task = r.getTask();
10909 if (task != null) {
10910 startLockTaskModeLocked(task);
10916 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10917 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10918 // This makes inner call to look as if it was initiated by system.
10919 long ident = Binder.clearCallingIdentity();
10921 synchronized (this) {
10922 startLockTaskModeById(taskId);
10925 Binder.restoreCallingIdentity(ident);
10930 public void stopLockTaskMode() {
10931 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10932 if (lockTask == null) {
10933 // Our work here is done.
10937 final int callingUid = Binder.getCallingUid();
10938 final int lockTaskUid = lockTask.mLockTaskUid;
10939 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10940 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10944 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10945 // It is possible lockTaskMode was started by the system process because
10946 // android:lockTaskMode is set to a locking value in the application manifest
10947 // instead of the app calling startLockTaskMode. In this case
10948 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10949 // {@link TaskRecord.effectiveUid} instead. Also caller with
10950 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10951 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10952 && callingUid != lockTaskUid
10953 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10954 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10955 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10958 long ident = Binder.clearCallingIdentity();
10960 Log.d(TAG, "stopLockTaskMode");
10962 synchronized (this) {
10963 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10964 "stopLockTask", true);
10966 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10968 tm.showInCallScreen(false);
10971 Binder.restoreCallingIdentity(ident);
10976 * This API should be called by SystemUI only when user perform certain action to dismiss
10977 * lock task mode. We should only dismiss pinned lock task mode in this case.
10980 public void stopSystemLockTaskMode() throws RemoteException {
10981 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10982 stopLockTaskMode();
10984 mStackSupervisor.showLockTaskToast();
10989 public boolean isInLockTaskMode() {
10990 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10994 public int getLockTaskModeState() {
10995 synchronized (this) {
10996 return mStackSupervisor.getLockTaskModeState();
11001 public void showLockTaskEscapeMessage(IBinder token) {
11002 synchronized (this) {
11003 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11007 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11012 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11013 throws RemoteException {
11014 synchronized (this) {
11015 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11017 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11021 final long origId = Binder.clearCallingIdentity();
11023 r.setDisablePreviewScreenshots(disable);
11025 Binder.restoreCallingIdentity(origId);
11030 // =========================================================
11031 // CONTENT PROVIDERS
11032 // =========================================================
11034 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11035 List<ProviderInfo> providers = null;
11037 providers = AppGlobals.getPackageManager()
11038 .queryContentProviders(app.processName, app.uid,
11039 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11040 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11042 } catch (RemoteException ex) {
11044 if (DEBUG_MU) Slog.v(TAG_MU,
11045 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11046 int userId = app.userId;
11047 if (providers != null) {
11048 int N = providers.size();
11049 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11050 for (int i=0; i<N; i++) {
11051 // TODO: keep logic in sync with installEncryptionUnawareProviders
11053 (ProviderInfo)providers.get(i);
11054 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11055 cpi.name, cpi.flags);
11056 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11057 // This is a singleton provider, but a user besides the
11058 // default user is asking to initialize a process it runs
11059 // in... well, no, it doesn't actually run in this process,
11060 // it runs in the process of the default user. Get rid of it.
11061 providers.remove(i);
11067 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11068 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11070 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11071 mProviderMap.putProviderByClass(comp, cpr);
11073 if (DEBUG_MU) Slog.v(TAG_MU,
11074 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11075 app.pubProviders.put(cpi.name, cpr);
11076 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11077 // Don't add this if it is a platform component that is marked
11078 // to run in multiple processes, because this is actually
11079 // part of the framework so doesn't make sense to track as a
11080 // separate apk in the process.
11081 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11084 notifyPackageUse(cpi.applicationInfo.packageName,
11085 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11092 * Check if the calling UID has a possible chance at accessing the provider
11093 * at the given authority and user.
11095 public String checkContentProviderAccess(String authority, int userId) {
11096 if (userId == UserHandle.USER_ALL) {
11097 mContext.enforceCallingOrSelfPermission(
11098 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11099 userId = UserHandle.getCallingUserId();
11102 ProviderInfo cpi = null;
11104 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11105 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11106 | PackageManager.MATCH_DISABLED_COMPONENTS
11107 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11108 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11110 } catch (RemoteException ignored) {
11113 return "Failed to find provider " + authority + " for user " + userId
11114 + "; expected to find a valid ContentProvider for this authority";
11117 ProcessRecord r = null;
11118 synchronized (mPidsSelfLocked) {
11119 r = mPidsSelfLocked.get(Binder.getCallingPid());
11122 return "Failed to find PID " + Binder.getCallingPid();
11125 synchronized (this) {
11126 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11131 * Check if {@link ProcessRecord} has a possible chance at accessing the
11132 * given {@link ProviderInfo}. Final permission checking is always done
11133 * in {@link ContentProvider}.
11135 private final String checkContentProviderPermissionLocked(
11136 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11137 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11138 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11139 boolean checkedGrants = false;
11141 // Looking for cross-user grants before enforcing the typical cross-users permissions
11142 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11143 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11144 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11147 checkedGrants = true;
11149 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11150 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11151 if (userId != tmpTargetUserId) {
11152 // When we actually went to determine the final targer user ID, this ended
11153 // up different than our initial check for the authority. This is because
11154 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11155 // SELF. So we need to re-check the grants again.
11156 checkedGrants = false;
11159 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11160 cpi.applicationInfo.uid, cpi.exported)
11161 == PackageManager.PERMISSION_GRANTED) {
11164 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11165 cpi.applicationInfo.uid, cpi.exported)
11166 == PackageManager.PERMISSION_GRANTED) {
11170 PathPermission[] pps = cpi.pathPermissions;
11172 int i = pps.length;
11175 PathPermission pp = pps[i];
11176 String pprperm = pp.getReadPermission();
11177 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11178 cpi.applicationInfo.uid, cpi.exported)
11179 == PackageManager.PERMISSION_GRANTED) {
11182 String ppwperm = pp.getWritePermission();
11183 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11184 cpi.applicationInfo.uid, cpi.exported)
11185 == PackageManager.PERMISSION_GRANTED) {
11190 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11194 final String suffix;
11195 if (!cpi.exported) {
11196 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11197 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11198 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11200 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11202 final String msg = "Permission Denial: opening provider " + cpi.name
11203 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11204 + ", uid=" + callingUid + ")" + suffix;
11210 * Returns if the ContentProvider has granted a uri to callingUid
11212 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11213 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11214 if (perms != null) {
11215 for (int i=perms.size()-1; i>=0; i--) {
11216 GrantUri grantUri = perms.keyAt(i);
11217 if (grantUri.sourceUserId == userId || !checkUser) {
11218 if (matchesProvider(grantUri.uri, cpi)) {
11228 * Returns true if the uri authority is one of the authorities specified in the provider.
11230 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11231 String uriAuth = uri.getAuthority();
11232 String cpiAuth = cpi.authority;
11233 if (cpiAuth.indexOf(';') == -1) {
11234 return cpiAuth.equals(uriAuth);
11236 String[] cpiAuths = cpiAuth.split(";");
11237 int length = cpiAuths.length;
11238 for (int i = 0; i < length; i++) {
11239 if (cpiAuths[i].equals(uriAuth)) return true;
11244 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11245 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11247 for (int i=0; i<r.conProviders.size(); i++) {
11248 ContentProviderConnection conn = r.conProviders.get(i);
11249 if (conn.provider == cpr) {
11250 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11251 "Adding provider requested by "
11252 + r.processName + " from process "
11253 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11254 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11256 conn.stableCount++;
11257 conn.numStableIncs++;
11259 conn.unstableCount++;
11260 conn.numUnstableIncs++;
11265 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11267 conn.stableCount = 1;
11268 conn.numStableIncs = 1;
11270 conn.unstableCount = 1;
11271 conn.numUnstableIncs = 1;
11273 cpr.connections.add(conn);
11274 r.conProviders.add(conn);
11275 startAssociationLocked(r.uid, r.processName, r.curProcState,
11276 cpr.uid, cpr.name, cpr.info.processName);
11279 cpr.addExternalProcessHandleLocked(externalProcessToken);
11283 boolean decProviderCountLocked(ContentProviderConnection conn,
11284 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11285 if (conn != null) {
11286 cpr = conn.provider;
11287 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11288 "Removing provider requested by "
11289 + conn.client.processName + " from process "
11290 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11291 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11293 conn.stableCount--;
11295 conn.unstableCount--;
11297 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11298 cpr.connections.remove(conn);
11299 conn.client.conProviders.remove(conn);
11300 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11301 // The client is more important than last activity -- note the time this
11302 // is happening, so we keep the old provider process around a bit as last
11303 // activity to avoid thrashing it.
11304 if (cpr.proc != null) {
11305 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11308 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11313 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11317 private void checkTime(long startTime, String where) {
11318 long now = SystemClock.uptimeMillis();
11319 if ((now-startTime) > 50) {
11320 // If we are taking more than 50ms, log about it.
11321 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11325 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11327 PROC_SPACE_TERM|PROC_PARENS,
11328 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11331 private final long[] mProcessStateStatsLongs = new long[1];
11333 boolean isProcessAliveLocked(ProcessRecord proc) {
11334 if (proc.procStatFile == null) {
11335 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11337 mProcessStateStatsLongs[0] = 0;
11338 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11339 mProcessStateStatsLongs, null)) {
11340 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11343 final long state = mProcessStateStatsLongs[0];
11344 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11346 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11349 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11350 String name, IBinder token, boolean stable, int userId) {
11351 ContentProviderRecord cpr;
11352 ContentProviderConnection conn = null;
11353 ProviderInfo cpi = null;
11355 synchronized(this) {
11356 long startTime = SystemClock.uptimeMillis();
11358 ProcessRecord r = null;
11359 if (caller != null) {
11360 r = getRecordForAppLocked(caller);
11362 throw new SecurityException(
11363 "Unable to find app for caller " + caller
11364 + " (pid=" + Binder.getCallingPid()
11365 + ") when getting content provider " + name);
11369 boolean checkCrossUser = true;
11371 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11373 // First check if this content provider has been published...
11374 cpr = mProviderMap.getProviderByName(name, userId);
11375 // If that didn't work, check if it exists for user 0 and then
11376 // verify that it's a singleton provider before using it.
11377 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11378 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11381 if (isSingleton(cpi.processName, cpi.applicationInfo,
11382 cpi.name, cpi.flags)
11383 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11384 userId = UserHandle.USER_SYSTEM;
11385 checkCrossUser = false;
11393 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11394 if (providerRunning) {
11397 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11398 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11400 throw new SecurityException(msg);
11402 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11404 if (r != null && cpr.canRunHere(r)) {
11405 // This provider has been published or is in the process
11406 // of being published... but it is also allowed to run
11407 // in the caller's process, so don't make a connection
11408 // and just let the caller instantiate its own instance.
11409 ContentProviderHolder holder = cpr.newHolder(null);
11410 // don't give caller the provider object, it needs
11411 // to make its own.
11412 holder.provider = null;
11415 // Don't expose providers between normal apps and instant apps
11417 if (AppGlobals.getPackageManager()
11418 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11421 } catch (RemoteException e) {
11424 final long origId = Binder.clearCallingIdentity();
11426 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11428 // In this case the provider instance already exists, so we can
11429 // return it right away.
11430 conn = incProviderCountLocked(r, cpr, token, stable);
11431 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11432 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11433 // If this is a perceptible app accessing the provider,
11434 // make sure to count it as being accessed and thus
11435 // back up on the LRU list. This is good because
11436 // content providers are often expensive to start.
11437 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11438 updateLruProcessLocked(cpr.proc, false, null);
11439 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11443 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11444 final int verifiedAdj = cpr.proc.verifiedAdj;
11445 boolean success = updateOomAdjLocked(cpr.proc, true);
11446 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11447 // if the process has been successfully adjusted. So to reduce races with
11448 // it, we will check whether the process still exists. Note that this doesn't
11449 // completely get rid of races with LMK killing the process, but should make
11450 // them much smaller.
11451 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11454 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11455 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11456 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11457 // NOTE: there is still a race here where a signal could be
11458 // pending on the process even though we managed to update its
11459 // adj level. Not sure what to do about this, but at least
11460 // the race is now smaller.
11462 // Uh oh... it looks like the provider's process
11463 // has been killed on us. We need to wait for a new
11464 // process to be started, and make sure its death
11465 // doesn't kill our process.
11466 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11467 + " is crashing; detaching " + r);
11468 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11469 checkTime(startTime, "getContentProviderImpl: before appDied");
11470 appDiedLocked(cpr.proc);
11471 checkTime(startTime, "getContentProviderImpl: after appDied");
11473 // This wasn't the last ref our process had on
11474 // the provider... we have now been killed, bail.
11477 providerRunning = false;
11480 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11483 Binder.restoreCallingIdentity(origId);
11486 if (!providerRunning) {
11488 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11489 cpi = AppGlobals.getPackageManager().
11490 resolveContentProvider(name,
11491 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11492 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11493 } catch (RemoteException ex) {
11498 // If the provider is a singleton AND
11499 // (it's a call within the same user || the provider is a
11501 // Then allow connecting to the singleton provider
11502 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11503 cpi.name, cpi.flags)
11504 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11506 userId = UserHandle.USER_SYSTEM;
11508 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11509 checkTime(startTime, "getContentProviderImpl: got app info for user");
11512 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11513 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11515 throw new SecurityException(msg);
11517 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11519 if (!mProcessesReady
11520 && !cpi.processName.equals("system")) {
11521 // If this content provider does not run in the system
11522 // process, and the system is not yet ready to run other
11523 // processes, then fail fast instead of hanging.
11524 throw new IllegalArgumentException(
11525 "Attempt to launch content provider before system ready");
11528 // Make sure that the user who owns this provider is running. If not,
11529 // we don't want to allow it to run.
11530 if (!mUserController.isUserRunningLocked(userId, 0)) {
11531 Slog.w(TAG, "Unable to launch app "
11532 + cpi.applicationInfo.packageName + "/"
11533 + cpi.applicationInfo.uid + " for provider "
11534 + name + ": user " + userId + " is stopped");
11538 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11539 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11540 cpr = mProviderMap.getProviderByClass(comp, userId);
11541 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11542 final boolean firstClass = cpr == null;
11544 final long ident = Binder.clearCallingIdentity();
11546 // If permissions need a review before any of the app components can run,
11547 // we return no provider and launch a review activity if the calling app
11548 // is in the foreground.
11549 if (mPermissionReviewRequired) {
11550 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11556 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11557 ApplicationInfo ai =
11558 AppGlobals.getPackageManager().
11559 getApplicationInfo(
11560 cpi.applicationInfo.packageName,
11561 STOCK_PM_FLAGS, userId);
11562 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11564 Slog.w(TAG, "No package info for content provider "
11568 ai = getAppInfoForUser(ai, userId);
11569 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11570 } catch (RemoteException ex) {
11571 // pm is in same process, this will never happen.
11573 Binder.restoreCallingIdentity(ident);
11577 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11579 if (r != null && cpr.canRunHere(r)) {
11580 // If this is a multiprocess provider, then just return its
11581 // info and allow the caller to instantiate it. Only do
11582 // this if the provider is the same user as the caller's
11583 // process, or can run as root (so can be in any process).
11584 return cpr.newHolder(null);
11587 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11588 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11589 + cpr.info.name + " callers=" + Debug.getCallers(6));
11591 // This is single process, and our app is now connecting to it.
11592 // See if we are already in the process of launching this
11594 final int N = mLaunchingProviders.size();
11596 for (i = 0; i < N; i++) {
11597 if (mLaunchingProviders.get(i) == cpr) {
11602 // If the provider is not already being launched, then get it
11605 final long origId = Binder.clearCallingIdentity();
11608 // Content provider is now in use, its package can't be stopped.
11610 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11611 AppGlobals.getPackageManager().setPackageStoppedState(
11612 cpr.appInfo.packageName, false, userId);
11613 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11614 } catch (RemoteException e) {
11615 } catch (IllegalArgumentException e) {
11616 Slog.w(TAG, "Failed trying to unstop package "
11617 + cpr.appInfo.packageName + ": " + e);
11620 // Use existing process if already started
11621 checkTime(startTime, "getContentProviderImpl: looking for process record");
11622 ProcessRecord proc = getProcessRecordLocked(
11623 cpi.processName, cpr.appInfo.uid, false);
11624 if (proc != null && proc.thread != null && !proc.killed) {
11625 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11626 "Installing in existing process " + proc);
11627 if (!proc.pubProviders.containsKey(cpi.name)) {
11628 checkTime(startTime, "getContentProviderImpl: scheduling install");
11629 proc.pubProviders.put(cpi.name, cpr);
11631 proc.thread.scheduleInstallProvider(cpi);
11632 } catch (RemoteException e) {
11636 checkTime(startTime, "getContentProviderImpl: before start process");
11637 proc = startProcessLocked(cpi.processName,
11638 cpr.appInfo, false, 0, "content provider",
11639 new ComponentName(cpi.applicationInfo.packageName,
11640 cpi.name), false, false, false);
11641 checkTime(startTime, "getContentProviderImpl: after start process");
11642 if (proc == null) {
11643 Slog.w(TAG, "Unable to launch app "
11644 + cpi.applicationInfo.packageName + "/"
11645 + cpi.applicationInfo.uid + " for provider "
11646 + name + ": process is bad");
11650 cpr.launchingApp = proc;
11651 mLaunchingProviders.add(cpr);
11653 Binder.restoreCallingIdentity(origId);
11657 checkTime(startTime, "getContentProviderImpl: updating data structures");
11659 // Make sure the provider is published (the same provider class
11660 // may be published under multiple names).
11662 mProviderMap.putProviderByClass(comp, cpr);
11665 mProviderMap.putProviderByName(name, cpr);
11666 conn = incProviderCountLocked(r, cpr, token, stable);
11667 if (conn != null) {
11668 conn.waiting = true;
11671 checkTime(startTime, "getContentProviderImpl: done!");
11673 grantEphemeralAccessLocked(userId, null /*intent*/,
11674 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11677 // Wait for the provider to be published...
11678 synchronized (cpr) {
11679 while (cpr.provider == null) {
11680 if (cpr.launchingApp == null) {
11681 Slog.w(TAG, "Unable to launch app "
11682 + cpi.applicationInfo.packageName + "/"
11683 + cpi.applicationInfo.uid + " for provider "
11684 + name + ": launching app became null");
11685 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11686 UserHandle.getUserId(cpi.applicationInfo.uid),
11687 cpi.applicationInfo.packageName,
11688 cpi.applicationInfo.uid, name);
11692 if (DEBUG_MU) Slog.v(TAG_MU,
11693 "Waiting to start provider " + cpr
11694 + " launchingApp=" + cpr.launchingApp);
11695 if (conn != null) {
11696 conn.waiting = true;
11699 } catch (InterruptedException ex) {
11701 if (conn != null) {
11702 conn.waiting = false;
11707 return cpr != null ? cpr.newHolder(conn) : null;
11710 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11711 ProcessRecord r, final int userId) {
11712 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11713 cpi.packageName, userId)) {
11715 final boolean callerForeground = r == null || r.setSchedGroup
11716 != ProcessList.SCHED_GROUP_BACKGROUND;
11718 // Show a permission review UI only for starting from a foreground app
11719 if (!callerForeground) {
11720 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11721 + cpi.packageName + " requires a permissions review");
11725 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11726 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11727 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11728 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11730 if (DEBUG_PERMISSIONS_REVIEW) {
11731 Slog.i(TAG, "u" + userId + " Launching permission review "
11732 + "for package " + cpi.packageName);
11735 final UserHandle userHandle = new UserHandle(userId);
11736 mHandler.post(new Runnable() {
11738 public void run() {
11739 mContext.startActivityAsUser(intent, userHandle);
11749 PackageManagerInternal getPackageManagerInternalLocked() {
11750 if (mPackageManagerInt == null) {
11751 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11753 return mPackageManagerInt;
11757 public final ContentProviderHolder getContentProvider(
11758 IApplicationThread caller, String name, int userId, boolean stable) {
11759 enforceNotIsolatedCaller("getContentProvider");
11760 if (caller == null) {
11761 String msg = "null IApplicationThread when getting content provider "
11764 throw new SecurityException(msg);
11766 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11767 // with cross-user grant.
11768 return getContentProviderImpl(caller, name, null, stable, userId);
11771 public ContentProviderHolder getContentProviderExternal(
11772 String name, int userId, IBinder token) {
11773 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11774 "Do not have permission in call getContentProviderExternal()");
11775 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11776 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11777 return getContentProviderExternalUnchecked(name, token, userId);
11780 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11781 IBinder token, int userId) {
11782 return getContentProviderImpl(null, name, token, true, userId);
11786 * Drop a content provider from a ProcessRecord's bookkeeping
11788 public void removeContentProvider(IBinder connection, boolean stable) {
11789 enforceNotIsolatedCaller("removeContentProvider");
11790 long ident = Binder.clearCallingIdentity();
11792 synchronized (this) {
11793 ContentProviderConnection conn;
11795 conn = (ContentProviderConnection)connection;
11796 } catch (ClassCastException e) {
11797 String msg ="removeContentProvider: " + connection
11798 + " not a ContentProviderConnection";
11800 throw new IllegalArgumentException(msg);
11802 if (conn == null) {
11803 throw new NullPointerException("connection is null");
11805 if (decProviderCountLocked(conn, null, null, stable)) {
11806 updateOomAdjLocked();
11810 Binder.restoreCallingIdentity(ident);
11814 public void removeContentProviderExternal(String name, IBinder token) {
11815 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11816 "Do not have permission in call removeContentProviderExternal()");
11817 int userId = UserHandle.getCallingUserId();
11818 long ident = Binder.clearCallingIdentity();
11820 removeContentProviderExternalUnchecked(name, token, userId);
11822 Binder.restoreCallingIdentity(ident);
11826 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11827 synchronized (this) {
11828 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11830 //remove from mProvidersByClass
11831 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11835 //update content provider record entry info
11836 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11837 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11838 if (localCpr.hasExternalProcessHandles()) {
11839 if (localCpr.removeExternalProcessHandleLocked(token)) {
11840 updateOomAdjLocked();
11842 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11843 + " with no external reference for token: "
11847 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11848 + " with no external references.");
11853 public final void publishContentProviders(IApplicationThread caller,
11854 List<ContentProviderHolder> providers) {
11855 if (providers == null) {
11859 enforceNotIsolatedCaller("publishContentProviders");
11860 synchronized (this) {
11861 final ProcessRecord r = getRecordForAppLocked(caller);
11862 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11864 throw new SecurityException(
11865 "Unable to find app for caller " + caller
11866 + " (pid=" + Binder.getCallingPid()
11867 + ") when publishing content providers");
11870 final long origId = Binder.clearCallingIdentity();
11872 final int N = providers.size();
11873 for (int i = 0; i < N; i++) {
11874 ContentProviderHolder src = providers.get(i);
11875 if (src == null || src.info == null || src.provider == null) {
11878 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11879 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11881 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11882 mProviderMap.putProviderByClass(comp, dst);
11883 String names[] = dst.info.authority.split(";");
11884 for (int j = 0; j < names.length; j++) {
11885 mProviderMap.putProviderByName(names[j], dst);
11888 int launchingCount = mLaunchingProviders.size();
11890 boolean wasInLaunchingProviders = false;
11891 for (j = 0; j < launchingCount; j++) {
11892 if (mLaunchingProviders.get(j) == dst) {
11893 mLaunchingProviders.remove(j);
11894 wasInLaunchingProviders = true;
11899 if (wasInLaunchingProviders) {
11900 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11902 synchronized (dst) {
11903 dst.provider = src.provider;
11907 updateOomAdjLocked(r, true);
11908 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11909 src.info.authority);
11913 Binder.restoreCallingIdentity(origId);
11917 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11918 ContentProviderConnection conn;
11920 conn = (ContentProviderConnection)connection;
11921 } catch (ClassCastException e) {
11922 String msg ="refContentProvider: " + connection
11923 + " not a ContentProviderConnection";
11925 throw new IllegalArgumentException(msg);
11927 if (conn == null) {
11928 throw new NullPointerException("connection is null");
11931 synchronized (this) {
11933 conn.numStableIncs += stable;
11935 stable = conn.stableCount + stable;
11937 throw new IllegalStateException("stableCount < 0: " + stable);
11940 if (unstable > 0) {
11941 conn.numUnstableIncs += unstable;
11943 unstable = conn.unstableCount + unstable;
11944 if (unstable < 0) {
11945 throw new IllegalStateException("unstableCount < 0: " + unstable);
11948 if ((stable+unstable) <= 0) {
11949 throw new IllegalStateException("ref counts can't go to zero here: stable="
11950 + stable + " unstable=" + unstable);
11952 conn.stableCount = stable;
11953 conn.unstableCount = unstable;
11958 public void unstableProviderDied(IBinder connection) {
11959 ContentProviderConnection conn;
11961 conn = (ContentProviderConnection)connection;
11962 } catch (ClassCastException e) {
11963 String msg ="refContentProvider: " + connection
11964 + " not a ContentProviderConnection";
11966 throw new IllegalArgumentException(msg);
11968 if (conn == null) {
11969 throw new NullPointerException("connection is null");
11972 // Safely retrieve the content provider associated with the connection.
11973 IContentProvider provider;
11974 synchronized (this) {
11975 provider = conn.provider.provider;
11978 if (provider == null) {
11979 // Um, yeah, we're way ahead of you.
11983 // Make sure the caller is being honest with us.
11984 if (provider.asBinder().pingBinder()) {
11985 // Er, no, still looks good to us.
11986 synchronized (this) {
11987 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11988 + " says " + conn + " died, but we don't agree");
11993 // Well look at that! It's dead!
11994 synchronized (this) {
11995 if (conn.provider.provider != provider) {
11996 // But something changed... good enough.
12000 ProcessRecord proc = conn.provider.proc;
12001 if (proc == null || proc.thread == null) {
12002 // Seems like the process is already cleaned up.
12006 // As far as we're concerned, this is just like receiving a
12007 // death notification... just a bit prematurely.
12008 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12009 + ") early provider death");
12010 final long ident = Binder.clearCallingIdentity();
12012 appDiedLocked(proc);
12014 Binder.restoreCallingIdentity(ident);
12020 public void appNotRespondingViaProvider(IBinder connection) {
12021 enforceCallingPermission(
12022 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12024 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12025 if (conn == null) {
12026 Slog.w(TAG, "ContentProviderConnection is null");
12030 final ProcessRecord host = conn.provider.proc;
12031 if (host == null) {
12032 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12036 mHandler.post(new Runnable() {
12038 public void run() {
12039 mAppErrors.appNotResponding(host, null, null, false,
12040 "ContentProvider not responding");
12045 public final void installSystemProviders() {
12046 List<ProviderInfo> providers;
12047 synchronized (this) {
12048 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12049 providers = generateApplicationProvidersLocked(app);
12050 if (providers != null) {
12051 for (int i=providers.size()-1; i>=0; i--) {
12052 ProviderInfo pi = (ProviderInfo)providers.get(i);
12053 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12054 Slog.w(TAG, "Not installing system proc provider " + pi.name
12055 + ": not system .apk");
12056 providers.remove(i);
12061 if (providers != null) {
12062 mSystemThread.installSystemProviders(providers);
12065 mConstants.start(mContext.getContentResolver());
12066 mCoreSettingsObserver = new CoreSettingsObserver(this);
12067 mFontScaleSettingObserver = new FontScaleSettingObserver();
12069 // Now that the settings provider is published we can consider sending
12070 // in a rescue party.
12071 RescueParty.onSettingsProviderPublished(mContext);
12073 //mUsageStatsService.monitorPackages();
12076 private void startPersistentApps(int matchFlags) {
12077 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12079 synchronized (this) {
12081 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12082 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12083 for (ApplicationInfo app : apps) {
12084 if (!"android".equals(app.packageName)) {
12085 addAppLocked(app, null, false, null /* ABI override */);
12088 } catch (RemoteException ex) {
12094 * When a user is unlocked, we need to install encryption-unaware providers
12095 * belonging to any running apps.
12097 private void installEncryptionUnawareProviders(int userId) {
12098 // We're only interested in providers that are encryption unaware, and
12099 // we don't care about uninstalled apps, since there's no way they're
12100 // running at this point.
12101 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12103 synchronized (this) {
12104 final int NP = mProcessNames.getMap().size();
12105 for (int ip = 0; ip < NP; ip++) {
12106 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12107 final int NA = apps.size();
12108 for (int ia = 0; ia < NA; ia++) {
12109 final ProcessRecord app = apps.valueAt(ia);
12110 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12112 final int NG = app.pkgList.size();
12113 for (int ig = 0; ig < NG; ig++) {
12115 final String pkgName = app.pkgList.keyAt(ig);
12116 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12117 .getPackageInfo(pkgName, matchFlags, userId);
12118 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12119 for (ProviderInfo pi : pkgInfo.providers) {
12120 // TODO: keep in sync with generateApplicationProvidersLocked
12121 final boolean processMatch = Objects.equals(pi.processName,
12122 app.processName) || pi.multiprocess;
12123 final boolean userMatch = isSingleton(pi.processName,
12124 pi.applicationInfo, pi.name, pi.flags)
12125 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12126 if (processMatch && userMatch) {
12127 Log.v(TAG, "Installing " + pi);
12128 app.thread.scheduleInstallProvider(pi);
12130 Log.v(TAG, "Skipping " + pi);
12134 } catch (RemoteException ignored) {
12143 * Allows apps to retrieve the MIME type of a URI.
12144 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12145 * users, then it does not need permission to access the ContentProvider.
12146 * Either, it needs cross-user uri grants.
12148 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12150 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12151 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12153 public String getProviderMimeType(Uri uri, int userId) {
12154 enforceNotIsolatedCaller("getProviderMimeType");
12155 final String name = uri.getAuthority();
12156 int callingUid = Binder.getCallingUid();
12157 int callingPid = Binder.getCallingPid();
12159 boolean clearedIdentity = false;
12160 synchronized (this) {
12161 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12163 if (canClearIdentity(callingPid, callingUid, userId)) {
12164 clearedIdentity = true;
12165 ident = Binder.clearCallingIdentity();
12167 ContentProviderHolder holder = null;
12169 holder = getContentProviderExternalUnchecked(name, null, userId);
12170 if (holder != null) {
12171 return holder.provider.getType(uri);
12173 } catch (RemoteException e) {
12174 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12176 } catch (Exception e) {
12177 Log.w(TAG, "Exception while determining type of " + uri, e);
12180 // We need to clear the identity to call removeContentProviderExternalUnchecked
12181 if (!clearedIdentity) {
12182 ident = Binder.clearCallingIdentity();
12185 if (holder != null) {
12186 removeContentProviderExternalUnchecked(name, null, userId);
12189 Binder.restoreCallingIdentity(ident);
12196 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12197 if (UserHandle.getUserId(callingUid) == userId) {
12200 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12201 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12202 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12203 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12209 // =========================================================
12210 // GLOBAL MANAGEMENT
12211 // =========================================================
12213 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12214 boolean isolated, int isolatedUid) {
12215 String proc = customProcess != null ? customProcess : info.processName;
12216 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12217 final int userId = UserHandle.getUserId(info.uid);
12218 int uid = info.uid;
12220 if (isolatedUid == 0) {
12221 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12223 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12224 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12225 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12227 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12228 mNextIsolatedProcessUid++;
12229 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12230 // No process for this uid, use it.
12234 if (stepsLeft <= 0) {
12239 // Special case for startIsolatedProcess (internal only), where
12240 // the uid of the isolated process is specified by the caller.
12243 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12245 // Register the isolated UID with this application so BatteryStats knows to
12246 // attribute resource usage to the application.
12248 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12249 // about the process state of the isolated UID *before* it is registered with the
12250 // owning application.
12251 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12253 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12254 if (!mBooted && !mBooting
12255 && userId == UserHandle.USER_SYSTEM
12256 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12257 r.persistent = true;
12258 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12260 addProcessNameLocked(r);
12264 private boolean uidOnBackgroundWhitelist(final int uid) {
12265 final int appId = UserHandle.getAppId(uid);
12266 final int[] whitelist = mBackgroundAppIdWhitelist;
12267 final int N = whitelist.length;
12268 for (int i = 0; i < N; i++) {
12269 if (appId == whitelist[i]) {
12277 public void backgroundWhitelistUid(final int uid) {
12278 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12279 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12282 if (DEBUG_BACKGROUND_CHECK) {
12283 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12285 synchronized (this) {
12286 final int N = mBackgroundAppIdWhitelist.length;
12287 int[] newList = new int[N+1];
12288 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12289 newList[N] = UserHandle.getAppId(uid);
12290 mBackgroundAppIdWhitelist = newList;
12294 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12295 String abiOverride) {
12298 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12305 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12306 updateLruProcessLocked(app, false, null);
12307 updateOomAdjLocked();
12310 // This package really, really can not be stopped.
12312 AppGlobals.getPackageManager().setPackageStoppedState(
12313 info.packageName, false, UserHandle.getUserId(app.uid));
12314 } catch (RemoteException e) {
12315 } catch (IllegalArgumentException e) {
12316 Slog.w(TAG, "Failed trying to unstop package "
12317 + info.packageName + ": " + e);
12320 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12321 app.persistent = true;
12322 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12324 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12325 mPersistentStartingProcesses.add(app);
12326 startProcessLocked(app, "added application",
12327 customProcess != null ? customProcess : app.processName, abiOverride,
12328 null /* entryPoint */, null /* entryPointArgs */);
12334 public void unhandledBack() {
12335 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12336 "unhandledBack()");
12338 synchronized(this) {
12339 final long origId = Binder.clearCallingIdentity();
12341 getFocusedStack().unhandledBackLocked();
12343 Binder.restoreCallingIdentity(origId);
12348 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12349 enforceNotIsolatedCaller("openContentUri");
12350 final int userId = UserHandle.getCallingUserId();
12351 final Uri uri = Uri.parse(uriString);
12352 String name = uri.getAuthority();
12353 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12354 ParcelFileDescriptor pfd = null;
12356 // We record the binder invoker's uid in thread-local storage before
12357 // going to the content provider to open the file. Later, in the code
12358 // that handles all permissions checks, we look for this uid and use
12359 // that rather than the Activity Manager's own uid. The effect is that
12360 // we do the check against the caller's permissions even though it looks
12361 // to the content provider like the Activity Manager itself is making
12363 Binder token = new Binder();
12364 sCallerIdentity.set(new Identity(
12365 token, Binder.getCallingPid(), Binder.getCallingUid()));
12367 pfd = cph.provider.openFile(null, uri, "r", null, token);
12368 } catch (FileNotFoundException e) {
12369 // do nothing; pfd will be returned null
12371 // Ensure that whatever happens, we clean up the identity state
12372 sCallerIdentity.remove();
12373 // Ensure we're done with the provider.
12374 removeContentProviderExternalUnchecked(name, null, userId);
12377 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12382 // Actually is sleeping or shutting down or whatever else in the future
12383 // is an inactive state.
12384 boolean isSleepingOrShuttingDownLocked() {
12385 return isSleepingLocked() || mShuttingDown;
12388 boolean isShuttingDownLocked() {
12389 return mShuttingDown;
12392 boolean isSleepingLocked() {
12396 void onWakefulnessChanged(int wakefulness) {
12397 synchronized(this) {
12398 mWakefulness = wakefulness;
12399 updateSleepIfNeededLocked();
12403 void finishRunningVoiceLocked() {
12404 if (mRunningVoice != null) {
12405 mRunningVoice = null;
12406 mVoiceWakeLock.release();
12407 updateSleepIfNeededLocked();
12411 void startTimeTrackingFocusedActivityLocked() {
12412 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12413 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12414 mCurAppTimeTracker.start(resumedActivity.packageName);
12418 void updateSleepIfNeededLocked() {
12419 final boolean shouldSleep = shouldSleepLocked();
12420 if (mSleeping && !shouldSleep) {
12422 startTimeTrackingFocusedActivityLocked();
12423 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12424 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12425 sendNotifyVrManagerOfSleepState(false);
12426 updateOomAdjLocked();
12427 } else if (!mSleeping && shouldSleep) {
12429 if (mCurAppTimeTracker != null) {
12430 mCurAppTimeTracker.stop();
12432 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12433 mStackSupervisor.goingToSleepLocked();
12434 sendNotifyVrManagerOfSleepState(true);
12435 updateOomAdjLocked();
12437 // Initialize the wake times of all processes.
12438 checkExcessivePowerUsageLocked(false);
12439 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12440 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12441 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12444 // Also update state in a special way for running foreground services UI.
12445 switch (mWakefulness) {
12446 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12447 case PowerManagerInternal.WAKEFULNESS_DREAMING:
12448 case PowerManagerInternal.WAKEFULNESS_DOZING:
12449 mServices.updateScreenStateLocked(false);
12451 case PowerManagerInternal.WAKEFULNESS_AWAKE:
12453 mServices.updateScreenStateLocked(true);
12458 private boolean shouldSleepLocked() {
12459 // Resume applications while running a voice interactor.
12460 if (mRunningVoice != null) {
12464 // TODO: Transform the lock screen state into a sleep token instead.
12465 switch (mWakefulness) {
12466 case PowerManagerInternal.WAKEFULNESS_AWAKE:
12467 case PowerManagerInternal.WAKEFULNESS_DREAMING:
12468 // Pause applications whenever the lock screen is shown or any sleep
12469 // tokens have been acquired.
12470 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12471 case PowerManagerInternal.WAKEFULNESS_DOZING:
12472 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12474 // If we're asleep then pause applications unconditionally.
12479 /** Pokes the task persister. */
12480 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12481 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12485 * Notifies all listeners when the pinned stack animation starts.
12488 public void notifyPinnedStackAnimationStarted() {
12489 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12493 * Notifies all listeners when the pinned stack animation ends.
12496 public void notifyPinnedStackAnimationEnded() {
12497 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12501 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12502 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12506 public boolean shutdown(int timeout) {
12507 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12508 != PackageManager.PERMISSION_GRANTED) {
12509 throw new SecurityException("Requires permission "
12510 + android.Manifest.permission.SHUTDOWN);
12513 boolean timedout = false;
12515 synchronized(this) {
12516 mShuttingDown = true;
12517 updateEventDispatchingLocked();
12518 timedout = mStackSupervisor.shutdownLocked(timeout);
12521 mAppOpsService.shutdown();
12522 if (mUsageStatsService != null) {
12523 mUsageStatsService.prepareShutdown();
12525 mBatteryStatsService.shutdown();
12526 synchronized (this) {
12527 mProcessStats.shutdownLocked();
12528 notifyTaskPersisterLocked(null, true);
12534 public final void activitySlept(IBinder token) {
12535 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12537 final long origId = Binder.clearCallingIdentity();
12539 synchronized (this) {
12540 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12542 mStackSupervisor.activitySleptLocked(r);
12546 Binder.restoreCallingIdentity(origId);
12549 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12550 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12551 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12552 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12553 boolean wasRunningVoice = mRunningVoice != null;
12554 mRunningVoice = session;
12555 if (!wasRunningVoice) {
12556 mVoiceWakeLock.acquire();
12557 updateSleepIfNeededLocked();
12562 private void updateEventDispatchingLocked() {
12563 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12567 public void setLockScreenShown(boolean showing) {
12568 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12569 != PackageManager.PERMISSION_GRANTED) {
12570 throw new SecurityException("Requires permission "
12571 + android.Manifest.permission.DEVICE_POWER);
12574 synchronized(this) {
12575 long ident = Binder.clearCallingIdentity();
12577 mKeyguardController.setKeyguardShown(showing);
12579 Binder.restoreCallingIdentity(ident);
12585 public void notifyLockedProfile(@UserIdInt int userId) {
12587 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12588 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12590 } catch (RemoteException ex) {
12591 throw new SecurityException("Fail to check is caller a privileged app", ex);
12594 synchronized (this) {
12595 final long ident = Binder.clearCallingIdentity();
12597 if (mUserController.shouldConfirmCredentials(userId)) {
12598 if (mKeyguardController.isKeyguardLocked()) {
12599 // Showing launcher to avoid user entering credential twice.
12600 final int currentUserId = mUserController.getCurrentUserIdLocked();
12601 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12603 mStackSupervisor.lockAllProfileTasks(userId);
12606 Binder.restoreCallingIdentity(ident);
12612 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12613 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12614 synchronized (this) {
12615 final long ident = Binder.clearCallingIdentity();
12617 mActivityStarter.startConfirmCredentialIntent(intent, options);
12619 Binder.restoreCallingIdentity(ident);
12625 public void stopAppSwitches() {
12626 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12627 != PackageManager.PERMISSION_GRANTED) {
12628 throw new SecurityException("viewquires permission "
12629 + android.Manifest.permission.STOP_APP_SWITCHES);
12632 synchronized(this) {
12633 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12634 + APP_SWITCH_DELAY_TIME;
12635 mDidAppSwitch = false;
12636 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12637 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12638 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12642 public void resumeAppSwitches() {
12643 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12644 != PackageManager.PERMISSION_GRANTED) {
12645 throw new SecurityException("Requires permission "
12646 + android.Manifest.permission.STOP_APP_SWITCHES);
12649 synchronized(this) {
12650 // Note that we don't execute any pending app switches... we will
12651 // let those wait until either the timeout, or the next start
12652 // activity request.
12653 mAppSwitchesAllowedTime = 0;
12657 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12658 int callingPid, int callingUid, String name) {
12659 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12663 int perm = checkComponentPermission(
12664 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12665 sourceUid, -1, true);
12666 if (perm == PackageManager.PERMISSION_GRANTED) {
12670 // If the actual IPC caller is different from the logical source, then
12671 // also see if they are allowed to control app switches.
12672 if (callingUid != -1 && callingUid != sourceUid) {
12673 perm = checkComponentPermission(
12674 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12675 callingUid, -1, true);
12676 if (perm == PackageManager.PERMISSION_GRANTED) {
12681 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12685 public void setDebugApp(String packageName, boolean waitForDebugger,
12686 boolean persistent) {
12687 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12690 long ident = Binder.clearCallingIdentity();
12692 // Note that this is not really thread safe if there are multiple
12693 // callers into it at the same time, but that's not a situation we
12696 final ContentResolver resolver = mContext.getContentResolver();
12697 Settings.Global.putString(
12698 resolver, Settings.Global.DEBUG_APP,
12700 Settings.Global.putInt(
12701 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12702 waitForDebugger ? 1 : 0);
12705 synchronized (this) {
12707 mOrigDebugApp = mDebugApp;
12708 mOrigWaitForDebugger = mWaitForDebugger;
12710 mDebugApp = packageName;
12711 mWaitForDebugger = waitForDebugger;
12712 mDebugTransient = !persistent;
12713 if (packageName != null) {
12714 forceStopPackageLocked(packageName, -1, false, false, true, true,
12715 false, UserHandle.USER_ALL, "set debug app");
12719 Binder.restoreCallingIdentity(ident);
12723 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12724 synchronized (this) {
12725 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12726 if (!isDebuggable) {
12727 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12728 throw new SecurityException("Process not debuggable: " + app.packageName);
12732 mTrackAllocationApp = processName;
12736 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12737 synchronized (this) {
12738 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12739 if (!isDebuggable) {
12740 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12741 throw new SecurityException("Process not debuggable: " + app.packageName);
12744 mProfileApp = processName;
12745 mProfileFile = profilerInfo.profileFile;
12746 if (mProfileFd != null) {
12748 mProfileFd.close();
12749 } catch (IOException e) {
12753 mProfileFd = profilerInfo.profileFd;
12754 mSamplingInterval = profilerInfo.samplingInterval;
12755 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12756 mStreamingOutput = profilerInfo.streamingOutput;
12761 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12762 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12763 if (!isDebuggable) {
12764 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12765 throw new SecurityException("Process not debuggable: " + app.packageName);
12768 mNativeDebuggingApp = processName;
12772 public void setAlwaysFinish(boolean enabled) {
12773 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12774 "setAlwaysFinish()");
12776 long ident = Binder.clearCallingIdentity();
12778 Settings.Global.putInt(
12779 mContext.getContentResolver(),
12780 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12782 synchronized (this) {
12783 mAlwaysFinishActivities = enabled;
12786 Binder.restoreCallingIdentity(ident);
12791 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12792 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12793 "setActivityController()");
12794 synchronized (this) {
12795 mController = controller;
12796 mControllerIsAMonkey = imAMonkey;
12797 Watchdog.getInstance().setActivityController(controller);
12802 public void setUserIsMonkey(boolean userIsMonkey) {
12803 synchronized (this) {
12804 synchronized (mPidsSelfLocked) {
12805 final int callingPid = Binder.getCallingPid();
12806 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12807 if (proc == null) {
12808 throw new SecurityException("Unknown process: " + callingPid);
12810 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12811 throw new SecurityException("Only an instrumentation process "
12812 + "with a UiAutomation can call setUserIsMonkey");
12815 mUserIsMonkey = userIsMonkey;
12820 public boolean isUserAMonkey() {
12821 synchronized (this) {
12822 // If there is a controller also implies the user is a monkey.
12823 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12828 * @deprecated This method is only used by a few internal components and it will soon be
12829 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12830 * No new code should be calling it.
12834 public void requestBugReport(int bugreportType) {
12835 String extraOptions = null;
12836 switch (bugreportType) {
12837 case ActivityManager.BUGREPORT_OPTION_FULL:
12838 // Default options.
12840 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12841 extraOptions = "bugreportplus";
12843 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12844 extraOptions = "bugreportremote";
12846 case ActivityManager.BUGREPORT_OPTION_WEAR:
12847 extraOptions = "bugreportwear";
12849 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12850 extraOptions = "bugreporttelephony";
12853 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12856 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12857 if (extraOptions != null) {
12858 SystemProperties.set("dumpstate.options", extraOptions);
12860 SystemProperties.set("ctl.start", "bugreport");
12864 * @deprecated This method is only used by a few internal components and it will soon be
12865 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12866 * No new code should be calling it.
12870 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12872 if (!TextUtils.isEmpty(shareTitle)) {
12873 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12874 String errorStr = "shareTitle should be less than " +
12875 MAX_BUGREPORT_TITLE_SIZE + " characters";
12876 throw new IllegalArgumentException(errorStr);
12878 if (!TextUtils.isEmpty(shareDescription)) {
12881 length = shareDescription.getBytes("UTF-8").length;
12882 } catch (UnsupportedEncodingException e) {
12883 String errorStr = "shareDescription: UnsupportedEncodingException";
12884 throw new IllegalArgumentException(errorStr);
12886 if (length > SystemProperties.PROP_VALUE_MAX) {
12887 String errorStr = "shareTitle should be less than " +
12888 SystemProperties.PROP_VALUE_MAX + " bytes";
12889 throw new IllegalArgumentException(errorStr);
12891 SystemProperties.set("dumpstate.options.description", shareDescription);
12894 SystemProperties.set("dumpstate.options.title", shareTitle);
12898 Slog.d(TAG, "Bugreport notification title " + shareTitle
12899 + " description " + shareDescription);
12900 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12903 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12904 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12907 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12908 if (r != null && (r.instr != null || r.usingWrapper)) {
12909 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12911 return KEY_DISPATCHING_TIMEOUT;
12915 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12916 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12917 != PackageManager.PERMISSION_GRANTED) {
12918 throw new SecurityException("Requires permission "
12919 + android.Manifest.permission.FILTER_EVENTS);
12921 ProcessRecord proc;
12923 synchronized (this) {
12924 synchronized (mPidsSelfLocked) {
12925 proc = mPidsSelfLocked.get(pid);
12927 timeout = getInputDispatchingTimeoutLocked(proc);
12930 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12938 * Handle input dispatching timeouts.
12939 * Returns whether input dispatching should be aborted or not.
12941 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12942 final ActivityRecord activity, final ActivityRecord parent,
12943 final boolean aboveSystem, String reason) {
12944 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12945 != PackageManager.PERMISSION_GRANTED) {
12946 throw new SecurityException("Requires permission "
12947 + android.Manifest.permission.FILTER_EVENTS);
12950 final String annotation;
12951 if (reason == null) {
12952 annotation = "Input dispatching timed out";
12954 annotation = "Input dispatching timed out (" + reason + ")";
12957 if (proc != null) {
12958 synchronized (this) {
12959 if (proc.debugging) {
12963 if (proc.instr != null) {
12964 Bundle info = new Bundle();
12965 info.putString("shortMsg", "keyDispatchingTimedOut");
12966 info.putString("longMsg", annotation);
12967 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12971 mHandler.post(new Runnable() {
12973 public void run() {
12974 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12983 public Bundle getAssistContextExtras(int requestType) {
12984 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12985 null, null, true /* focused */, true /* newSessionId */,
12986 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12990 synchronized (pae) {
12991 while (!pae.haveResult) {
12994 } catch (InterruptedException e) {
12998 synchronized (this) {
12999 buildAssistBundleLocked(pae, pae.result);
13000 mPendingAssistExtras.remove(pae);
13001 mUiHandler.removeCallbacks(pae);
13007 public boolean isAssistDataAllowedOnCurrentActivity() {
13009 synchronized (this) {
13010 final ActivityStack focusedStack = getFocusedStack();
13011 if (focusedStack == null || focusedStack.isAssistantStack()) {
13015 final ActivityRecord activity = focusedStack.topActivity();
13016 if (activity == null) {
13019 userId = activity.userId;
13021 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13022 Context.DEVICE_POLICY_SERVICE);
13023 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13027 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13028 long ident = Binder.clearCallingIdentity();
13030 synchronized (this) {
13031 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13032 ActivityRecord top = getFocusedStack().topActivity();
13033 if (top != caller) {
13034 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13035 + " is not current top " + top);
13038 if (!top.nowVisible) {
13039 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13040 + " is not visible");
13044 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13047 Binder.restoreCallingIdentity(ident);
13052 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13053 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13054 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13055 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13056 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13060 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13061 IBinder activityToken, int flags) {
13062 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13063 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13064 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13067 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13068 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13069 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13071 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13072 "enqueueAssistContext()");
13074 synchronized (this) {
13075 ActivityRecord activity = getFocusedStack().topActivity();
13076 if (activity == null) {
13077 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13080 if (activity.app == null || activity.app.thread == null) {
13081 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13085 if (activityToken != null) {
13086 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13087 if (activity != caller) {
13088 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13089 + " is not current top " + activity);
13094 activity = ActivityRecord.forTokenLocked(activityToken);
13095 if (activity == null) {
13096 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13097 + " couldn't be found");
13102 PendingAssistExtras pae;
13103 Bundle extras = new Bundle();
13104 if (args != null) {
13105 extras.putAll(args);
13107 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13108 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13110 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13112 pae.isHome = activity.isHomeActivity();
13114 // Increment the sessionId if necessary
13115 if (newSessionId) {
13119 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13120 mViSessionId, flags);
13121 mPendingAssistExtras.add(pae);
13122 mUiHandler.postDelayed(pae, timeout);
13123 } catch (RemoteException e) {
13124 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13131 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13132 IResultReceiver receiver;
13133 synchronized (this) {
13134 mPendingAssistExtras.remove(pae);
13135 receiver = pae.receiver;
13137 if (receiver != null) {
13138 // Caller wants result sent back to them.
13139 Bundle sendBundle = new Bundle();
13140 // At least return the receiver extras
13141 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13142 pae.receiverExtras);
13144 pae.receiver.send(0, sendBundle);
13145 } catch (RemoteException e) {
13150 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13151 if (result != null) {
13152 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13154 if (pae.hint != null) {
13155 pae.extras.putBoolean(pae.hint, true);
13159 /** Called from an app when assist data is ready. */
13161 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13162 AssistContent content, Uri referrer) {
13163 PendingAssistExtras pae = (PendingAssistExtras)token;
13164 synchronized (pae) {
13165 pae.result = extras;
13166 pae.structure = structure;
13167 pae.content = content;
13168 if (referrer != null) {
13169 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13171 if (structure != null) {
13172 structure.setHomeActivity(pae.isHome);
13174 pae.haveResult = true;
13176 if (pae.intent == null && pae.receiver == null) {
13177 // Caller is just waiting for the result.
13182 // We are now ready to launch the assist activity.
13183 IResultReceiver sendReceiver = null;
13184 Bundle sendBundle = null;
13185 synchronized (this) {
13186 buildAssistBundleLocked(pae, extras);
13187 boolean exists = mPendingAssistExtras.remove(pae);
13188 mUiHandler.removeCallbacks(pae);
13193 if ((sendReceiver=pae.receiver) != null) {
13194 // Caller wants result sent back to them.
13195 sendBundle = new Bundle();
13196 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13197 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13198 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13199 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13200 pae.receiverExtras);
13203 if (sendReceiver != null) {
13205 sendReceiver.send(0, sendBundle);
13206 } catch (RemoteException e) {
13211 long ident = Binder.clearCallingIdentity();
13213 pae.intent.replaceExtras(pae.extras);
13214 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13215 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13216 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13217 closeSystemDialogs("assist");
13219 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13220 } catch (ActivityNotFoundException e) {
13221 Slog.w(TAG, "No activity to handle assist action.", e);
13224 Binder.restoreCallingIdentity(ident);
13228 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13230 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13231 true /* focused */, true /* newSessionId */, userHandle, args,
13232 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13235 public void registerProcessObserver(IProcessObserver observer) {
13236 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13237 "registerProcessObserver()");
13238 synchronized (this) {
13239 mProcessObservers.register(observer);
13244 public void unregisterProcessObserver(IProcessObserver observer) {
13245 synchronized (this) {
13246 mProcessObservers.unregister(observer);
13251 public int getUidProcessState(int uid, String callingPackage) {
13252 if (!hasUsageStatsPermission(callingPackage)) {
13253 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13254 "getUidProcessState");
13257 synchronized (this) {
13258 UidRecord uidRec = mActiveUids.get(uid);
13259 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13264 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13265 String callingPackage) {
13266 if (!hasUsageStatsPermission(callingPackage)) {
13267 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13268 "registerUidObserver");
13270 synchronized (this) {
13271 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13272 callingPackage, which, cutpoint));
13277 public void unregisterUidObserver(IUidObserver observer) {
13278 synchronized (this) {
13279 mUidObservers.unregister(observer);
13284 public boolean convertFromTranslucent(IBinder token) {
13285 final long origId = Binder.clearCallingIdentity();
13287 synchronized (this) {
13288 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13292 final boolean translucentChanged = r.changeWindowTranslucency(true);
13293 if (translucentChanged) {
13294 r.getStack().releaseBackgroundResources(r);
13295 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13297 mWindowManager.setAppFullscreen(token, true);
13298 return translucentChanged;
13301 Binder.restoreCallingIdentity(origId);
13306 public boolean convertToTranslucent(IBinder token, Bundle options) {
13307 final long origId = Binder.clearCallingIdentity();
13309 synchronized (this) {
13310 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13314 final TaskRecord task = r.getTask();
13315 int index = task.mActivities.lastIndexOf(r);
13317 ActivityRecord under = task.mActivities.get(index - 1);
13318 under.returningOptions = ActivityOptions.fromBundle(options);
13320 final boolean translucentChanged = r.changeWindowTranslucency(false);
13321 if (translucentChanged) {
13322 r.getStack().convertActivityToTranslucent(r);
13324 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13325 mWindowManager.setAppFullscreen(token, false);
13326 return translucentChanged;
13329 Binder.restoreCallingIdentity(origId);
13334 public boolean requestVisibleBehind(IBinder token, boolean visible) {
13335 final long origId = Binder.clearCallingIdentity();
13337 synchronized (this) {
13338 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13340 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13345 Binder.restoreCallingIdentity(origId);
13350 public boolean isBackgroundVisibleBehind(IBinder token) {
13351 final long origId = Binder.clearCallingIdentity();
13353 synchronized (this) {
13354 final ActivityStack stack = ActivityRecord.getStackLocked(token);
13355 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13356 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13357 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13361 Binder.restoreCallingIdentity(origId);
13366 public Bundle getActivityOptions(IBinder token) {
13367 final long origId = Binder.clearCallingIdentity();
13369 synchronized (this) {
13370 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13372 final ActivityOptions activityOptions = r.pendingOptions;
13373 return activityOptions == null ? null : activityOptions.toBundle();
13378 Binder.restoreCallingIdentity(origId);
13383 public void setImmersive(IBinder token, boolean immersive) {
13384 synchronized(this) {
13385 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13387 throw new IllegalArgumentException();
13389 r.immersive = immersive;
13391 // update associated state if we're frontmost
13392 if (r == mStackSupervisor.getResumedActivityLocked()) {
13393 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13394 applyUpdateLockStateLocked(r);
13400 public boolean isImmersive(IBinder token) {
13401 synchronized (this) {
13402 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13404 throw new IllegalArgumentException();
13406 return r.immersive;
13411 public void setVrThread(int tid) {
13412 enforceSystemHasVrFeature();
13413 synchronized (this) {
13414 synchronized (mPidsSelfLocked) {
13415 final int pid = Binder.getCallingPid();
13416 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13417 mVrController.setVrThreadLocked(tid, pid, proc);
13423 public void setPersistentVrThread(int tid) {
13424 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13425 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13426 + Binder.getCallingPid()
13427 + ", uid=" + Binder.getCallingUid()
13428 + " requires " + permission.RESTRICTED_VR_ACCESS;
13430 throw new SecurityException(msg);
13432 enforceSystemHasVrFeature();
13433 synchronized (this) {
13434 synchronized (mPidsSelfLocked) {
13435 final int pid = Binder.getCallingPid();
13436 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13437 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13443 * Schedule the given thread a normal scheduling priority.
13445 * @param newTid the tid of the thread to adjust the scheduling of.
13446 * @param suppressLogs {@code true} if any error logging should be disabled.
13448 * @return {@code true} if this succeeded.
13450 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13452 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13454 } catch (IllegalArgumentException e) {
13455 if (!suppressLogs) {
13456 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13463 * Schedule the given thread an FIFO scheduling priority.
13465 * @param newTid the tid of the thread to adjust the scheduling of.
13466 * @param suppressLogs {@code true} if any error logging should be disabled.
13468 * @return {@code true} if this succeeded.
13470 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13472 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13474 } catch (IllegalArgumentException e) {
13475 if (!suppressLogs) {
13476 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13483 * Check that we have the features required for VR-related API calls, and throw an exception if
13486 private void enforceSystemHasVrFeature() {
13487 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13488 throw new UnsupportedOperationException("VR mode not supported on this device!");
13493 public void setRenderThread(int tid) {
13494 synchronized (this) {
13495 ProcessRecord proc;
13496 int pid = Binder.getCallingPid();
13497 if (pid == Process.myPid()) {
13498 demoteSystemServerRenderThread(tid);
13501 synchronized (mPidsSelfLocked) {
13502 proc = mPidsSelfLocked.get(pid);
13503 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13504 // ensure the tid belongs to the process
13505 if (!isThreadInProcess(pid, tid)) {
13506 throw new IllegalArgumentException(
13507 "Render thread does not belong to process");
13509 proc.renderThreadTid = tid;
13510 if (DEBUG_OOM_ADJ) {
13511 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13513 // promote to FIFO now
13514 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13515 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13516 if (mUseFifoUiScheduling) {
13517 setThreadScheduler(proc.renderThreadTid,
13518 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13520 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13524 if (DEBUG_OOM_ADJ) {
13525 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13526 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13527 mUseFifoUiScheduling);
13535 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13536 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13538 * @param tid the tid of the RenderThread
13540 private void demoteSystemServerRenderThread(int tid) {
13541 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13545 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13546 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13547 throw new UnsupportedOperationException("VR mode not supported on this device!");
13550 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13553 synchronized (this) {
13554 r = ActivityRecord.isInStackLocked(token);
13558 throw new IllegalArgumentException();
13562 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13563 VrManagerInternal.NO_ERROR) {
13567 synchronized(this) {
13568 r.requestedVrComponent = (enabled) ? packageName : null;
13570 // Update associated state if this activity is currently focused
13571 if (r == mStackSupervisor.getResumedActivityLocked()) {
13572 applyUpdateVrModeLocked(r);
13579 public boolean isVrModePackageEnabled(ComponentName packageName) {
13580 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13581 throw new UnsupportedOperationException("VR mode not supported on this device!");
13584 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13586 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13587 VrManagerInternal.NO_ERROR;
13590 public boolean isTopActivityImmersive() {
13591 enforceNotIsolatedCaller("startActivity");
13592 synchronized (this) {
13593 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13594 return (r != null) ? r.immersive : false;
13599 * @return whether the system should disable UI modes incompatible with VR mode.
13601 boolean shouldDisableNonVrUiLocked() {
13602 return mVrController.shouldDisableNonVrUiLocked();
13606 public boolean isTopOfTask(IBinder token) {
13607 synchronized (this) {
13608 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13610 throw new IllegalArgumentException();
13612 return r.getTask().getTopActivity() == r;
13617 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13618 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13619 String msg = "Permission Denial: setHasTopUi() from pid="
13620 + Binder.getCallingPid()
13621 + ", uid=" + Binder.getCallingUid()
13622 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13624 throw new SecurityException(msg);
13626 final int pid = Binder.getCallingPid();
13627 final long origId = Binder.clearCallingIdentity();
13629 synchronized (this) {
13630 boolean changed = false;
13632 synchronized (mPidsSelfLocked) {
13633 pr = mPidsSelfLocked.get(pid);
13635 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13638 if (pr.hasTopUi != hasTopUi) {
13639 if (DEBUG_OOM_ADJ) {
13640 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13642 pr.hasTopUi = hasTopUi;
13647 updateOomAdjLocked(pr, true);
13651 Binder.restoreCallingIdentity(origId);
13655 public final void enterSafeMode() {
13656 synchronized(this) {
13657 // It only makes sense to do this before the system is ready
13658 // and started launching other packages.
13659 if (!mSystemReady) {
13661 AppGlobals.getPackageManager().enterSafeMode();
13662 } catch (RemoteException e) {
13670 public final void showSafeModeOverlay() {
13671 View v = LayoutInflater.from(mContext).inflate(
13672 com.android.internal.R.layout.safe_mode, null);
13673 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13674 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13675 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13676 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13677 lp.gravity = Gravity.BOTTOM | Gravity.START;
13678 lp.format = v.getBackground().getOpacity();
13679 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13680 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13681 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13682 ((WindowManager)mContext.getSystemService(
13683 Context.WINDOW_SERVICE)).addView(v, lp);
13686 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, 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 if (mBatteryStatsService.isOnBattery()) {
13694 mBatteryStatsService.enforceCallingPermission();
13695 int MY_UID = Binder.getCallingUid();
13697 if (sender == null) {
13700 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13702 BatteryStatsImpl.Uid.Pkg pkg =
13703 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13704 sourcePkg != null ? sourcePkg : rec.key.packageName);
13705 pkg.noteWakeupAlarmLocked(tag);
13710 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13711 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13714 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13715 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13716 synchronized (stats) {
13717 mBatteryStatsService.enforceCallingPermission();
13718 int MY_UID = Binder.getCallingUid();
13720 if (sender == null) {
13723 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13725 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13729 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13730 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13733 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13734 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13735 synchronized (stats) {
13736 mBatteryStatsService.enforceCallingPermission();
13737 int MY_UID = Binder.getCallingUid();
13739 if (sender == null) {
13742 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13744 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13748 public boolean killPids(int[] pids, String pReason, boolean secure) {
13749 if (Binder.getCallingUid() != SYSTEM_UID) {
13750 throw new SecurityException("killPids only available to the system");
13752 String reason = (pReason == null) ? "Unknown" : pReason;
13753 // XXX Note: don't acquire main activity lock here, because the window
13754 // manager calls in with its locks held.
13756 boolean killed = false;
13757 synchronized (mPidsSelfLocked) {
13759 for (int i=0; i<pids.length; i++) {
13760 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13761 if (proc != null) {
13762 int type = proc.setAdj;
13763 if (type > worstType) {
13769 // If the worst oom_adj is somewhere in the cached proc LRU range,
13770 // then constrain it so we will kill all cached procs.
13771 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13772 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13773 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13776 // If this is not a secure call, don't let it kill processes that
13778 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13779 worstType = ProcessList.SERVICE_ADJ;
13782 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13783 for (int i=0; i<pids.length; i++) {
13784 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13785 if (proc == null) {
13788 int adj = proc.setAdj;
13789 if (adj >= worstType && !proc.killedByAm) {
13790 proc.kill(reason, true);
13799 public void killUid(int appId, int userId, String reason) {
13800 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13801 synchronized (this) {
13802 final long identity = Binder.clearCallingIdentity();
13804 killPackageProcessesLocked(null, appId, userId,
13805 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13806 reason != null ? reason : "kill uid");
13808 Binder.restoreCallingIdentity(identity);
13814 public boolean killProcessesBelowForeground(String reason) {
13815 if (Binder.getCallingUid() != SYSTEM_UID) {
13816 throw new SecurityException("killProcessesBelowForeground() only available to system");
13819 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13822 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13823 if (Binder.getCallingUid() != SYSTEM_UID) {
13824 throw new SecurityException("killProcessesBelowAdj() only available to system");
13827 boolean killed = false;
13828 synchronized (mPidsSelfLocked) {
13829 final int size = mPidsSelfLocked.size();
13830 for (int i = 0; i < size; i++) {
13831 final int pid = mPidsSelfLocked.keyAt(i);
13832 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13833 if (proc == null) continue;
13835 final int adj = proc.setAdj;
13836 if (adj > belowAdj && !proc.killedByAm) {
13837 proc.kill(reason, true);
13846 public void hang(final IBinder who, boolean allowRestart) {
13847 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13848 != PackageManager.PERMISSION_GRANTED) {
13849 throw new SecurityException("Requires permission "
13850 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13853 final IBinder.DeathRecipient death = new DeathRecipient() {
13855 public void binderDied() {
13856 synchronized (this) {
13863 who.linkToDeath(death, 0);
13864 } catch (RemoteException e) {
13865 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13869 synchronized (this) {
13870 Watchdog.getInstance().setAllowRestart(allowRestart);
13871 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13872 synchronized (death) {
13873 while (who.isBinderAlive()) {
13876 } catch (InterruptedException e) {
13880 Watchdog.getInstance().setAllowRestart(true);
13885 public void restart() {
13886 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13887 != PackageManager.PERMISSION_GRANTED) {
13888 throw new SecurityException("Requires permission "
13889 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13892 Log.i(TAG, "Sending shutdown broadcast...");
13894 BroadcastReceiver br = new BroadcastReceiver() {
13895 @Override public void onReceive(Context context, Intent intent) {
13896 // Now the broadcast is done, finish up the low-level shutdown.
13897 Log.i(TAG, "Shutting down activity manager...");
13899 Log.i(TAG, "Shutdown complete, restarting!");
13900 killProcess(myPid());
13905 // First send the high-level shut down broadcast.
13906 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13907 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13908 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13909 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13910 mContext.sendOrderedBroadcastAsUser(intent,
13911 UserHandle.ALL, null, br, mHandler, 0, null, null);
13913 br.onReceive(mContext, intent);
13916 private long getLowRamTimeSinceIdle(long now) {
13917 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13921 public void performIdleMaintenance() {
13922 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13923 != PackageManager.PERMISSION_GRANTED) {
13924 throw new SecurityException("Requires permission "
13925 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13928 synchronized (this) {
13929 final long now = SystemClock.uptimeMillis();
13930 final long timeSinceLastIdle = now - mLastIdleTime;
13931 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13932 mLastIdleTime = now;
13933 mLowRamTimeSinceLastIdle = 0;
13934 if (mLowRamStartTime != 0) {
13935 mLowRamStartTime = now;
13938 StringBuilder sb = new StringBuilder(128);
13939 sb.append("Idle maintenance over ");
13940 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13941 sb.append(" low RAM for ");
13942 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13943 Slog.i(TAG, sb.toString());
13945 // If at least 1/3 of our time since the last idle period has been spent
13946 // with RAM low, then we want to kill processes.
13947 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13949 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13950 ProcessRecord proc = mLruProcesses.get(i);
13951 if (proc.notCachedSinceIdle) {
13952 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13953 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13954 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13955 if (doKilling && proc.initialIdlePss != 0
13956 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13957 sb = new StringBuilder(128);
13959 sb.append(proc.processName);
13960 sb.append(" in idle maint: pss=");
13961 sb.append(proc.lastPss);
13962 sb.append(", swapPss=");
13963 sb.append(proc.lastSwapPss);
13964 sb.append(", initialPss=");
13965 sb.append(proc.initialIdlePss);
13966 sb.append(", period=");
13967 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13968 sb.append(", lowRamPeriod=");
13969 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13970 Slog.wtfQuiet(TAG, sb.toString());
13971 proc.kill("idle maint (pss " + proc.lastPss
13972 + " from " + proc.initialIdlePss + ")", true);
13975 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13976 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13977 proc.notCachedSinceIdle = true;
13978 proc.initialIdlePss = 0;
13979 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13980 mTestPssMode, isSleepingLocked(), now);
13984 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13985 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13990 public void sendIdleJobTrigger() {
13991 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13992 != PackageManager.PERMISSION_GRANTED) {
13993 throw new SecurityException("Requires permission "
13994 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13997 final long ident = Binder.clearCallingIdentity();
13999 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14000 .setPackage("android")
14001 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14002 broadcastIntent(null, intent, null, null, 0, null, null, null,
14003 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14005 Binder.restoreCallingIdentity(ident);
14009 private void retrieveSettings() {
14010 final ContentResolver resolver = mContext.getContentResolver();
14011 final boolean freeformWindowManagement =
14012 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14013 || Settings.Global.getInt(
14014 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14015 final boolean supportsPictureInPicture =
14016 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14018 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14019 final boolean supportsSplitScreenMultiWindow =
14020 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14021 final boolean supportsMultiDisplay = mContext.getPackageManager()
14022 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14023 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14024 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14025 final boolean alwaysFinishActivities =
14026 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14027 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14028 final boolean forceResizable = Settings.Global.getInt(
14029 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14030 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14031 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14032 final boolean supportsLeanbackOnly =
14033 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14035 // Transfer any global setting for forcing RTL layout, into a System Property
14036 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14038 final Configuration configuration = new Configuration();
14039 Settings.System.getConfiguration(resolver, configuration);
14041 // This will take care of setting the correct layout direction flags
14042 configuration.setLayoutDirection(configuration.locale);
14045 synchronized (this) {
14046 mDebugApp = mOrigDebugApp = debugApp;
14047 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14048 mAlwaysFinishActivities = alwaysFinishActivities;
14049 mSupportsLeanbackOnly = supportsLeanbackOnly;
14050 mForceResizableActivities = forceResizable;
14051 final boolean multiWindowFormEnabled = freeformWindowManagement
14052 || supportsSplitScreenMultiWindow
14053 || supportsPictureInPicture
14054 || supportsMultiDisplay;
14055 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14056 mSupportsMultiWindow = true;
14057 mSupportsFreeformWindowManagement = freeformWindowManagement;
14058 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14059 mSupportsPictureInPicture = supportsPictureInPicture;
14060 mSupportsMultiDisplay = supportsMultiDisplay;
14062 mSupportsMultiWindow = false;
14063 mSupportsFreeformWindowManagement = false;
14064 mSupportsSplitScreenMultiWindow = false;
14065 mSupportsPictureInPicture = false;
14066 mSupportsMultiDisplay = false;
14068 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14069 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14070 // This happens before any activities are started, so we can change global configuration
14072 updateConfigurationLocked(configuration, null, true);
14073 final Configuration globalConfig = getGlobalConfiguration();
14074 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14076 // Load resources only after the current configuration has been set.
14077 final Resources res = mContext.getResources();
14078 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14079 mThumbnailWidth = res.getDimensionPixelSize(
14080 com.android.internal.R.dimen.thumbnail_width);
14081 mThumbnailHeight = res.getDimensionPixelSize(
14082 com.android.internal.R.dimen.thumbnail_height);
14083 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14084 com.android.internal.R.string.config_appsNotReportingCrashes));
14085 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14086 com.android.internal.R.bool.config_customUserSwitchUi);
14087 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14088 mFullscreenThumbnailScale = (float) res
14089 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14090 (float) globalConfig.screenWidthDp;
14092 mFullscreenThumbnailScale = res.getFraction(
14093 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14095 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14099 public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14100 traceLog.traceBegin("PhaseActivityManagerReady");
14101 synchronized(this) {
14102 if (mSystemReady) {
14103 // If we're done calling all the receivers, run the next "boot phase" passed in
14104 // by the SystemServer
14105 if (goingCallback != null) {
14106 goingCallback.run();
14111 mLocalDeviceIdleController
14112 = LocalServices.getService(DeviceIdleController.LocalService.class);
14113 mAssistUtils = new AssistUtils(mContext);
14114 mVrController.onSystemReady();
14115 // Make sure we have the current profile info, since it is needed for security checks.
14116 mUserController.onSystemReady();
14117 mRecentTasks.onSystemReadyLocked();
14118 mAppOpsService.systemReady();
14119 mSystemReady = true;
14122 ArrayList<ProcessRecord> procsToKill = null;
14123 synchronized(mPidsSelfLocked) {
14124 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14125 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14126 if (!isAllowedWhileBooting(proc.info)){
14127 if (procsToKill == null) {
14128 procsToKill = new ArrayList<ProcessRecord>();
14130 procsToKill.add(proc);
14135 synchronized(this) {
14136 if (procsToKill != null) {
14137 for (int i=procsToKill.size()-1; i>=0; i--) {
14138 ProcessRecord proc = procsToKill.get(i);
14139 Slog.i(TAG, "Removing system update proc: " + proc);
14140 removeProcessLocked(proc, true, false, "system update done");
14144 // Now that we have cleaned up any update processes, we
14145 // are ready to start launching real processes and know that
14146 // we won't trample on them any more.
14147 mProcessesReady = true;
14150 Slog.i(TAG, "System now ready");
14151 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14152 SystemClock.uptimeMillis());
14154 synchronized(this) {
14155 // Make sure we have no pre-ready processes sitting around.
14157 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14158 ResolveInfo ri = mContext.getPackageManager()
14159 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14161 CharSequence errorMsg = null;
14163 ActivityInfo ai = ri.activityInfo;
14164 ApplicationInfo app = ai.applicationInfo;
14165 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14166 mTopAction = Intent.ACTION_FACTORY_TEST;
14168 mTopComponent = new ComponentName(app.packageName,
14171 errorMsg = mContext.getResources().getText(
14172 com.android.internal.R.string.factorytest_not_system);
14175 errorMsg = mContext.getResources().getText(
14176 com.android.internal.R.string.factorytest_no_action);
14178 if (errorMsg != null) {
14181 mTopComponent = null;
14182 Message msg = Message.obtain();
14183 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14184 msg.getData().putCharSequence("msg", errorMsg);
14185 mUiHandler.sendMessage(msg);
14190 retrieveSettings();
14191 final int currentUserId;
14192 synchronized (this) {
14193 currentUserId = mUserController.getCurrentUserIdLocked();
14194 readGrantedUriPermissionsLocked();
14197 if (goingCallback != null) goingCallback.run();
14198 traceLog.traceBegin("ActivityManagerStartApps");
14199 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14200 Integer.toString(currentUserId), currentUserId);
14201 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14202 Integer.toString(currentUserId), currentUserId);
14203 mSystemServiceManager.startUser(currentUserId);
14205 synchronized (this) {
14206 // Only start up encryption-aware persistent apps; once user is
14207 // unlocked we'll come back around and start unaware apps
14208 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14210 // Start up initial activity.
14212 // Enable home activity for system user, so that the system can always boot. We don't
14213 // do this when the system user is not setup since the setup wizard should be the one
14214 // to handle home activity in this case.
14215 if (UserManager.isSplitSystemUser() &&
14216 Settings.Secure.getInt(mContext.getContentResolver(),
14217 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14218 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14220 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14221 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14222 UserHandle.USER_SYSTEM);
14223 } catch (RemoteException e) {
14224 throw e.rethrowAsRuntimeException();
14227 startHomeActivityLocked(currentUserId, "systemReady");
14230 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14231 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14232 + " data partition or your device will be unstable.");
14233 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14235 } catch (RemoteException e) {
14238 if (!Build.isBuildConsistent()) {
14239 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14240 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14243 long ident = Binder.clearCallingIdentity();
14245 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14246 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14247 | Intent.FLAG_RECEIVER_FOREGROUND);
14248 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14249 broadcastIntentLocked(null, null, intent,
14250 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14251 null, false, false, MY_PID, SYSTEM_UID,
14253 intent = new Intent(Intent.ACTION_USER_STARTING);
14254 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14255 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14256 broadcastIntentLocked(null, null, intent,
14257 null, new IIntentReceiver.Stub() {
14259 public void performReceive(Intent intent, int resultCode, String data,
14260 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14261 throws RemoteException {
14264 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14265 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14266 } catch (Throwable t) {
14267 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14269 Binder.restoreCallingIdentity(ident);
14271 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14272 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14273 traceLog.traceEnd(); // ActivityManagerStartApps
14274 traceLog.traceEnd(); // PhaseActivityManagerReady
14278 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14279 synchronized (this) {
14280 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14284 void skipCurrentReceiverLocked(ProcessRecord app) {
14285 for (BroadcastQueue queue : mBroadcastQueues) {
14286 queue.skipCurrentReceiverLocked(app);
14291 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14292 * The application process will exit immediately after this call returns.
14293 * @param app object of the crashing app, null for the system server
14294 * @param crashInfo describing the exception
14296 public void handleApplicationCrash(IBinder app,
14297 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14298 ProcessRecord r = findAppProcess(app, "Crash");
14299 final String processName = app == null ? "system_server"
14300 : (r == null ? "unknown" : r.processName);
14302 handleApplicationCrashInner("crash", r, processName, crashInfo);
14305 /* Native crash reporting uses this inner version because it needs to be somewhat
14306 * decoupled from the AM-managed cleanup lifecycle
14308 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14309 ApplicationErrorReport.CrashInfo crashInfo) {
14310 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14311 UserHandle.getUserId(Binder.getCallingUid()), processName,
14312 r == null ? -1 : r.info.flags,
14313 crashInfo.exceptionClassName,
14314 crashInfo.exceptionMessage,
14315 crashInfo.throwFileName,
14316 crashInfo.throwLineNumber);
14318 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14320 mAppErrors.crashApplication(r, crashInfo);
14323 public void handleApplicationStrictModeViolation(
14326 StrictMode.ViolationInfo info) {
14327 ProcessRecord r = findAppProcess(app, "StrictMode");
14332 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14333 Integer stackFingerprint = info.hashCode();
14334 boolean logIt = true;
14335 synchronized (mAlreadyLoggedViolatedStacks) {
14336 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14338 // TODO: sub-sample into EventLog for these, with
14339 // the info.durationMillis? Then we'd get
14340 // the relative pain numbers, without logging all
14341 // the stack traces repeatedly. We'd want to do
14342 // likewise in the client code, which also does
14343 // dup suppression, before the Binder call.
14345 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14346 mAlreadyLoggedViolatedStacks.clear();
14348 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14352 logStrictModeViolationToDropBox(r, info);
14356 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14357 AppErrorResult result = new AppErrorResult();
14358 synchronized (this) {
14359 final long origId = Binder.clearCallingIdentity();
14361 Message msg = Message.obtain();
14362 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14363 HashMap<String, Object> data = new HashMap<String, Object>();
14364 data.put("result", result);
14365 data.put("app", r);
14366 data.put("violationMask", violationMask);
14367 data.put("info", info);
14369 mUiHandler.sendMessage(msg);
14371 Binder.restoreCallingIdentity(origId);
14373 int res = result.get();
14374 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14378 // Depending on the policy in effect, there could be a bunch of
14379 // these in quick succession so we try to batch these together to
14380 // minimize disk writes, number of dropbox entries, and maximize
14381 // compression, by having more fewer, larger records.
14382 private void logStrictModeViolationToDropBox(
14383 ProcessRecord process,
14384 StrictMode.ViolationInfo info) {
14385 if (info == null) {
14388 final boolean isSystemApp = process == null ||
14389 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14390 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14391 final String processName = process == null ? "unknown" : process.processName;
14392 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14393 final DropBoxManager dbox = (DropBoxManager)
14394 mContext.getSystemService(Context.DROPBOX_SERVICE);
14396 // Exit early if the dropbox isn't configured to accept this report type.
14397 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14399 boolean bufferWasEmpty;
14400 boolean needsFlush;
14401 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14402 synchronized (sb) {
14403 bufferWasEmpty = sb.length() == 0;
14404 appendDropBoxProcessHeaders(process, processName, sb);
14405 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14406 sb.append("System-App: ").append(isSystemApp).append("\n");
14407 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14408 if (info.violationNumThisLoop != 0) {
14409 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14411 if (info.numAnimationsRunning != 0) {
14412 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14414 if (info.broadcastIntentAction != null) {
14415 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14417 if (info.durationMillis != -1) {
14418 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14420 if (info.numInstances != -1) {
14421 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14423 if (info.tags != null) {
14424 for (String tag : info.tags) {
14425 sb.append("Span-Tag: ").append(tag).append("\n");
14429 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14430 sb.append(info.crashInfo.stackTrace);
14433 if (info.message != null) {
14434 sb.append(info.message);
14438 // Only buffer up to ~64k. Various logging bits truncate
14440 needsFlush = (sb.length() > 64 * 1024);
14443 // Flush immediately if the buffer's grown too large, or this
14444 // is a non-system app. Non-system apps are isolated with a
14445 // different tag & policy and not batched.
14447 // Batching is useful during internal testing with
14448 // StrictMode settings turned up high. Without batching,
14449 // thousands of separate files could be created on boot.
14450 if (!isSystemApp || needsFlush) {
14451 new Thread("Error dump: " + dropboxTag) {
14453 public void run() {
14455 synchronized (sb) {
14456 report = sb.toString();
14457 sb.delete(0, sb.length());
14460 if (report.length() != 0) {
14461 dbox.addText(dropboxTag, report);
14468 // System app batching:
14469 if (!bufferWasEmpty) {
14470 // An existing dropbox-writing thread is outstanding, so
14471 // we don't need to start it up. The existing thread will
14472 // catch the buffer appends we just did.
14476 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14477 // (After this point, we shouldn't access AMS internal data structures.)
14478 new Thread("Error dump: " + dropboxTag) {
14480 public void run() {
14481 // 5 second sleep to let stacks arrive and be batched together
14483 Thread.sleep(5000); // 5 seconds
14484 } catch (InterruptedException e) {}
14486 String errorReport;
14487 synchronized (mStrictModeBuffer) {
14488 errorReport = mStrictModeBuffer.toString();
14489 if (errorReport.length() == 0) {
14492 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14493 mStrictModeBuffer.trimToSize();
14495 dbox.addText(dropboxTag, errorReport);
14501 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14502 * @param app object of the crashing app, null for the system server
14503 * @param tag reported by the caller
14504 * @param system whether this wtf is coming from the system
14505 * @param crashInfo describing the context of the error
14506 * @return true if the process should exit immediately (WTF is fatal)
14508 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14509 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14510 final int callingUid = Binder.getCallingUid();
14511 final int callingPid = Binder.getCallingPid();
14514 // If this is coming from the system, we could very well have low-level
14515 // system locks held, so we want to do this all asynchronously. And we
14516 // never want this to become fatal, so there is that too.
14517 mHandler.post(new Runnable() {
14518 @Override public void run() {
14519 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14525 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14528 final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14529 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14530 final boolean isSystem = (r == null) || r.persistent;
14532 if (isFatal && !isSystem) {
14533 mAppErrors.crashApplication(r, crashInfo);
14540 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14541 final ApplicationErrorReport.CrashInfo crashInfo) {
14542 final ProcessRecord r = findAppProcess(app, "WTF");
14543 final String processName = app == null ? "system_server"
14544 : (r == null ? "unknown" : r.processName);
14546 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14547 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14549 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14555 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14556 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14558 private ProcessRecord findAppProcess(IBinder app, String reason) {
14563 synchronized (this) {
14564 final int NP = mProcessNames.getMap().size();
14565 for (int ip=0; ip<NP; ip++) {
14566 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14567 final int NA = apps.size();
14568 for (int ia=0; ia<NA; ia++) {
14569 ProcessRecord p = apps.valueAt(ia);
14570 if (p.thread != null && p.thread.asBinder() == app) {
14576 Slog.w(TAG, "Can't find mystery application for " + reason
14577 + " from pid=" + Binder.getCallingPid()
14578 + " uid=" + Binder.getCallingUid() + ": " + app);
14584 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14585 * to append various headers to the dropbox log text.
14587 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14588 StringBuilder sb) {
14589 // Watchdog thread ends up invoking this function (with
14590 // a null ProcessRecord) to add the stack file to dropbox.
14591 // Do not acquire a lock on this (am) in such cases, as it
14592 // could cause a potential deadlock, if and when watchdog
14593 // is invoked due to unavailability of lock on am and it
14594 // would prevent watchdog from killing system_server.
14595 if (process == null) {
14596 sb.append("Process: ").append(processName).append("\n");
14599 // Note: ProcessRecord 'process' is guarded by the service
14600 // instance. (notably process.pkgList, which could otherwise change
14601 // concurrently during execution of this method)
14602 synchronized (this) {
14603 sb.append("Process: ").append(processName).append("\n");
14604 sb.append("PID: ").append(process.pid).append("\n");
14605 int flags = process.info.flags;
14606 IPackageManager pm = AppGlobals.getPackageManager();
14607 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14608 for (int ip=0; ip<process.pkgList.size(); ip++) {
14609 String pkg = process.pkgList.keyAt(ip);
14610 sb.append("Package: ").append(pkg);
14612 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14614 sb.append(" v").append(pi.versionCode);
14615 if (pi.versionName != null) {
14616 sb.append(" (").append(pi.versionName).append(")");
14619 } catch (RemoteException e) {
14620 Slog.e(TAG, "Error getting package info: " + pkg, e);
14627 private static String processClass(ProcessRecord process) {
14628 if (process == null || process.pid == MY_PID) {
14629 return "system_server";
14630 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14631 return "system_app";
14637 private volatile long mWtfClusterStart;
14638 private volatile int mWtfClusterCount;
14641 * Write a description of an error (crash, WTF, ANR) to the drop box.
14642 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14643 * @param process which caused the error, null means the system server
14644 * @param activity which triggered the error, null if unknown
14645 * @param parent activity related to the error, null if unknown
14646 * @param subject line related to the error, null if absent
14647 * @param report in long form describing the error, null if absent
14648 * @param dataFile text file to include in the report, null if none
14649 * @param crashInfo giving an application stack trace, null if absent
14651 public void addErrorToDropBox(String eventType,
14652 ProcessRecord process, String processName, ActivityRecord activity,
14653 ActivityRecord parent, String subject,
14654 final String report, final File dataFile,
14655 final ApplicationErrorReport.CrashInfo crashInfo) {
14656 // NOTE -- this must never acquire the ActivityManagerService lock,
14657 // otherwise the watchdog may be prevented from resetting the system.
14659 // Bail early if not published yet
14660 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14661 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14663 // Exit early if the dropbox isn't configured to accept this report type.
14664 final String dropboxTag = processClass(process) + "_" + eventType;
14665 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14667 // Rate-limit how often we're willing to do the heavy lifting below to
14668 // collect and record logs; currently 5 logs per 10 second period.
14669 final long now = SystemClock.elapsedRealtime();
14670 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14671 mWtfClusterStart = now;
14672 mWtfClusterCount = 1;
14674 if (mWtfClusterCount++ >= 5) return;
14677 final StringBuilder sb = new StringBuilder(1024);
14678 appendDropBoxProcessHeaders(process, processName, sb);
14679 if (process != null) {
14680 sb.append("Foreground: ")
14681 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14684 if (activity != null) {
14685 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14687 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14688 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14690 if (parent != null && parent != activity) {
14691 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14693 if (subject != null) {
14694 sb.append("Subject: ").append(subject).append("\n");
14696 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14697 if (Debug.isDebuggerConnected()) {
14698 sb.append("Debugger: Connected\n");
14702 // Do the rest in a worker thread to avoid blocking the caller on I/O
14703 // (After this point, we shouldn't access AMS internal data structures.)
14704 Thread worker = new Thread("Error dump: " + dropboxTag) {
14706 public void run() {
14707 if (report != null) {
14711 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14712 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14713 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14714 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14716 if (dataFile != null && maxDataFileSize > 0) {
14718 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14719 "\n\n[[TRUNCATED]]"));
14720 } catch (IOException e) {
14721 Slog.e(TAG, "Error reading " + dataFile, e);
14724 if (crashInfo != null && crashInfo.stackTrace != null) {
14725 sb.append(crashInfo.stackTrace);
14731 // Merge several logcat streams, and take the last N lines
14732 InputStreamReader input = null;
14734 java.lang.Process logcat = new ProcessBuilder(
14735 "/system/bin/timeout", "-k", "15s", "10s",
14736 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14737 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14738 .redirectErrorStream(true).start();
14740 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14741 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14742 input = new InputStreamReader(logcat.getInputStream());
14745 char[] buf = new char[8192];
14746 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14747 } catch (IOException e) {
14748 Slog.e(TAG, "Error running logcat", e);
14750 if (input != null) try { input.close(); } catch (IOException e) {}
14754 dbox.addText(dropboxTag, sb.toString());
14758 if (process == null) {
14759 // If process is null, we are being called from some internal code
14760 // and may be about to die -- run this synchronously.
14768 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14769 enforceNotIsolatedCaller("getProcessesInErrorState");
14770 // assume our apps are happy - lazy create the list
14771 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14773 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14774 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14775 int userId = UserHandle.getUserId(Binder.getCallingUid());
14777 synchronized (this) {
14779 // iterate across all processes
14780 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14781 ProcessRecord app = mLruProcesses.get(i);
14782 if (!allUsers && app.userId != userId) {
14785 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14786 // This one's in trouble, so we'll generate a report for it
14787 // crashes are higher priority (in case there's a crash *and* an anr)
14788 ActivityManager.ProcessErrorStateInfo report = null;
14789 if (app.crashing) {
14790 report = app.crashingReport;
14791 } else if (app.notResponding) {
14792 report = app.notRespondingReport;
14795 if (report != null) {
14796 if (errList == null) {
14797 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14799 errList.add(report);
14801 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14802 " crashing = " + app.crashing +
14803 " notResponding = " + app.notResponding);
14812 static int procStateToImportance(int procState, int memAdj,
14813 ActivityManager.RunningAppProcessInfo currApp,
14814 int clientTargetSdk) {
14815 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14816 procState, clientTargetSdk);
14817 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14818 currApp.lru = memAdj;
14825 private void fillInProcMemInfo(ProcessRecord app,
14826 ActivityManager.RunningAppProcessInfo outInfo,
14827 int clientTargetSdk) {
14828 outInfo.pid = app.pid;
14829 outInfo.uid = app.info.uid;
14830 if (mHeavyWeightProcess == app) {
14831 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14833 if (app.persistent) {
14834 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14836 if (app.activities.size() > 0) {
14837 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14839 outInfo.lastTrimLevel = app.trimMemoryLevel;
14840 int adj = app.curAdj;
14841 int procState = app.curProcState;
14842 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14843 outInfo.importanceReasonCode = app.adjTypeCode;
14844 outInfo.processState = app.curProcState;
14848 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14849 enforceNotIsolatedCaller("getRunningAppProcesses");
14851 final int callingUid = Binder.getCallingUid();
14852 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14854 // Lazy instantiation of list
14855 List<ActivityManager.RunningAppProcessInfo> runList = null;
14856 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14857 callingUid) == PackageManager.PERMISSION_GRANTED;
14858 final int userId = UserHandle.getUserId(callingUid);
14859 final boolean allUids = isGetTasksAllowed(
14860 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14862 synchronized (this) {
14863 // Iterate across all processes
14864 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14865 ProcessRecord app = mLruProcesses.get(i);
14866 if ((!allUsers && app.userId != userId)
14867 || (!allUids && app.uid != callingUid)) {
14870 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14871 // Generate process state info for running application
14872 ActivityManager.RunningAppProcessInfo currApp =
14873 new ActivityManager.RunningAppProcessInfo(app.processName,
14874 app.pid, app.getPackageList());
14875 fillInProcMemInfo(app, currApp, clientTargetSdk);
14876 if (app.adjSource instanceof ProcessRecord) {
14877 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14878 currApp.importanceReasonImportance =
14879 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14880 app.adjSourceProcState);
14881 } else if (app.adjSource instanceof ActivityRecord) {
14882 ActivityRecord r = (ActivityRecord)app.adjSource;
14883 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14885 if (app.adjTarget instanceof ComponentName) {
14886 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14888 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14889 // + " lru=" + currApp.lru);
14890 if (runList == null) {
14891 runList = new ArrayList<>();
14893 runList.add(currApp);
14901 public List<ApplicationInfo> getRunningExternalApplications() {
14902 enforceNotIsolatedCaller("getRunningExternalApplications");
14903 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14904 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14905 if (runningApps != null && runningApps.size() > 0) {
14906 Set<String> extList = new HashSet<String>();
14907 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14908 if (app.pkgList != null) {
14909 for (String pkg : app.pkgList) {
14914 IPackageManager pm = AppGlobals.getPackageManager();
14915 for (String pkg : extList) {
14917 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14918 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14921 } catch (RemoteException e) {
14929 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14930 enforceNotIsolatedCaller("getMyMemoryState");
14932 final int callingUid = Binder.getCallingUid();
14933 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14935 synchronized (this) {
14936 ProcessRecord proc;
14937 synchronized (mPidsSelfLocked) {
14938 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14940 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14945 public int getMemoryTrimLevel() {
14946 enforceNotIsolatedCaller("getMyMemoryState");
14947 synchronized (this) {
14948 return mLastMemoryLevel;
14953 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14954 FileDescriptor err, String[] args, ShellCallback callback,
14955 ResultReceiver resultReceiver) {
14956 (new ActivityManagerShellCommand(this, false)).exec(
14957 this, in, out, err, args, callback, resultReceiver);
14961 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14962 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14964 boolean dumpAll = false;
14965 boolean dumpClient = false;
14966 boolean dumpCheckin = false;
14967 boolean dumpCheckinFormat = false;
14968 boolean dumpVisibleStacksOnly = false;
14969 boolean dumpFocusedStackOnly = false;
14970 String dumpPackage = null;
14973 while (opti < args.length) {
14974 String opt = args[opti];
14975 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14979 if ("-a".equals(opt)) {
14981 } else if ("-c".equals(opt)) {
14983 } else if ("-v".equals(opt)) {
14984 dumpVisibleStacksOnly = true;
14985 } else if ("-f".equals(opt)) {
14986 dumpFocusedStackOnly = true;
14987 } else if ("-p".equals(opt)) {
14988 if (opti < args.length) {
14989 dumpPackage = args[opti];
14992 pw.println("Error: -p option requires package argument");
14996 } else if ("--checkin".equals(opt)) {
14997 dumpCheckin = dumpCheckinFormat = true;
14998 } else if ("-C".equals(opt)) {
14999 dumpCheckinFormat = true;
15000 } else if ("-h".equals(opt)) {
15001 ActivityManagerShellCommand.dumpHelp(pw, true);
15004 pw.println("Unknown argument: " + opt + "; use -h for help");
15008 long origId = Binder.clearCallingIdentity();
15009 boolean more = false;
15010 // Is the caller requesting to dump a particular piece of data?
15011 if (opti < args.length) {
15012 String cmd = args[opti];
15014 if ("activities".equals(cmd) || "a".equals(cmd)) {
15015 synchronized (this) {
15016 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15018 } else if ("lastanr".equals(cmd)) {
15019 synchronized (this) {
15020 dumpLastANRLocked(pw);
15022 } else if ("starter".equals(cmd)) {
15023 synchronized (this) {
15024 dumpActivityStarterLocked(pw);
15026 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15027 synchronized (this) {
15028 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15030 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15033 if (opti >= args.length) {
15035 newArgs = EMPTY_STRING_ARRAY;
15037 dumpPackage = args[opti];
15039 newArgs = new String[args.length - opti];
15040 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15041 args.length - opti);
15043 synchronized (this) {
15044 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15046 } else if ("broadcast-stats".equals(cmd)) {
15049 if (opti >= args.length) {
15051 newArgs = EMPTY_STRING_ARRAY;
15053 dumpPackage = args[opti];
15055 newArgs = new String[args.length - opti];
15056 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15057 args.length - opti);
15059 synchronized (this) {
15060 if (dumpCheckinFormat) {
15061 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15064 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15067 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15070 if (opti >= args.length) {
15072 newArgs = EMPTY_STRING_ARRAY;
15074 dumpPackage = args[opti];
15076 newArgs = new String[args.length - opti];
15077 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15078 args.length - opti);
15080 synchronized (this) {
15081 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15083 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15086 if (opti >= args.length) {
15088 newArgs = EMPTY_STRING_ARRAY;
15090 dumpPackage = args[opti];
15092 newArgs = new String[args.length - opti];
15093 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15094 args.length - opti);
15096 synchronized (this) {
15097 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15099 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15100 synchronized (this) {
15101 dumpOomLocked(fd, pw, args, opti, true);
15103 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15104 synchronized (this) {
15105 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15107 } else if ("provider".equals(cmd)) {
15110 if (opti >= args.length) {
15112 newArgs = EMPTY_STRING_ARRAY;
15116 newArgs = new String[args.length - opti];
15117 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15119 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15120 pw.println("No providers match: " + name);
15121 pw.println("Use -h for help.");
15123 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15124 synchronized (this) {
15125 dumpProvidersLocked(fd, pw, args, opti, true, null);
15127 } else if ("service".equals(cmd)) {
15130 if (opti >= args.length) {
15132 newArgs = EMPTY_STRING_ARRAY;
15136 newArgs = new String[args.length - opti];
15137 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15138 args.length - opti);
15140 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15141 pw.println("No services match: " + name);
15142 pw.println("Use -h for help.");
15144 } else if ("package".equals(cmd)) {
15146 if (opti >= args.length) {
15147 pw.println("package: no package name specified");
15148 pw.println("Use -h for help.");
15150 dumpPackage = args[opti];
15152 newArgs = new String[args.length - opti];
15153 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15154 args.length - opti);
15159 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15160 synchronized (this) {
15161 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15163 } else if ("settings".equals(cmd)) {
15164 synchronized (this) {
15165 mConstants.dump(pw);
15167 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15169 ActiveServices.ServiceDumper dumper;
15170 synchronized (this) {
15171 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15174 dumper.dumpWithClient();
15176 synchronized (this) {
15177 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15178 dumpPackage).dumpLocked();
15181 } else if ("locks".equals(cmd)) {
15182 LockGuard.dump(fd, pw, args);
15184 // Dumping a single activity?
15185 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15186 dumpFocusedStackOnly)) {
15187 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15188 int res = shell.exec(this, null, fd, null, args, null,
15189 new ResultReceiver(null));
15191 pw.println("Bad activity command, or no activities match: " + cmd);
15192 pw.println("Use -h for help.");
15197 Binder.restoreCallingIdentity(origId);
15202 // No piece of data specified, dump everything.
15203 if (dumpCheckinFormat) {
15204 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15205 } else if (dumpClient) {
15206 ActiveServices.ServiceDumper sdumper;
15207 synchronized (this) {
15208 mConstants.dump(pw);
15211 pw.println("-------------------------------------------------------------------------------");
15213 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15216 pw.println("-------------------------------------------------------------------------------");
15218 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15221 pw.println("-------------------------------------------------------------------------------");
15223 if (dumpAll || dumpPackage != null) {
15224 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15227 pw.println("-------------------------------------------------------------------------------");
15230 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15233 pw.println("-------------------------------------------------------------------------------");
15235 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15238 pw.println("-------------------------------------------------------------------------------");
15240 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15243 sdumper.dumpWithClient();
15245 synchronized (this) {
15247 pw.println("-------------------------------------------------------------------------------");
15249 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15252 pw.println("-------------------------------------------------------------------------------");
15254 dumpLastANRLocked(pw);
15257 pw.println("-------------------------------------------------------------------------------");
15259 dumpActivityStarterLocked(pw);
15262 pw.println("-------------------------------------------------------------------------------");
15264 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15265 if (mAssociations.size() > 0) {
15268 pw.println("-------------------------------------------------------------------------------");
15270 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15274 pw.println("-------------------------------------------------------------------------------");
15276 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15280 synchronized (this) {
15281 mConstants.dump(pw);
15284 pw.println("-------------------------------------------------------------------------------");
15286 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15289 pw.println("-------------------------------------------------------------------------------");
15291 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15294 pw.println("-------------------------------------------------------------------------------");
15296 if (dumpAll || dumpPackage != null) {
15297 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15300 pw.println("-------------------------------------------------------------------------------");
15303 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15306 pw.println("-------------------------------------------------------------------------------");
15308 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15311 pw.println("-------------------------------------------------------------------------------");
15313 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15317 pw.println("-------------------------------------------------------------------------------");
15319 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15322 pw.println("-------------------------------------------------------------------------------");
15324 dumpLastANRLocked(pw);
15327 pw.println("-------------------------------------------------------------------------------");
15329 dumpActivityStarterLocked(pw);
15332 pw.println("-------------------------------------------------------------------------------");
15334 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15335 if (mAssociations.size() > 0) {
15338 pw.println("-------------------------------------------------------------------------------");
15340 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15344 pw.println("-------------------------------------------------------------------------------");
15346 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15349 Binder.restoreCallingIdentity(origId);
15352 private void dumpLastANRLocked(PrintWriter pw) {
15353 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
15354 if (mLastANRState == null) {
15355 pw.println(" <no ANR has occurred since boot>");
15357 pw.println(mLastANRState);
15361 private void dumpActivityStarterLocked(PrintWriter pw) {
15362 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
15363 mActivityStarter.dump(pw, "");
15366 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15367 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15368 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15369 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15372 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15373 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15374 pw.println(header);
15376 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15378 boolean needSep = printedAnything;
15380 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15381 mStackSupervisor.getResumedActivityLocked(),
15382 dumpPackage, needSep, " ResumedActivity: ");
15384 printedAnything = true;
15388 if (dumpPackage == null) {
15392 printedAnything = true;
15393 mStackSupervisor.dump(pw, " ");
15396 if (!printedAnything) {
15397 pw.println(" (nothing)");
15401 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15402 int opti, boolean dumpAll, String dumpPackage) {
15403 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15405 boolean printedAnything = false;
15407 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15408 boolean printedHeader = false;
15410 final int N = mRecentTasks.size();
15411 for (int i=0; i<N; i++) {
15412 TaskRecord tr = mRecentTasks.get(i);
15413 if (dumpPackage != null) {
15414 if (tr.realActivity == null ||
15415 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15419 if (!printedHeader) {
15420 pw.println(" Recent tasks:");
15421 printedHeader = true;
15422 printedAnything = true;
15424 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15427 mRecentTasks.get(i).dump(pw, " ");
15432 if (!printedAnything) {
15433 pw.println(" (nothing)");
15437 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15438 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15439 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15442 if (dumpPackage != null) {
15443 IPackageManager pm = AppGlobals.getPackageManager();
15445 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15446 } catch (RemoteException e) {
15450 boolean printedAnything = false;
15452 final long now = SystemClock.uptimeMillis();
15454 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15455 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15456 = mAssociations.valueAt(i1);
15457 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15458 SparseArray<ArrayMap<String, Association>> sourceUids
15459 = targetComponents.valueAt(i2);
15460 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15461 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15462 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15463 Association ass = sourceProcesses.valueAt(i4);
15464 if (dumpPackage != null) {
15465 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15466 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15470 printedAnything = true;
15472 pw.print(ass.mTargetProcess);
15474 UserHandle.formatUid(pw, ass.mTargetUid);
15476 pw.print(ass.mSourceProcess);
15478 UserHandle.formatUid(pw, ass.mSourceUid);
15481 pw.print(ass.mTargetComponent.flattenToShortString());
15484 long dur = ass.mTime;
15485 if (ass.mNesting > 0) {
15486 dur += now - ass.mStartTime;
15488 TimeUtils.formatDuration(dur, pw);
15490 pw.print(ass.mCount);
15491 pw.print(" times)");
15493 for (int i=0; i<ass.mStateTimes.length; i++) {
15494 long amt = ass.mStateTimes[i];
15495 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15496 amt += now - ass.mLastStateUptime;
15500 pw.print(ProcessList.makeProcStateString(
15501 i + ActivityManager.MIN_PROCESS_STATE));
15503 TimeUtils.formatDuration(amt, pw);
15504 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15510 if (ass.mNesting > 0) {
15511 pw.print(" Currently active: ");
15512 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15521 if (!printedAnything) {
15522 pw.println(" (nothing)");
15526 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15527 String header, boolean needSep) {
15528 boolean printed = false;
15529 int whichAppId = -1;
15530 if (dumpPackage != null) {
15532 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15534 whichAppId = UserHandle.getAppId(info.uid);
15535 } catch (NameNotFoundException e) {
15536 e.printStackTrace();
15539 for (int i=0; i<uids.size(); i++) {
15540 UidRecord uidRec = uids.valueAt(i);
15541 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15550 pw.println(header);
15553 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15554 pw.print(": "); pw.println(uidRec);
15559 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15560 int opti, boolean dumpAll, String dumpPackage) {
15561 boolean needSep = false;
15562 boolean printedAnything = false;
15565 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15568 final int NP = mProcessNames.getMap().size();
15569 for (int ip=0; ip<NP; ip++) {
15570 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15571 final int NA = procs.size();
15572 for (int ia=0; ia<NA; ia++) {
15573 ProcessRecord r = procs.valueAt(ia);
15574 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15578 pw.println(" All known processes:");
15580 printedAnything = true;
15582 pw.print(r.persistent ? " *PERS*" : " *APP*");
15583 pw.print(" UID "); pw.print(procs.keyAt(ia));
15584 pw.print(" "); pw.println(r);
15586 if (r.persistent) {
15593 if (mIsolatedProcesses.size() > 0) {
15594 boolean printed = false;
15595 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15596 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15597 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15604 pw.println(" Isolated process list (sorted by uid):");
15605 printedAnything = true;
15609 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15614 if (mActiveInstrumentation.size() > 0) {
15615 boolean printed = false;
15616 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15617 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15618 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15619 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15626 pw.println(" Active instrumentation:");
15627 printedAnything = true;
15631 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15637 if (mActiveUids.size() > 0) {
15638 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15639 printedAnything = needSep = true;
15643 if (mValidateUids.size() > 0) {
15644 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15645 printedAnything = needSep = true;
15650 if (mLruProcesses.size() > 0) {
15654 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15655 pw.print(" total, non-act at ");
15656 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15657 pw.print(", non-svc at ");
15658 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15660 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15662 printedAnything = true;
15665 if (dumpAll || dumpPackage != null) {
15666 synchronized (mPidsSelfLocked) {
15667 boolean printed = false;
15668 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15669 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15670 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15674 if (needSep) pw.println();
15676 pw.println(" PID mappings:");
15678 printedAnything = true;
15680 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15681 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15686 if (mImportantProcesses.size() > 0) {
15687 synchronized (mPidsSelfLocked) {
15688 boolean printed = false;
15689 for (int i = 0; i< mImportantProcesses.size(); i++) {
15690 ProcessRecord r = mPidsSelfLocked.get(
15691 mImportantProcesses.valueAt(i).pid);
15692 if (dumpPackage != null && (r == null
15693 || !r.pkgList.containsKey(dumpPackage))) {
15697 if (needSep) pw.println();
15699 pw.println(" Foreground Processes:");
15701 printedAnything = true;
15703 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15704 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15709 if (mPersistentStartingProcesses.size() > 0) {
15710 if (needSep) pw.println();
15712 printedAnything = true;
15713 pw.println(" Persisent processes that are starting:");
15714 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15715 "Starting Norm", "Restarting PERS", dumpPackage);
15718 if (mRemovedProcesses.size() > 0) {
15719 if (needSep) pw.println();
15721 printedAnything = true;
15722 pw.println(" Processes that are being removed:");
15723 dumpProcessList(pw, this, mRemovedProcesses, " ",
15724 "Removed Norm", "Removed PERS", dumpPackage);
15727 if (mProcessesOnHold.size() > 0) {
15728 if (needSep) pw.println();
15730 printedAnything = true;
15731 pw.println(" Processes that are on old until the system is ready:");
15732 dumpProcessList(pw, this, mProcessesOnHold, " ",
15733 "OnHold Norm", "OnHold PERS", dumpPackage);
15736 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15738 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15740 printedAnything = true;
15743 if (dumpPackage == null) {
15746 mUserController.dump(pw, dumpAll);
15748 if (mHomeProcess != null && (dumpPackage == null
15749 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15754 pw.println(" mHomeProcess: " + mHomeProcess);
15756 if (mPreviousProcess != null && (dumpPackage == null
15757 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15762 pw.println(" mPreviousProcess: " + mPreviousProcess);
15765 StringBuilder sb = new StringBuilder(128);
15766 sb.append(" mPreviousProcessVisibleTime: ");
15767 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15770 if (mHeavyWeightProcess != null && (dumpPackage == null
15771 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15776 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15778 if (dumpPackage == null) {
15779 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15780 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15783 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15784 if (mCompatModePackages.getPackages().size() > 0) {
15785 boolean printed = false;
15786 for (Map.Entry<String, Integer> entry
15787 : mCompatModePackages.getPackages().entrySet()) {
15788 String pkg = entry.getKey();
15789 int mode = entry.getValue();
15790 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15794 pw.println(" mScreenCompatPackages:");
15797 pw.print(" "); pw.print(pkg); pw.print(": ");
15798 pw.print(mode); pw.println();
15801 final int NI = mUidObservers.getRegisteredCallbackCount();
15802 boolean printed = false;
15803 for (int i=0; i<NI; i++) {
15804 final UidObserverRegistration reg = (UidObserverRegistration)
15805 mUidObservers.getRegisteredCallbackCookie(i);
15806 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15808 pw.println(" mUidObservers:");
15811 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15812 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15813 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15816 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15819 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15822 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15823 pw.print(" STATE");
15824 pw.print(" (cut="); pw.print(reg.cutpoint);
15828 if (reg.lastProcStates != null) {
15829 final int NJ = reg.lastProcStates.size();
15830 for (int j=0; j<NJ; j++) {
15831 pw.print(" Last ");
15832 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15833 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15838 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15839 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15840 if (mPendingTempWhitelist.size() > 0) {
15841 pw.println(" mPendingTempWhitelist:");
15842 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15843 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15845 UserHandle.formatUid(pw, ptw.targetUid);
15847 TimeUtils.formatDuration(ptw.duration, pw);
15849 pw.println(ptw.tag);
15853 if (dumpPackage == null) {
15854 pw.println(" mWakefulness="
15855 + PowerManagerInternal.wakefulnessToString(mWakefulness));
15856 pw.println(" mSleepTokens=" + mSleepTokens);
15857 pw.println(" mSleeping=" + mSleeping);
15858 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15859 if (mRunningVoice != null) {
15860 pw.println(" mRunningVoice=" + mRunningVoice);
15861 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
15864 pw.println(" mVrController=" + mVrController);
15865 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15866 || mOrigWaitForDebugger) {
15867 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15868 || dumpPackage.equals(mOrigDebugApp)) {
15873 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15874 + " mDebugTransient=" + mDebugTransient
15875 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15878 if (mCurAppTimeTracker != null) {
15879 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
15881 if (mMemWatchProcesses.getMap().size() > 0) {
15882 pw.println(" Mem watch processes:");
15883 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15884 = mMemWatchProcesses.getMap();
15885 for (int i=0; i<procs.size(); i++) {
15886 final String proc = procs.keyAt(i);
15887 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15888 for (int j=0; j<uids.size(); j++) {
15893 StringBuilder sb = new StringBuilder();
15894 sb.append(" ").append(proc).append('/');
15895 UserHandle.formatUid(sb, uids.keyAt(j));
15896 Pair<Long, String> val = uids.valueAt(j);
15897 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15898 if (val.second != null) {
15899 sb.append(", report to ").append(val.second);
15901 pw.println(sb.toString());
15904 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15905 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15906 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15907 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15909 if (mTrackAllocationApp != null) {
15910 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15915 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
15918 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15919 || mProfileFd != null) {
15920 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15925 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15926 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15927 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15928 + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15929 pw.println(" mProfileType=" + mProfileType);
15932 if (mNativeDebuggingApp != null) {
15933 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15938 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
15941 if (dumpPackage == null) {
15942 if (mAlwaysFinishActivities) {
15943 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15945 if (mController != null) {
15946 pw.println(" mController=" + mController
15947 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15950 pw.println(" Total persistent processes: " + numPers);
15951 pw.println(" mProcessesReady=" + mProcessesReady
15952 + " mSystemReady=" + mSystemReady
15953 + " mBooted=" + mBooted
15954 + " mFactoryTest=" + mFactoryTest);
15955 pw.println(" mBooting=" + mBooting
15956 + " mCallFinishBooting=" + mCallFinishBooting
15957 + " mBootAnimationComplete=" + mBootAnimationComplete);
15958 pw.print(" mLastPowerCheckRealtime=");
15959 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15961 pw.print(" mLastPowerCheckUptime=");
15962 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15964 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15965 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15966 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15967 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
15968 + " (" + mLruProcesses.size() + " total)"
15969 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15970 + " mNumServiceProcs=" + mNumServiceProcs
15971 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15972 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
15973 + " mLastMemoryLevel=" + mLastMemoryLevel
15974 + " mLastNumProcesses=" + mLastNumProcesses);
15975 long now = SystemClock.uptimeMillis();
15976 pw.print(" mLastIdleTime=");
15977 TimeUtils.formatDuration(now, mLastIdleTime, pw);
15978 pw.print(" mLowRamSinceLastIdle=");
15979 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15984 if (!printedAnything) {
15985 pw.println(" (nothing)");
15989 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15990 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15991 if (mProcessesToGc.size() > 0) {
15992 boolean printed = false;
15993 long now = SystemClock.uptimeMillis();
15994 for (int i=0; i<mProcessesToGc.size(); i++) {
15995 ProcessRecord proc = mProcessesToGc.get(i);
15996 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16000 if (needSep) pw.println();
16002 pw.println(" Processes that are waiting to GC:");
16005 pw.print(" Process "); pw.println(proc);
16006 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16007 pw.print(", last gced=");
16008 pw.print(now-proc.lastRequestedGc);
16009 pw.print(" ms ago, last lowMem=");
16010 pw.print(now-proc.lastLowMemory);
16011 pw.println(" ms ago");
16018 void printOomLevel(PrintWriter pw, String name, int adj) {
16022 if (adj < 10) pw.print(' ');
16024 if (adj > -10) pw.print(' ');
16030 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16034 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16035 int opti, boolean dumpAll) {
16036 boolean needSep = false;
16038 if (mLruProcesses.size() > 0) {
16039 if (needSep) pw.println();
16041 pw.println(" OOM levels:");
16042 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16043 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16044 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16045 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16046 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16047 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16048 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16049 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16050 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16051 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16052 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16053 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16054 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16055 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16057 if (needSep) pw.println();
16058 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16059 pw.print(" total, non-act at ");
16060 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16061 pw.print(", non-svc at ");
16062 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16064 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16068 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16071 pw.println(" mHomeProcess: " + mHomeProcess);
16072 pw.println(" mPreviousProcess: " + mPreviousProcess);
16073 if (mHeavyWeightProcess != null) {
16074 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16081 * There are three ways to call this:
16082 * - no provider specified: dump all the providers
16083 * - a flattened component name that matched an existing provider was specified as the
16084 * first arg: dump that one provider
16085 * - the first arg isn't the flattened component name of an existing provider:
16086 * dump all providers whose component contains the first arg as a substring
16088 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16089 int opti, boolean dumpAll) {
16090 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16093 static class ItemMatcher {
16094 ArrayList<ComponentName> components;
16095 ArrayList<String> strings;
16096 ArrayList<Integer> objects;
16103 void build(String name) {
16104 ComponentName componentName = ComponentName.unflattenFromString(name);
16105 if (componentName != null) {
16106 if (components == null) {
16107 components = new ArrayList<ComponentName>();
16109 components.add(componentName);
16113 // Not a '/' separated full component name; maybe an object ID?
16115 objectId = Integer.parseInt(name, 16);
16116 if (objects == null) {
16117 objects = new ArrayList<Integer>();
16119 objects.add(objectId);
16121 } catch (RuntimeException e) {
16122 // Not an integer; just do string match.
16123 if (strings == null) {
16124 strings = new ArrayList<String>();
16132 int build(String[] args, int opti) {
16133 for (; opti<args.length; opti++) {
16134 String name = args[opti];
16135 if ("--".equals(name)) {
16143 boolean match(Object object, ComponentName comp) {
16147 if (components != null) {
16148 for (int i=0; i<components.size(); i++) {
16149 if (components.get(i).equals(comp)) {
16154 if (objects != null) {
16155 for (int i=0; i<objects.size(); i++) {
16156 if (System.identityHashCode(object) == objects.get(i)) {
16161 if (strings != null) {
16162 String flat = comp.flattenToString();
16163 for (int i=0; i<strings.size(); i++) {
16164 if (flat.contains(strings.get(i))) {
16174 * There are three things that cmd can be:
16175 * - a flattened component name that matches an existing activity
16176 * - the cmd arg isn't the flattened component name of an existing activity:
16177 * dump all activity whose component contains the cmd as a substring
16178 * - A hex number of the ActivityRecord object instance.
16180 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16181 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16183 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16184 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16185 ArrayList<ActivityRecord> activities;
16187 synchronized (this) {
16188 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16189 dumpFocusedStackOnly);
16192 if (activities.size() <= 0) {
16196 String[] newArgs = new String[args.length - opti];
16197 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16199 TaskRecord lastTask = null;
16200 boolean needSep = false;
16201 for (int i=activities.size()-1; i>=0; i--) {
16202 ActivityRecord r = activities.get(i);
16207 synchronized (this) {
16208 final TaskRecord task = r.getTask();
16209 if (lastTask != task) {
16211 pw.print("TASK "); pw.print(lastTask.affinity);
16212 pw.print(" id="); pw.print(lastTask.taskId);
16213 pw.print(" userId="); pw.println(lastTask.userId);
16215 lastTask.dump(pw, " ");
16219 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16225 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16226 * there is a thread associated with the activity.
16228 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16229 final ActivityRecord r, String[] args, boolean dumpAll) {
16230 String innerPrefix = prefix + " ";
16231 synchronized (this) {
16232 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16233 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16235 if (r.app != null) pw.println(r.app.pid);
16236 else pw.println("(not running)");
16238 r.dump(pw, innerPrefix);
16241 if (r.app != null && r.app.thread != null) {
16242 // flush anything that is already in the PrintWriter since the thread is going
16243 // to write to the file descriptor directly
16246 TransferPipe tp = new TransferPipe();
16248 r.app.thread.dumpActivity(tp.getWriteFd(),
16249 r.appToken, innerPrefix, args);
16254 } catch (IOException e) {
16255 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16256 } catch (RemoteException e) {
16257 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16262 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16263 int opti, boolean dumpAll, String dumpPackage) {
16264 boolean needSep = false;
16265 boolean onlyHistory = false;
16266 boolean printedAnything = false;
16268 if ("history".equals(dumpPackage)) {
16269 if (opti < args.length && "-s".equals(args[opti])) {
16272 onlyHistory = true;
16273 dumpPackage = null;
16276 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16277 if (!onlyHistory && dumpAll) {
16278 if (mRegisteredReceivers.size() > 0) {
16279 boolean printed = false;
16280 Iterator it = mRegisteredReceivers.values().iterator();
16281 while (it.hasNext()) {
16282 ReceiverList r = (ReceiverList)it.next();
16283 if (dumpPackage != null && (r.app == null ||
16284 !dumpPackage.equals(r.app.info.packageName))) {
16288 pw.println(" Registered Receivers:");
16291 printedAnything = true;
16293 pw.print(" * "); pw.println(r);
16298 if (mReceiverResolver.dump(pw, needSep ?
16299 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16300 " ", dumpPackage, false, false)) {
16302 printedAnything = true;
16306 for (BroadcastQueue q : mBroadcastQueues) {
16307 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16308 printedAnything |= needSep;
16313 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16314 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16319 printedAnything = true;
16320 pw.print(" Sticky broadcasts for user ");
16321 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16322 StringBuilder sb = new StringBuilder(128);
16323 for (Map.Entry<String, ArrayList<Intent>> ent
16324 : mStickyBroadcasts.valueAt(user).entrySet()) {
16325 pw.print(" * Sticky action "); pw.print(ent.getKey());
16328 ArrayList<Intent> intents = ent.getValue();
16329 final int N = intents.size();
16330 for (int i=0; i<N; i++) {
16332 sb.append(" Intent: ");
16333 intents.get(i).toShortString(sb, false, true, false, false);
16334 pw.println(sb.toString());
16335 Bundle bundle = intents.get(i).getExtras();
16336 if (bundle != null) {
16338 pw.println(bundle.toString());
16348 if (!onlyHistory && dumpAll) {
16350 for (BroadcastQueue queue : mBroadcastQueues) {
16351 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16352 + queue.mBroadcastsScheduled);
16354 pw.println(" mHandler:");
16355 mHandler.dump(new PrintWriterPrinter(pw), " ");
16357 printedAnything = true;
16360 if (!printedAnything) {
16361 pw.println(" (nothing)");
16365 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16366 int opti, boolean dumpAll, String dumpPackage) {
16367 if (mCurBroadcastStats == null) {
16371 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16372 final long now = SystemClock.elapsedRealtime();
16373 if (mLastBroadcastStats != null) {
16374 pw.print(" Last stats (from ");
16375 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16377 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16379 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16380 - mLastBroadcastStats.mStartUptime, pw);
16381 pw.println(" uptime):");
16382 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16383 pw.println(" (nothing)");
16387 pw.print(" Current stats (from ");
16388 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16389 pw.print(" to now, ");
16390 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16391 - mCurBroadcastStats.mStartUptime, pw);
16392 pw.println(" uptime):");
16393 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16394 pw.println(" (nothing)");
16398 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16399 int opti, boolean fullCheckin, String dumpPackage) {
16400 if (mCurBroadcastStats == null) {
16404 if (mLastBroadcastStats != null) {
16405 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16407 mLastBroadcastStats = null;
16411 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16413 mCurBroadcastStats = null;
16417 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16418 int opti, boolean dumpAll, String dumpPackage) {
16420 boolean printedAnything = false;
16422 ItemMatcher matcher = new ItemMatcher();
16423 matcher.build(args, opti);
16425 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16427 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16428 printedAnything |= needSep;
16430 if (mLaunchingProviders.size() > 0) {
16431 boolean printed = false;
16432 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16433 ContentProviderRecord r = mLaunchingProviders.get(i);
16434 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16438 if (needSep) pw.println();
16440 pw.println(" Launching content providers:");
16442 printedAnything = true;
16444 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16449 if (!printedAnything) {
16450 pw.println(" (nothing)");
16454 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16455 int opti, boolean dumpAll, String dumpPackage) {
16456 boolean needSep = false;
16457 boolean printedAnything = false;
16459 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16461 if (mGrantedUriPermissions.size() > 0) {
16462 boolean printed = false;
16464 if (dumpPackage != null) {
16466 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16467 MATCH_ANY_USER, 0);
16468 } catch (NameNotFoundException e) {
16472 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16473 int uid = mGrantedUriPermissions.keyAt(i);
16474 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16477 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16479 if (needSep) pw.println();
16481 pw.println(" Granted Uri Permissions:");
16483 printedAnything = true;
16485 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16486 for (UriPermission perm : perms.values()) {
16487 pw.print(" "); pw.println(perm);
16489 perm.dump(pw, " ");
16495 if (!printedAnything) {
16496 pw.println(" (nothing)");
16500 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16501 int opti, boolean dumpAll, String dumpPackage) {
16502 boolean printed = false;
16504 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16506 if (mIntentSenderRecords.size() > 0) {
16507 // Organize these by package name, so they are easier to read.
16508 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16509 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16510 final Iterator<WeakReference<PendingIntentRecord>> it
16511 = mIntentSenderRecords.values().iterator();
16512 while (it.hasNext()) {
16513 WeakReference<PendingIntentRecord> ref = it.next();
16514 PendingIntentRecord rec = ref != null ? ref.get() : null;
16519 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16522 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16523 if (list == null) {
16524 list = new ArrayList<>();
16525 byPackage.put(rec.key.packageName, list);
16529 for (int i = 0; i < byPackage.size(); i++) {
16530 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16532 pw.print(" * "); pw.print(byPackage.keyAt(i));
16533 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16534 for (int j = 0; j < intents.size(); j++) {
16535 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16537 intents.get(j).dump(pw, " ");
16541 if (weakRefs.size() > 0) {
16543 pw.println(" * WEAK REFS:");
16544 for (int i = 0; i < weakRefs.size(); i++) {
16545 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16551 pw.println(" (nothing)");
16555 private static final int dumpProcessList(PrintWriter pw,
16556 ActivityManagerService service, List list,
16557 String prefix, String normalLabel, String persistentLabel,
16558 String dumpPackage) {
16560 final int N = list.size()-1;
16561 for (int i=N; i>=0; i--) {
16562 ProcessRecord r = (ProcessRecord)list.get(i);
16563 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16566 pw.println(String.format("%s%s #%2d: %s",
16567 prefix, (r.persistent ? persistentLabel : normalLabel),
16569 if (r.persistent) {
16576 private static final boolean dumpProcessOomList(PrintWriter pw,
16577 ActivityManagerService service, List<ProcessRecord> origList,
16578 String prefix, String normalLabel, String persistentLabel,
16579 boolean inclDetails, String dumpPackage) {
16581 ArrayList<Pair<ProcessRecord, Integer>> list
16582 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16583 for (int i=0; i<origList.size(); i++) {
16584 ProcessRecord r = origList.get(i);
16585 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16588 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16591 if (list.size() <= 0) {
16595 Comparator<Pair<ProcessRecord, Integer>> comparator
16596 = new Comparator<Pair<ProcessRecord, Integer>>() {
16598 public int compare(Pair<ProcessRecord, Integer> object1,
16599 Pair<ProcessRecord, Integer> object2) {
16600 if (object1.first.setAdj != object2.first.setAdj) {
16601 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16603 if (object1.first.setProcState != object2.first.setProcState) {
16604 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16606 if (object1.second.intValue() != object2.second.intValue()) {
16607 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16613 Collections.sort(list, comparator);
16615 final long curRealtime = SystemClock.elapsedRealtime();
16616 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16617 final long curUptime = SystemClock.uptimeMillis();
16618 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16620 for (int i=list.size()-1; i>=0; i--) {
16621 ProcessRecord r = list.get(i).first;
16622 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16624 switch (r.setSchedGroup) {
16625 case ProcessList.SCHED_GROUP_BACKGROUND:
16628 case ProcessList.SCHED_GROUP_DEFAULT:
16631 case ProcessList.SCHED_GROUP_TOP_APP:
16639 if (r.foregroundActivities) {
16641 } else if (r.foregroundServices) {
16646 String procState = ProcessList.makeProcStateString(r.curProcState);
16648 pw.print(r.persistent ? persistentLabel : normalLabel);
16650 int num = (origList.size()-1)-list.get(i).second;
16651 if (num < 10) pw.print(' ');
16656 pw.print(schedGroup);
16658 pw.print(foreground);
16660 pw.print(procState);
16662 if (r.trimMemoryLevel < 10) pw.print(' ');
16663 pw.print(r.trimMemoryLevel);
16665 pw.print(r.toShortString());
16667 pw.print(r.adjType);
16669 if (r.adjSource != null || r.adjTarget != null) {
16672 if (r.adjTarget instanceof ComponentName) {
16673 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16674 } else if (r.adjTarget != null) {
16675 pw.print(r.adjTarget.toString());
16677 pw.print("{null}");
16680 if (r.adjSource instanceof ProcessRecord) {
16682 pw.print(((ProcessRecord)r.adjSource).toShortString());
16684 } else if (r.adjSource != null) {
16685 pw.println(r.adjSource.toString());
16687 pw.println("{null}");
16693 pw.print("oom: max="); pw.print(r.maxAdj);
16694 pw.print(" curRaw="); pw.print(r.curRawAdj);
16695 pw.print(" setRaw="); pw.print(r.setRawAdj);
16696 pw.print(" cur="); pw.print(r.curAdj);
16697 pw.print(" set="); pw.println(r.setAdj);
16700 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16701 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16702 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16703 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16704 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16708 pw.print("cached="); pw.print(r.cached);
16709 pw.print(" empty="); pw.print(r.empty);
16710 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16712 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16713 if (r.lastWakeTime != 0) {
16715 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16716 synchronized (stats) {
16717 wtime = stats.getProcessWakeTime(r.info.uid,
16718 r.pid, curRealtime);
16720 long timeUsed = wtime - r.lastWakeTime;
16723 pw.print("keep awake over ");
16724 TimeUtils.formatDuration(realtimeSince, pw);
16725 pw.print(" used ");
16726 TimeUtils.formatDuration(timeUsed, pw);
16728 pw.print((timeUsed*100)/realtimeSince);
16731 if (r.lastCpuTime != 0) {
16732 long timeUsed = r.curCpuTime - r.lastCpuTime;
16735 pw.print("run cpu over ");
16736 TimeUtils.formatDuration(uptimeSince, pw);
16737 pw.print(" used ");
16738 TimeUtils.formatDuration(timeUsed, pw);
16740 pw.print((timeUsed*100)/uptimeSince);
16749 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16751 ArrayList<ProcessRecord> procs;
16752 synchronized (this) {
16753 if (args != null && args.length > start
16754 && args[start].charAt(0) != '-') {
16755 procs = new ArrayList<ProcessRecord>();
16758 pid = Integer.parseInt(args[start]);
16759 } catch (NumberFormatException e) {
16761 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16762 ProcessRecord proc = mLruProcesses.get(i);
16763 if (proc.pid == pid) {
16765 } else if (allPkgs && proc.pkgList != null
16766 && proc.pkgList.containsKey(args[start])) {
16768 } else if (proc.processName.equals(args[start])) {
16772 if (procs.size() <= 0) {
16776 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16782 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16783 PrintWriter pw, String[] args) {
16784 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16785 if (procs == null) {
16786 pw.println("No process found for: " + args[0]);
16790 long uptime = SystemClock.uptimeMillis();
16791 long realtime = SystemClock.elapsedRealtime();
16792 pw.println("Applications Graphics Acceleration Info:");
16793 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16795 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16796 ProcessRecord r = procs.get(i);
16797 if (r.thread != null) {
16798 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16801 TransferPipe tp = new TransferPipe();
16803 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16808 } catch (IOException e) {
16809 pw.println("Failure while dumping the app: " + r);
16811 } catch (RemoteException e) {
16812 pw.println("Got a RemoteException while dumping the app " + r);
16819 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16820 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16821 if (procs == null) {
16822 pw.println("No process found for: " + args[0]);
16826 pw.println("Applications Database Info:");
16828 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16829 ProcessRecord r = procs.get(i);
16830 if (r.thread != null) {
16831 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16834 TransferPipe tp = new TransferPipe();
16836 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16841 } catch (IOException e) {
16842 pw.println("Failure while dumping the app: " + r);
16844 } catch (RemoteException e) {
16845 pw.println("Got a RemoteException while dumping the app " + r);
16852 final static class MemItem {
16853 final boolean isProc;
16854 final String label;
16855 final String shortLabel;
16857 final long swapPss;
16859 final boolean hasActivities;
16860 ArrayList<MemItem> subitems;
16862 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16863 boolean _hasActivities) {
16866 shortLabel = _shortLabel;
16868 swapPss = _swapPss;
16870 hasActivities = _hasActivities;
16873 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16876 shortLabel = _shortLabel;
16878 swapPss = _swapPss;
16880 hasActivities = false;
16884 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16885 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16886 if (sort && !isCompact) {
16887 Collections.sort(items, new Comparator<MemItem>() {
16889 public int compare(MemItem lhs, MemItem rhs) {
16890 if (lhs.pss < rhs.pss) {
16892 } else if (lhs.pss > rhs.pss) {
16900 for (int i=0; i<items.size(); i++) {
16901 MemItem mi = items.get(i);
16904 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16905 mi.label, stringifyKBSize(mi.swapPss));
16907 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16909 } else if (mi.isProc) {
16910 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16911 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16912 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16913 pw.println(mi.hasActivities ? ",a" : ",e");
16915 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16916 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16918 if (mi.subitems != null) {
16919 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
16920 true, isCompact, dumpSwapPss);
16925 // These are in KB.
16926 static final long[] DUMP_MEM_BUCKETS = new long[] {
16927 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16928 120*1024, 160*1024, 200*1024,
16929 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16930 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16933 static final void appendMemBucket(StringBuilder out, long memKB, String label,
16934 boolean stackLike) {
16935 int start = label.lastIndexOf('.');
16936 if (start >= 0) start++;
16938 int end = label.length();
16939 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16940 if (DUMP_MEM_BUCKETS[i] >= memKB) {
16941 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16942 out.append(bucket);
16943 out.append(stackLike ? "MB." : "MB ");
16944 out.append(label, start, end);
16948 out.append(memKB/1024);
16949 out.append(stackLike ? "MB." : "MB ");
16950 out.append(label, start, end);
16953 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16954 ProcessList.NATIVE_ADJ,
16955 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16956 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16957 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16958 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16959 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16960 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16962 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16964 "System", "Persistent", "Persistent Service", "Foreground",
16965 "Visible", "Perceptible",
16966 "Heavy Weight", "Backup",
16967 "A Services", "Home",
16968 "Previous", "B Services", "Cached"
16970 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16972 "sys", "pers", "persvc", "fore",
16975 "servicea", "home",
16976 "prev", "serviceb", "cached"
16979 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16980 long realtime, boolean isCheckinRequest, boolean isCompact) {
16982 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16984 if (isCheckinRequest || isCompact) {
16985 // short checkin version
16986 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16988 pw.println("Applications Memory Usage (in Kilobytes):");
16989 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16993 private static final int KSM_SHARED = 0;
16994 private static final int KSM_SHARING = 1;
16995 private static final int KSM_UNSHARED = 2;
16996 private static final int KSM_VOLATILE = 3;
16998 private final long[] getKsmInfo() {
16999 long[] longOut = new long[4];
17000 final int[] SINGLE_LONG_FORMAT = new int[] {
17001 PROC_SPACE_TERM| PROC_OUT_LONG
17003 long[] longTmp = new long[1];
17004 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17005 SINGLE_LONG_FORMAT, null, longTmp, null);
17006 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17008 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17009 SINGLE_LONG_FORMAT, null, longTmp, null);
17010 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17012 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17013 SINGLE_LONG_FORMAT, null, longTmp, null);
17014 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17016 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17017 SINGLE_LONG_FORMAT, null, longTmp, null);
17018 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17022 private static String stringifySize(long size, int order) {
17023 Locale locale = Locale.US;
17026 return String.format(locale, "%,13d", size);
17028 return String.format(locale, "%,9dK", size / 1024);
17030 return String.format(locale, "%,5dM", size / 1024 / 1024);
17031 case 1024 * 1024 * 1024:
17032 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17034 throw new IllegalArgumentException("Invalid size order");
17038 private static String stringifyKBSize(long size) {
17039 return stringifySize(size * 1024, 1024);
17042 // Update this version number in case you change the 'compact' format
17043 private static final int MEMINFO_COMPACT_VERSION = 1;
17045 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17046 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17047 boolean dumpDetails = false;
17048 boolean dumpFullDetails = false;
17049 boolean dumpDalvik = false;
17050 boolean dumpSummaryOnly = false;
17051 boolean dumpUnreachable = false;
17052 boolean oomOnly = false;
17053 boolean isCompact = false;
17054 boolean localOnly = false;
17055 boolean packages = false;
17056 boolean isCheckinRequest = false;
17057 boolean dumpSwapPss = false;
17060 while (opti < args.length) {
17061 String opt = args[opti];
17062 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17066 if ("-a".equals(opt)) {
17067 dumpDetails = true;
17068 dumpFullDetails = true;
17070 dumpSwapPss = true;
17071 } else if ("-d".equals(opt)) {
17073 } else if ("-c".equals(opt)) {
17075 } else if ("-s".equals(opt)) {
17076 dumpDetails = true;
17077 dumpSummaryOnly = true;
17078 } else if ("-S".equals(opt)) {
17079 dumpSwapPss = true;
17080 } else if ("--unreachable".equals(opt)) {
17081 dumpUnreachable = true;
17082 } else if ("--oom".equals(opt)) {
17084 } else if ("--local".equals(opt)) {
17086 } else if ("--package".equals(opt)) {
17088 } else if ("--checkin".equals(opt)) {
17089 isCheckinRequest = true;
17091 } else if ("-h".equals(opt)) {
17092 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17093 pw.println(" -a: include all available information for each process.");
17094 pw.println(" -d: include dalvik details.");
17095 pw.println(" -c: dump in a compact machine-parseable representation.");
17096 pw.println(" -s: dump only summary of application memory usage.");
17097 pw.println(" -S: dump also SwapPss.");
17098 pw.println(" --oom: only show processes organized by oom adj.");
17099 pw.println(" --local: only collect details locally, don't call process.");
17100 pw.println(" --package: interpret process arg as package, dumping all");
17101 pw.println(" processes that have loaded that package.");
17102 pw.println(" --checkin: dump data for a checkin");
17103 pw.println("If [process] is specified it can be the name or ");
17104 pw.println("pid of a specific process to dump.");
17107 pw.println("Unknown argument: " + opt + "; use -h for help");
17111 long uptime = SystemClock.uptimeMillis();
17112 long realtime = SystemClock.elapsedRealtime();
17113 final long[] tmpLong = new long[1];
17115 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17116 if (procs == null) {
17117 // No Java processes. Maybe they want to print a native process.
17118 if (args != null && args.length > opti
17119 && args[opti].charAt(0) != '-') {
17120 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17121 = new ArrayList<ProcessCpuTracker.Stats>();
17122 updateCpuStatsNow();
17125 findPid = Integer.parseInt(args[opti]);
17126 } catch (NumberFormatException e) {
17128 synchronized (mProcessCpuTracker) {
17129 final int N = mProcessCpuTracker.countStats();
17130 for (int i=0; i<N; i++) {
17131 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17132 if (st.pid == findPid || (st.baseName != null
17133 && st.baseName.equals(args[opti]))) {
17134 nativeProcs.add(st);
17138 if (nativeProcs.size() > 0) {
17139 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17141 Debug.MemoryInfo mi = null;
17142 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17143 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17144 final int pid = r.pid;
17145 if (!isCheckinRequest && dumpDetails) {
17146 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17149 mi = new Debug.MemoryInfo();
17151 if (dumpDetails || (!brief && !oomOnly)) {
17152 Debug.getMemoryInfo(pid, mi);
17154 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17155 mi.dalvikPrivateDirty = (int)tmpLong[0];
17157 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17158 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17159 if (isCheckinRequest) {
17166 pw.println("No process found for: " + args[opti]);
17170 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17171 dumpDetails = true;
17174 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17176 String[] innerArgs = new String[args.length-opti];
17177 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17179 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17180 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17181 long nativePss = 0;
17182 long nativeSwapPss = 0;
17183 long dalvikPss = 0;
17184 long dalvikSwapPss = 0;
17185 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17187 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17190 long otherSwapPss = 0;
17191 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17192 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17194 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17195 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17196 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17197 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17200 long totalSwapPss = 0;
17201 long cachedPss = 0;
17202 long cachedSwapPss = 0;
17203 boolean hasSwapPss = false;
17205 Debug.MemoryInfo mi = null;
17206 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17207 final ProcessRecord r = procs.get(i);
17208 final IApplicationThread thread;
17211 final boolean hasActivities;
17212 synchronized (this) {
17215 oomAdj = r.getSetAdjWithServices();
17216 hasActivities = r.activities.size() > 0;
17218 if (thread != null) {
17219 if (!isCheckinRequest && dumpDetails) {
17220 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17223 mi = new Debug.MemoryInfo();
17225 if (dumpDetails || (!brief && !oomOnly)) {
17226 Debug.getMemoryInfo(pid, mi);
17227 hasSwapPss = mi.hasSwappedOutPss;
17229 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17230 mi.dalvikPrivateDirty = (int)tmpLong[0];
17234 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17235 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17236 if (isCheckinRequest) {
17242 TransferPipe tp = new TransferPipe();
17244 thread.dumpMemInfo(tp.getWriteFd(),
17245 mi, isCheckinRequest, dumpFullDetails,
17246 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17251 } catch (IOException e) {
17252 if (!isCheckinRequest) {
17253 pw.println("Got IoException!");
17256 } catch (RemoteException e) {
17257 if (!isCheckinRequest) {
17258 pw.println("Got RemoteException!");
17265 final long myTotalPss = mi.getTotalPss();
17266 final long myTotalUss = mi.getTotalUss();
17267 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17269 synchronized (this) {
17270 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17271 // Record this for posterity if the process has been stable.
17272 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17276 if (!isCheckinRequest && mi != null) {
17277 totalPss += myTotalPss;
17278 totalSwapPss += myTotalSwapPss;
17279 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17280 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17281 myTotalSwapPss, pid, hasActivities);
17282 procMems.add(pssItem);
17283 procMemsMap.put(pid, pssItem);
17285 nativePss += mi.nativePss;
17286 nativeSwapPss += mi.nativeSwappedOutPss;
17287 dalvikPss += mi.dalvikPss;
17288 dalvikSwapPss += mi.dalvikSwappedOutPss;
17289 for (int j=0; j<dalvikSubitemPss.length; j++) {
17290 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17291 dalvikSubitemSwapPss[j] +=
17292 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17294 otherPss += mi.otherPss;
17295 otherSwapPss += mi.otherSwappedOutPss;
17296 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17297 long mem = mi.getOtherPss(j);
17300 mem = mi.getOtherSwappedOutPss(j);
17301 miscSwapPss[j] += mem;
17302 otherSwapPss -= mem;
17305 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17306 cachedPss += myTotalPss;
17307 cachedSwapPss += myTotalSwapPss;
17310 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17311 if (oomIndex == (oomPss.length - 1)
17312 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17313 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17314 oomPss[oomIndex] += myTotalPss;
17315 oomSwapPss[oomIndex] += myTotalSwapPss;
17316 if (oomProcs[oomIndex] == null) {
17317 oomProcs[oomIndex] = new ArrayList<MemItem>();
17319 oomProcs[oomIndex].add(pssItem);
17327 long nativeProcTotalPss = 0;
17329 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17330 // If we are showing aggregations, also look for native processes to
17331 // include so that our aggregations are more accurate.
17332 updateCpuStatsNow();
17334 synchronized (mProcessCpuTracker) {
17335 final int N = mProcessCpuTracker.countStats();
17336 for (int i=0; i<N; i++) {
17337 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17338 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17340 mi = new Debug.MemoryInfo();
17342 if (!brief && !oomOnly) {
17343 Debug.getMemoryInfo(st.pid, mi);
17345 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17346 mi.nativePrivateDirty = (int)tmpLong[0];
17349 final long myTotalPss = mi.getTotalPss();
17350 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17351 totalPss += myTotalPss;
17352 nativeProcTotalPss += myTotalPss;
17354 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17355 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17356 procMems.add(pssItem);
17358 nativePss += mi.nativePss;
17359 nativeSwapPss += mi.nativeSwappedOutPss;
17360 dalvikPss += mi.dalvikPss;
17361 dalvikSwapPss += mi.dalvikSwappedOutPss;
17362 for (int j=0; j<dalvikSubitemPss.length; j++) {
17363 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17364 dalvikSubitemSwapPss[j] +=
17365 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17367 otherPss += mi.otherPss;
17368 otherSwapPss += mi.otherSwappedOutPss;
17369 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17370 long mem = mi.getOtherPss(j);
17373 mem = mi.getOtherSwappedOutPss(j);
17374 miscSwapPss[j] += mem;
17375 otherSwapPss -= mem;
17377 oomPss[0] += myTotalPss;
17378 oomSwapPss[0] += myTotalSwapPss;
17379 if (oomProcs[0] == null) {
17380 oomProcs[0] = new ArrayList<MemItem>();
17382 oomProcs[0].add(pssItem);
17387 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17389 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17390 final MemItem dalvikItem =
17391 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17392 if (dalvikSubitemPss.length > 0) {
17393 dalvikItem.subitems = new ArrayList<MemItem>();
17394 for (int j=0; j<dalvikSubitemPss.length; j++) {
17395 final String name = Debug.MemoryInfo.getOtherLabel(
17396 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17397 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17398 dalvikSubitemSwapPss[j], j));
17401 catMems.add(dalvikItem);
17402 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17403 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17404 String label = Debug.MemoryInfo.getOtherLabel(j);
17405 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17408 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17409 for (int j=0; j<oomPss.length; j++) {
17410 if (oomPss[j] != 0) {
17411 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17412 : DUMP_MEM_OOM_LABEL[j];
17413 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17414 DUMP_MEM_OOM_ADJ[j]);
17415 item.subitems = oomProcs[j];
17420 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17421 if (!brief && !oomOnly && !isCompact) {
17423 pw.println("Total PSS by process:");
17424 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17428 pw.println("Total PSS by OOM adjustment:");
17430 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17431 if (!brief && !oomOnly) {
17432 PrintWriter out = categoryPw != null ? categoryPw : pw;
17435 out.println("Total PSS by category:");
17437 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17442 MemInfoReader memInfo = new MemInfoReader();
17443 memInfo.readMemInfo();
17444 if (nativeProcTotalPss > 0) {
17445 synchronized (this) {
17446 final long cachedKb = memInfo.getCachedSizeKb();
17447 final long freeKb = memInfo.getFreeSizeKb();
17448 final long zramKb = memInfo.getZramTotalSizeKb();
17449 final long kernelKb = memInfo.getKernelUsedSizeKb();
17450 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17451 kernelKb*1024, nativeProcTotalPss*1024);
17452 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17453 nativeProcTotalPss);
17458 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17459 pw.print(" (status ");
17460 switch (mLastMemoryLevel) {
17461 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17462 pw.println("normal)");
17464 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17465 pw.println("moderate)");
17467 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17468 pw.println("low)");
17470 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17471 pw.println("critical)");
17474 pw.print(mLastMemoryLevel);
17478 pw.print(" Free RAM: ");
17479 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17480 + memInfo.getFreeSizeKb()));
17482 pw.print(stringifyKBSize(cachedPss));
17483 pw.print(" cached pss + ");
17484 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17485 pw.print(" cached kernel + ");
17486 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17487 pw.println(" free)");
17489 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17490 pw.print(cachedPss + memInfo.getCachedSizeKb()
17491 + memInfo.getFreeSizeKb()); pw.print(",");
17492 pw.println(totalPss - cachedPss);
17495 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17496 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17497 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17499 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17500 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17501 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17502 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17503 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17505 pw.print("lostram,"); pw.println(lostRAM);
17508 if (memInfo.getZramTotalSizeKb() != 0) {
17510 pw.print(" ZRAM: ");
17511 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17512 pw.print(" physical used for ");
17513 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17514 - memInfo.getSwapFreeSizeKb()));
17515 pw.print(" in swap (");
17516 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17517 pw.println(" total swap)");
17519 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17520 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17521 pw.println(memInfo.getSwapFreeSizeKb());
17524 final long[] ksm = getKsmInfo();
17526 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17527 || ksm[KSM_VOLATILE] != 0) {
17528 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17529 pw.print(" saved from shared ");
17530 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17531 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17532 pw.print(" unshared; ");
17533 pw.print(stringifyKBSize(
17534 ksm[KSM_VOLATILE])); pw.println(" volatile");
17536 pw.print(" Tuning: ");
17537 pw.print(ActivityManager.staticGetMemoryClass());
17538 pw.print(" (large ");
17539 pw.print(ActivityManager.staticGetLargeMemoryClass());
17540 pw.print("), oom ");
17541 pw.print(stringifySize(
17542 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17543 pw.print(", restore limit ");
17544 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17545 if (ActivityManager.isLowRamDeviceStatic()) {
17546 pw.print(" (low-ram)");
17548 if (ActivityManager.isHighEndGfx()) {
17549 pw.print(" (high-end-gfx)");
17553 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17554 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17555 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17556 pw.print("tuning,");
17557 pw.print(ActivityManager.staticGetMemoryClass());
17559 pw.print(ActivityManager.staticGetLargeMemoryClass());
17561 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17562 if (ActivityManager.isLowRamDeviceStatic()) {
17563 pw.print(",low-ram");
17565 if (ActivityManager.isHighEndGfx()) {
17566 pw.print(",high-end-gfx");
17574 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17575 long memtrack, String name) {
17577 sb.append(ProcessList.makeOomAdjString(oomAdj));
17579 sb.append(ProcessList.makeProcStateString(procState));
17581 ProcessList.appendRamKb(sb, pss);
17584 if (memtrack > 0) {
17586 sb.append(stringifyKBSize(memtrack));
17587 sb.append(" memtrack)");
17591 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17592 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17593 sb.append(" (pid ");
17596 sb.append(mi.adjType);
17598 if (mi.adjReason != null) {
17600 sb.append(mi.adjReason);
17605 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17606 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17607 for (int i=0, N=memInfos.size(); i<N; i++) {
17608 ProcessMemInfo mi = memInfos.get(i);
17609 infoMap.put(mi.pid, mi);
17611 updateCpuStatsNow();
17612 long[] memtrackTmp = new long[1];
17613 final List<ProcessCpuTracker.Stats> stats;
17614 // Get a list of Stats that have vsize > 0
17615 synchronized (mProcessCpuTracker) {
17616 stats = mProcessCpuTracker.getStats((st) -> {
17617 return st.vsize > 0;
17620 final int statsCount = stats.size();
17621 for (int i = 0; i < statsCount; i++) {
17622 ProcessCpuTracker.Stats st = stats.get(i);
17623 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17625 if (infoMap.indexOfKey(st.pid) < 0) {
17626 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17627 ProcessList.NATIVE_ADJ, -1, "native", null);
17629 mi.memtrack = memtrackTmp[0];
17636 long totalMemtrack = 0;
17637 for (int i=0, N=memInfos.size(); i<N; i++) {
17638 ProcessMemInfo mi = memInfos.get(i);
17640 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17641 mi.memtrack = memtrackTmp[0];
17643 totalPss += mi.pss;
17644 totalMemtrack += mi.memtrack;
17646 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17647 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17648 if (lhs.oomAdj != rhs.oomAdj) {
17649 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17651 if (lhs.pss != rhs.pss) {
17652 return lhs.pss < rhs.pss ? 1 : -1;
17658 StringBuilder tag = new StringBuilder(128);
17659 StringBuilder stack = new StringBuilder(128);
17660 tag.append("Low on memory -- ");
17661 appendMemBucket(tag, totalPss, "total", false);
17662 appendMemBucket(stack, totalPss, "total", true);
17664 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17665 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17666 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17668 boolean firstLine = true;
17669 int lastOomAdj = Integer.MIN_VALUE;
17670 long extraNativeRam = 0;
17671 long extraNativeMemtrack = 0;
17672 long cachedPss = 0;
17673 for (int i=0, N=memInfos.size(); i<N; i++) {
17674 ProcessMemInfo mi = memInfos.get(i);
17676 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17677 cachedPss += mi.pss;
17680 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17681 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17682 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17683 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17684 if (lastOomAdj != mi.oomAdj) {
17685 lastOomAdj = mi.oomAdj;
17686 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17689 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17694 stack.append("\n\t at ");
17702 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17703 appendMemBucket(tag, mi.pss, mi.name, false);
17705 appendMemBucket(stack, mi.pss, mi.name, true);
17706 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17707 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17709 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17710 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17711 stack.append(DUMP_MEM_OOM_LABEL[k]);
17713 stack.append(DUMP_MEM_OOM_ADJ[k]);
17720 appendMemInfo(fullNativeBuilder, mi);
17721 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17722 // The short form only has native processes that are >= 512K.
17723 if (mi.pss >= 512) {
17724 appendMemInfo(shortNativeBuilder, mi);
17726 extraNativeRam += mi.pss;
17727 extraNativeMemtrack += mi.memtrack;
17730 // Short form has all other details, but if we have collected RAM
17731 // from smaller native processes let's dump a summary of that.
17732 if (extraNativeRam > 0) {
17733 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17734 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17735 shortNativeBuilder.append('\n');
17736 extraNativeRam = 0;
17738 appendMemInfo(fullJavaBuilder, mi);
17742 fullJavaBuilder.append(" ");
17743 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17744 fullJavaBuilder.append(": TOTAL");
17745 if (totalMemtrack > 0) {
17746 fullJavaBuilder.append(" (");
17747 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17748 fullJavaBuilder.append(" memtrack)");
17751 fullJavaBuilder.append("\n");
17753 MemInfoReader memInfo = new MemInfoReader();
17754 memInfo.readMemInfo();
17755 final long[] infos = memInfo.getRawInfo();
17757 StringBuilder memInfoBuilder = new StringBuilder(1024);
17758 Debug.getMemInfo(infos);
17759 memInfoBuilder.append(" MemInfo: ");
17760 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17761 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17762 memInfoBuilder.append(stringifyKBSize(
17763 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17764 memInfoBuilder.append(stringifyKBSize(
17765 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17766 memInfoBuilder.append(stringifyKBSize(
17767 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17768 memInfoBuilder.append(" ");
17769 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17770 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17771 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17772 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17773 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17774 memInfoBuilder.append(" ZRAM: ");
17775 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17776 memInfoBuilder.append(" RAM, ");
17777 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17778 memInfoBuilder.append(" swap total, ");
17779 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17780 memInfoBuilder.append(" swap free\n");
17782 final long[] ksm = getKsmInfo();
17783 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17784 || ksm[KSM_VOLATILE] != 0) {
17785 memInfoBuilder.append(" KSM: ");
17786 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17787 memInfoBuilder.append(" saved from shared ");
17788 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17789 memInfoBuilder.append("\n ");
17790 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17791 memInfoBuilder.append(" unshared; ");
17792 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17793 memInfoBuilder.append(" volatile\n");
17795 memInfoBuilder.append(" Free RAM: ");
17796 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17797 + memInfo.getFreeSizeKb()));
17798 memInfoBuilder.append("\n");
17799 memInfoBuilder.append(" Used RAM: ");
17800 memInfoBuilder.append(stringifyKBSize(
17801 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17802 memInfoBuilder.append("\n");
17803 memInfoBuilder.append(" Lost RAM: ");
17804 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17805 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17806 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17807 memInfoBuilder.append("\n");
17808 Slog.i(TAG, "Low on memory:");
17809 Slog.i(TAG, shortNativeBuilder.toString());
17810 Slog.i(TAG, fullJavaBuilder.toString());
17811 Slog.i(TAG, memInfoBuilder.toString());
17813 StringBuilder dropBuilder = new StringBuilder(1024);
17815 StringWriter oomSw = new StringWriter();
17816 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17817 StringWriter catSw = new StringWriter();
17818 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17819 String[] emptyArgs = new String[] { };
17820 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17822 String oomString = oomSw.toString();
17824 dropBuilder.append("Low on memory:");
17825 dropBuilder.append(stack);
17826 dropBuilder.append('\n');
17827 dropBuilder.append(fullNativeBuilder);
17828 dropBuilder.append(fullJavaBuilder);
17829 dropBuilder.append('\n');
17830 dropBuilder.append(memInfoBuilder);
17831 dropBuilder.append('\n');
17833 dropBuilder.append(oomString);
17834 dropBuilder.append('\n');
17836 StringWriter catSw = new StringWriter();
17837 synchronized (ActivityManagerService.this) {
17838 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17839 String[] emptyArgs = new String[] { };
17841 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17843 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17844 false, null).dumpLocked();
17846 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17849 dropBuilder.append(catSw.toString());
17850 addErrorToDropBox("lowmem", null, "system_server", null,
17851 null, tag.toString(), dropBuilder.toString(), null, null);
17852 //Slog.i(TAG, "Sent to dropbox:");
17853 //Slog.i(TAG, dropBuilder.toString());
17854 synchronized (ActivityManagerService.this) {
17855 long now = SystemClock.uptimeMillis();
17856 if (mLastMemUsageReportTime < now) {
17857 mLastMemUsageReportTime = now;
17863 * Searches array of arguments for the specified string
17864 * @param args array of argument strings
17865 * @param value value to search for
17866 * @return true if the value is contained in the array
17868 private static boolean scanArgs(String[] args, String value) {
17869 if (args != null) {
17870 for (String arg : args) {
17871 if (value.equals(arg)) {
17879 private final boolean removeDyingProviderLocked(ProcessRecord proc,
17880 ContentProviderRecord cpr, boolean always) {
17881 final boolean inLaunching = mLaunchingProviders.contains(cpr);
17883 if (!inLaunching || always) {
17884 synchronized (cpr) {
17885 cpr.launchingApp = null;
17888 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17889 String names[] = cpr.info.authority.split(";");
17890 for (int j = 0; j < names.length; j++) {
17891 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17895 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17896 ContentProviderConnection conn = cpr.connections.get(i);
17897 if (conn.waiting) {
17898 // If this connection is waiting for the provider, then we don't
17899 // need to mess with its process unless we are always removing
17900 // or for some reason the provider is not currently launching.
17901 if (inLaunching && !always) {
17905 ProcessRecord capp = conn.client;
17907 if (conn.stableCount > 0) {
17908 if (!capp.persistent && capp.thread != null
17910 && capp.pid != MY_PID) {
17911 capp.kill("depends on provider "
17912 + cpr.name.flattenToShortString()
17913 + " in dying proc " + (proc != null ? proc.processName : "??")
17914 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17916 } else if (capp.thread != null && conn.provider.provider != null) {
17918 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17919 } catch (RemoteException e) {
17921 // In the protocol here, we don't expect the client to correctly
17922 // clean up this connection, we'll just remove it.
17923 cpr.connections.remove(i);
17924 if (conn.client.conProviders.remove(conn)) {
17925 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17930 if (inLaunching && always) {
17931 mLaunchingProviders.remove(cpr);
17933 return inLaunching;
17937 * Main code for cleaning up a process when it has gone away. This is
17938 * called both as a result of the process dying, or directly when stopping
17939 * a process when running in single process mode.
17941 * @return Returns true if the given process has been restarted, so the
17942 * app that was passed in must remain on the process lists.
17944 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17945 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17947 removeLruProcessLocked(app);
17948 ProcessList.remove(app.pid);
17951 mProcessesToGc.remove(app);
17952 mPendingPssProcesses.remove(app);
17954 // Dismiss any open dialogs.
17955 if (app.crashDialog != null && !app.forceCrashReport) {
17956 app.crashDialog.dismiss();
17957 app.crashDialog = null;
17959 if (app.anrDialog != null) {
17960 app.anrDialog.dismiss();
17961 app.anrDialog = null;
17963 if (app.waitDialog != null) {
17964 app.waitDialog.dismiss();
17965 app.waitDialog = null;
17968 app.crashing = false;
17969 app.notResponding = false;
17971 app.resetPackageList(mProcessStats);
17972 app.unlinkDeathRecipient();
17973 app.makeInactive(mProcessStats);
17974 app.waitingToKill = null;
17975 app.forcingToImportant = null;
17976 updateProcessForegroundLocked(app, false, false);
17977 app.foregroundActivities = false;
17978 app.hasShownUi = false;
17979 app.treatLikeActivity = false;
17980 app.hasAboveClient = false;
17981 app.hasClientActivities = false;
17983 mServices.killServicesLocked(app, allowRestart);
17985 boolean restart = false;
17987 // Remove published content providers.
17988 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17989 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17990 final boolean always = app.bad || !allowRestart;
17991 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17992 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17993 // We left the provider in the launching list, need to
17998 cpr.provider = null;
18001 app.pubProviders.clear();
18003 // Take care of any launching providers waiting for this process.
18004 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18008 // Unregister from connected content providers.
18009 if (!app.conProviders.isEmpty()) {
18010 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18011 ContentProviderConnection conn = app.conProviders.get(i);
18012 conn.provider.connections.remove(conn);
18013 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18014 conn.provider.name);
18016 app.conProviders.clear();
18019 // At this point there may be remaining entries in mLaunchingProviders
18020 // where we were the only one waiting, so they are no longer of use.
18021 // Look for these and clean up if found.
18022 // XXX Commented out for now. Trying to figure out a way to reproduce
18023 // the actual situation to identify what is actually going on.
18025 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18026 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18027 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18028 synchronized (cpr) {
18029 cpr.launchingApp = null;
18036 skipCurrentReceiverLocked(app);
18038 // Unregister any receivers.
18039 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18040 removeReceiverLocked(app.receivers.valueAt(i));
18042 app.receivers.clear();
18044 // If the app is undergoing backup, tell the backup manager about it
18045 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18046 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18047 + mBackupTarget.appInfo + " died during backup");
18048 mHandler.post(new Runnable() {
18052 IBackupManager bm = IBackupManager.Stub.asInterface(
18053 ServiceManager.getService(Context.BACKUP_SERVICE));
18054 bm.agentDisconnected(app.info.packageName);
18055 } catch (RemoteException e) {
18056 // can't happen; backup manager is local
18062 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18063 ProcessChangeItem item = mPendingProcessChanges.get(i);
18064 if (item.pid == app.pid) {
18065 mPendingProcessChanges.remove(i);
18066 mAvailProcessChanges.add(item);
18069 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18070 null).sendToTarget();
18072 // If the caller is restarting this app, then leave it in its
18073 // current lists and let the caller take care of it.
18078 if (!app.persistent || app.isolated) {
18079 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18080 "Removing non-persistent process during cleanup: " + app);
18081 if (!replacingPid) {
18082 removeProcessNameLocked(app.processName, app.uid, app);
18084 if (mHeavyWeightProcess == app) {
18085 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18086 mHeavyWeightProcess.userId, 0));
18087 mHeavyWeightProcess = null;
18089 } else if (!app.removed) {
18090 // This app is persistent, so we need to keep its record around.
18091 // If it is not already on the pending app list, add it there
18092 // and start a new process for it.
18093 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18094 mPersistentStartingProcesses.add(app);
18098 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18099 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18100 mProcessesOnHold.remove(app);
18102 if (app == mHomeProcess) {
18103 mHomeProcess = null;
18105 if (app == mPreviousProcess) {
18106 mPreviousProcess = null;
18109 if (restart && !app.isolated) {
18110 // We have components that still need to be running in the
18111 // process, so re-launch it.
18113 ProcessList.remove(app.pid);
18115 addProcessNameLocked(app);
18116 startProcessLocked(app, "restart", app.processName);
18118 } else if (app.pid > 0 && app.pid != MY_PID) {
18121 synchronized (mPidsSelfLocked) {
18122 mPidsSelfLocked.remove(app.pid);
18123 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18125 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18126 if (app.isolated) {
18127 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18134 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18135 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18136 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18137 if (cpr.launchingApp == app) {
18144 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18145 // Look through the content providers we are waiting to have launched,
18146 // and if any run in this process then either schedule a restart of
18147 // the process or kill the client waiting for it if this process has
18149 boolean restart = false;
18150 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18151 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18152 if (cpr.launchingApp == app) {
18153 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18156 removeDyingProviderLocked(app, cpr, true);
18163 // =========================================================
18165 // =========================================================
18168 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18170 enforceNotIsolatedCaller("getServices");
18172 final int callingUid = Binder.getCallingUid();
18173 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18174 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18175 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18177 synchronized (this) {
18178 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18179 allowed, canInteractAcrossUsers);
18184 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18185 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18186 synchronized (this) {
18187 return mServices.getRunningServiceControlPanelLocked(name);
18192 public ComponentName startService(IApplicationThread caller, Intent service,
18193 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18194 throws TransactionTooLargeException {
18195 enforceNotIsolatedCaller("startService");
18196 // Refuse possible leaked file descriptors
18197 if (service != null && service.hasFileDescriptors() == true) {
18198 throw new IllegalArgumentException("File descriptors passed in Intent");
18201 if (callingPackage == null) {
18202 throw new IllegalArgumentException("callingPackage cannot be null");
18205 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18206 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18207 synchronized(this) {
18208 final int callingPid = Binder.getCallingPid();
18209 final int callingUid = Binder.getCallingUid();
18210 final long origId = Binder.clearCallingIdentity();
18213 res = mServices.startServiceLocked(caller, service,
18214 resolvedType, callingPid, callingUid,
18215 requireForeground, callingPackage, userId);
18217 Binder.restoreCallingIdentity(origId);
18223 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18224 boolean fgRequired, String callingPackage, int userId)
18225 throws TransactionTooLargeException {
18226 synchronized(this) {
18227 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18228 "startServiceInPackage: " + service + " type=" + resolvedType);
18229 final long origId = Binder.clearCallingIdentity();
18232 res = mServices.startServiceLocked(null, service,
18233 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18235 Binder.restoreCallingIdentity(origId);
18242 public int stopService(IApplicationThread caller, Intent service,
18243 String resolvedType, int userId) {
18244 enforceNotIsolatedCaller("stopService");
18245 // Refuse possible leaked file descriptors
18246 if (service != null && service.hasFileDescriptors() == true) {
18247 throw new IllegalArgumentException("File descriptors passed in Intent");
18250 synchronized(this) {
18251 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18256 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18257 enforceNotIsolatedCaller("peekService");
18258 // Refuse possible leaked file descriptors
18259 if (service != null && service.hasFileDescriptors() == true) {
18260 throw new IllegalArgumentException("File descriptors passed in Intent");
18263 if (callingPackage == null) {
18264 throw new IllegalArgumentException("callingPackage cannot be null");
18267 synchronized(this) {
18268 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18273 public boolean stopServiceToken(ComponentName className, IBinder token,
18275 synchronized(this) {
18276 return mServices.stopServiceTokenLocked(className, token, startId);
18281 public void setServiceForeground(ComponentName className, IBinder token,
18282 int id, Notification notification, int flags) {
18283 synchronized(this) {
18284 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18289 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18290 boolean requireFull, String name, String callerPackage) {
18291 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18292 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18295 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18296 String className, int flags) {
18297 boolean result = false;
18298 // For apps that don't have pre-defined UIDs, check for permission
18299 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18300 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18301 if (ActivityManager.checkUidPermission(
18302 INTERACT_ACROSS_USERS,
18303 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18304 ComponentName comp = new ComponentName(aInfo.packageName, className);
18305 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18306 + " requests FLAG_SINGLE_USER, but app does not hold "
18307 + INTERACT_ACROSS_USERS;
18309 throw new SecurityException(msg);
18311 // Permission passed
18314 } else if ("system".equals(componentProcessName)) {
18316 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18317 // Phone app and persistent apps are allowed to export singleuser providers.
18318 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18319 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18321 if (DEBUG_MU) Slog.v(TAG_MU,
18322 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18323 + Integer.toHexString(flags) + ") = " + result);
18328 * Checks to see if the caller is in the same app as the singleton
18329 * component, or the component is in a special app. It allows special apps
18330 * to export singleton components but prevents exporting singleton
18331 * components for regular apps.
18333 boolean isValidSingletonCall(int callingUid, int componentUid) {
18334 int componentAppId = UserHandle.getAppId(componentUid);
18335 return UserHandle.isSameApp(callingUid, componentUid)
18336 || componentAppId == SYSTEM_UID
18337 || componentAppId == PHONE_UID
18338 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18339 == PackageManager.PERMISSION_GRANTED;
18342 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18343 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18344 int userId) throws TransactionTooLargeException {
18345 enforceNotIsolatedCaller("bindService");
18347 // Refuse possible leaked file descriptors
18348 if (service != null && service.hasFileDescriptors() == true) {
18349 throw new IllegalArgumentException("File descriptors passed in Intent");
18352 if (callingPackage == null) {
18353 throw new IllegalArgumentException("callingPackage cannot be null");
18356 synchronized(this) {
18357 return mServices.bindServiceLocked(caller, token, service,
18358 resolvedType, connection, flags, callingPackage, userId);
18362 public boolean unbindService(IServiceConnection connection) {
18363 synchronized (this) {
18364 return mServices.unbindServiceLocked(connection);
18368 public void publishService(IBinder token, Intent intent, IBinder service) {
18369 // Refuse possible leaked file descriptors
18370 if (intent != null && intent.hasFileDescriptors() == true) {
18371 throw new IllegalArgumentException("File descriptors passed in Intent");
18374 synchronized(this) {
18375 if (!(token instanceof ServiceRecord)) {
18376 throw new IllegalArgumentException("Invalid service token");
18378 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18382 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18383 // Refuse possible leaked file descriptors
18384 if (intent != null && intent.hasFileDescriptors() == true) {
18385 throw new IllegalArgumentException("File descriptors passed in Intent");
18388 synchronized(this) {
18389 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18393 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18394 synchronized(this) {
18395 if (!(token instanceof ServiceRecord)) {
18396 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18397 throw new IllegalArgumentException("Invalid service token");
18399 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18403 // =========================================================
18404 // BACKUP AND RESTORE
18405 // =========================================================
18407 // Cause the target app to be launched if necessary and its backup agent
18408 // instantiated. The backup agent will invoke backupAgentCreated() on the
18409 // activity manager to announce its creation.
18410 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18411 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18412 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18414 IPackageManager pm = AppGlobals.getPackageManager();
18415 ApplicationInfo app = null;
18417 app = pm.getApplicationInfo(packageName, 0, userId);
18418 } catch (RemoteException e) {
18419 // can't happen; package manager is process-local
18422 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18429 synchronized(this) {
18430 // !!! TODO: currently no check here that we're already bound
18431 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18432 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18433 synchronized (stats) {
18434 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18437 // Backup agent is now in use, its package can't be stopped.
18439 AppGlobals.getPackageManager().setPackageStoppedState(
18440 app.packageName, false, UserHandle.getUserId(app.uid));
18441 } catch (RemoteException e) {
18442 } catch (IllegalArgumentException e) {
18443 Slog.w(TAG, "Failed trying to unstop package "
18444 + app.packageName + ": " + e);
18447 BackupRecord r = new BackupRecord(ss, app, backupMode);
18448 ComponentName hostingName =
18449 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18450 ? new ComponentName(app.packageName, app.backupAgentName)
18451 : new ComponentName("android", "FullBackupAgent");
18452 // startProcessLocked() returns existing proc's record if it's already running
18453 ProcessRecord proc = startProcessLocked(app.processName, app,
18454 false, 0, "backup", hostingName, false, false, false);
18455 if (proc == null) {
18456 Slog.e(TAG, "Unable to start backup agent process " + r);
18460 // If the app is a regular app (uid >= 10000) and not the system server or phone
18461 // process, etc, then mark it as being in full backup so that certain calls to the
18462 // process can be blocked. This is not reset to false anywhere because we kill the
18463 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18464 if (UserHandle.isApp(app.uid) &&
18465 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18466 proc.inFullBackup = true;
18469 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18470 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18472 mBackupAppName = app.packageName;
18474 // Try not to kill the process during backup
18475 updateOomAdjLocked(proc, true);
18477 // If the process is already attached, schedule the creation of the backup agent now.
18478 // If it is not yet live, this will be done when it attaches to the framework.
18479 if (proc.thread != null) {
18480 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18482 proc.thread.scheduleCreateBackupAgent(app,
18483 compatibilityInfoForPackageLocked(app), backupMode);
18484 } catch (RemoteException e) {
18485 // Will time out on the backup manager side
18488 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18490 // Invariants: at this point, the target app process exists and the application
18491 // is either already running or in the process of coming up. mBackupTarget and
18492 // mBackupAppName describe the app, so that when it binds back to the AM we
18493 // know that it's scheduled for a backup-agent operation.
18496 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18497 if (oldBackupUid != -1) {
18498 js.removeBackingUpUid(oldBackupUid);
18500 if (newBackupUid != -1) {
18501 js.addBackingUpUid(newBackupUid);
18508 public void clearPendingBackup() {
18509 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18510 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18512 synchronized (this) {
18513 mBackupTarget = null;
18514 mBackupAppName = null;
18517 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18518 js.clearAllBackingUpUids();
18521 // A backup agent has just come up
18522 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18523 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18526 synchronized(this) {
18527 if (!agentPackageName.equals(mBackupAppName)) {
18528 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18533 long oldIdent = Binder.clearCallingIdentity();
18535 IBackupManager bm = IBackupManager.Stub.asInterface(
18536 ServiceManager.getService(Context.BACKUP_SERVICE));
18537 bm.agentConnected(agentPackageName, agent);
18538 } catch (RemoteException e) {
18539 // can't happen; the backup manager service is local
18540 } catch (Exception e) {
18541 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18542 e.printStackTrace();
18544 Binder.restoreCallingIdentity(oldIdent);
18548 // done with this agent
18549 public void unbindBackupAgent(ApplicationInfo appInfo) {
18550 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18551 if (appInfo == null) {
18552 Slog.w(TAG, "unbind backup agent for null app");
18558 synchronized(this) {
18560 if (mBackupAppName == null) {
18561 Slog.w(TAG, "Unbinding backup agent with no active backup");
18565 if (!mBackupAppName.equals(appInfo.packageName)) {
18566 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18570 // Not backing this app up any more; reset its OOM adjustment
18571 final ProcessRecord proc = mBackupTarget.app;
18572 updateOomAdjLocked(proc, true);
18573 proc.inFullBackup = false;
18575 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18577 // If the app crashed during backup, 'thread' will be null here
18578 if (proc.thread != null) {
18580 proc.thread.scheduleDestroyBackupAgent(appInfo,
18581 compatibilityInfoForPackageLocked(appInfo));
18582 } catch (Exception e) {
18583 Slog.e(TAG, "Exception when unbinding backup agent:");
18584 e.printStackTrace();
18588 mBackupTarget = null;
18589 mBackupAppName = null;
18593 if (oldBackupUid != -1) {
18594 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18595 js.removeBackingUpUid(oldBackupUid);
18599 // =========================================================
18601 // =========================================================
18603 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18604 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18607 // Easy case -- we have the app's ProcessRecord.
18608 if (record != null) {
18609 return record.info.isInstantApp();
18611 // Otherwise check with PackageManager.
18612 if (callerPackage == null) {
18613 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18614 throw new IllegalArgumentException("Calling application did not provide package name");
18616 mAppOpsService.checkPackage(uid, callerPackage);
18618 IPackageManager pm = AppGlobals.getPackageManager();
18619 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18620 } catch (RemoteException e) {
18621 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18626 boolean isPendingBroadcastProcessLocked(int pid) {
18627 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18628 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18631 void skipPendingBroadcastLocked(int pid) {
18632 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18633 for (BroadcastQueue queue : mBroadcastQueues) {
18634 queue.skipPendingBroadcastLocked(pid);
18638 // The app just attached; send any pending broadcasts that it should receive
18639 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18640 boolean didSomething = false;
18641 for (BroadcastQueue queue : mBroadcastQueues) {
18642 didSomething |= queue.sendPendingBroadcastsLocked(app);
18644 return didSomething;
18647 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18648 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18650 enforceNotIsolatedCaller("registerReceiver");
18651 ArrayList<Intent> stickyIntents = null;
18652 ProcessRecord callerApp = null;
18653 final boolean visibleToInstantApps
18654 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18657 boolean instantApp;
18658 synchronized(this) {
18659 if (caller != null) {
18660 callerApp = getRecordForAppLocked(caller);
18661 if (callerApp == null) {
18662 throw new SecurityException(
18663 "Unable to find app for caller " + caller
18664 + " (pid=" + Binder.getCallingPid()
18665 + ") when registering receiver " + receiver);
18667 if (callerApp.info.uid != SYSTEM_UID &&
18668 !callerApp.pkgList.containsKey(callerPackage) &&
18669 !"android".equals(callerPackage)) {
18670 throw new SecurityException("Given caller package " + callerPackage
18671 + " is not running in process " + callerApp);
18673 callingUid = callerApp.info.uid;
18674 callingPid = callerApp.pid;
18676 callerPackage = null;
18677 callingUid = Binder.getCallingUid();
18678 callingPid = Binder.getCallingPid();
18681 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18682 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18683 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18685 Iterator<String> actions = filter.actionsIterator();
18686 if (actions == null) {
18687 ArrayList<String> noAction = new ArrayList<String>(1);
18688 noAction.add(null);
18689 actions = noAction.iterator();
18692 // Collect stickies of users
18693 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18694 while (actions.hasNext()) {
18695 String action = actions.next();
18696 for (int id : userIds) {
18697 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18698 if (stickies != null) {
18699 ArrayList<Intent> intents = stickies.get(action);
18700 if (intents != null) {
18701 if (stickyIntents == null) {
18702 stickyIntents = new ArrayList<Intent>();
18704 stickyIntents.addAll(intents);
18711 ArrayList<Intent> allSticky = null;
18712 if (stickyIntents != null) {
18713 final ContentResolver resolver = mContext.getContentResolver();
18714 // Look for any matching sticky broadcasts...
18715 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18716 Intent intent = stickyIntents.get(i);
18717 // Don't provided intents that aren't available to instant apps.
18719 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18722 // If intent has scheme "content", it will need to acccess
18723 // provider that needs to lock mProviderMap in ActivityThread
18724 // and also it may need to wait application response, so we
18725 // cannot lock ActivityManagerService here.
18726 if (filter.match(resolver, intent, true, TAG) >= 0) {
18727 if (allSticky == null) {
18728 allSticky = new ArrayList<Intent>();
18730 allSticky.add(intent);
18735 // The first sticky in the list is returned directly back to the client.
18736 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18737 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18738 if (receiver == null) {
18742 synchronized (this) {
18743 if (callerApp != null && (callerApp.thread == null
18744 || callerApp.thread.asBinder() != caller.asBinder())) {
18745 // Original caller already died
18748 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18750 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18752 if (rl.app != null) {
18753 rl.app.receivers.add(rl);
18756 receiver.asBinder().linkToDeath(rl, 0);
18757 } catch (RemoteException e) {
18760 rl.linkedToDeath = true;
18762 mRegisteredReceivers.put(receiver.asBinder(), rl);
18763 } else if (rl.uid != callingUid) {
18764 throw new IllegalArgumentException(
18765 "Receiver requested to register for uid " + callingUid
18766 + " was previously registered for uid " + rl.uid
18767 + " callerPackage is " + callerPackage);
18768 } else if (rl.pid != callingPid) {
18769 throw new IllegalArgumentException(
18770 "Receiver requested to register for pid " + callingPid
18771 + " was previously registered for pid " + rl.pid
18772 + " callerPackage is " + callerPackage);
18773 } else if (rl.userId != userId) {
18774 throw new IllegalArgumentException(
18775 "Receiver requested to register for user " + userId
18776 + " was previously registered for user " + rl.userId
18777 + " callerPackage is " + callerPackage);
18779 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18780 permission, callingUid, userId, instantApp, visibleToInstantApps);
18782 if (!bf.debugCheck()) {
18783 Slog.w(TAG, "==> For Dynamic broadcast");
18785 mReceiverResolver.addFilter(bf);
18787 // Enqueue broadcasts for all existing stickies that match
18789 if (allSticky != null) {
18790 ArrayList receivers = new ArrayList();
18793 final int stickyCount = allSticky.size();
18794 for (int i = 0; i < stickyCount; i++) {
18795 Intent intent = allSticky.get(i);
18796 BroadcastQueue queue = broadcastQueueForIntent(intent);
18797 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18798 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18799 null, 0, null, null, false, true, true, -1);
18800 queue.enqueueParallelBroadcastLocked(r);
18801 queue.scheduleBroadcastsLocked();
18809 public void unregisterReceiver(IIntentReceiver receiver) {
18810 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18812 final long origId = Binder.clearCallingIdentity();
18814 boolean doTrim = false;
18816 synchronized(this) {
18817 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18819 final BroadcastRecord r = rl.curBroadcast;
18820 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18821 final boolean doNext = r.queue.finishReceiverLocked(
18822 r, r.resultCode, r.resultData, r.resultExtras,
18823 r.resultAbort, false);
18826 r.queue.processNextBroadcast(false);
18830 if (rl.app != null) {
18831 rl.app.receivers.remove(rl);
18833 removeReceiverLocked(rl);
18834 if (rl.linkedToDeath) {
18835 rl.linkedToDeath = false;
18836 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18841 // If we actually concluded any broadcasts, we might now be able
18842 // to trim the recipients' apps from our working set
18844 trimApplications();
18849 Binder.restoreCallingIdentity(origId);
18853 void removeReceiverLocked(ReceiverList rl) {
18854 mRegisteredReceivers.remove(rl.receiver.asBinder());
18855 for (int i = rl.size() - 1; i >= 0; i--) {
18856 mReceiverResolver.removeFilter(rl.get(i));
18860 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18861 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18862 ProcessRecord r = mLruProcesses.get(i);
18863 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18865 r.thread.dispatchPackageBroadcast(cmd, packages);
18866 } catch (RemoteException ex) {
18872 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18873 int callingUid, int[] users) {
18874 // TODO: come back and remove this assumption to triage all broadcasts
18875 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18877 List<ResolveInfo> receivers = null;
18879 HashSet<ComponentName> singleUserReceivers = null;
18880 boolean scannedFirstReceivers = false;
18881 for (int user : users) {
18882 // Skip users that have Shell restrictions, with exception of always permitted
18883 // Shell broadcasts
18884 if (callingUid == SHELL_UID
18885 && mUserController.hasUserRestriction(
18886 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18887 && !isPermittedShellBroadcast(intent)) {
18890 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18891 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18892 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18893 // If this is not the system user, we need to check for
18894 // any receivers that should be filtered out.
18895 for (int i=0; i<newReceivers.size(); i++) {
18896 ResolveInfo ri = newReceivers.get(i);
18897 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18898 newReceivers.remove(i);
18903 if (newReceivers != null && newReceivers.size() == 0) {
18904 newReceivers = null;
18906 if (receivers == null) {
18907 receivers = newReceivers;
18908 } else if (newReceivers != null) {
18909 // We need to concatenate the additional receivers
18910 // found with what we have do far. This would be easy,
18911 // but we also need to de-dup any receivers that are
18913 if (!scannedFirstReceivers) {
18914 // Collect any single user receivers we had already retrieved.
18915 scannedFirstReceivers = true;
18916 for (int i=0; i<receivers.size(); i++) {
18917 ResolveInfo ri = receivers.get(i);
18918 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18919 ComponentName cn = new ComponentName(
18920 ri.activityInfo.packageName, ri.activityInfo.name);
18921 if (singleUserReceivers == null) {
18922 singleUserReceivers = new HashSet<ComponentName>();
18924 singleUserReceivers.add(cn);
18928 // Add the new results to the existing results, tracking
18929 // and de-dupping single user receivers.
18930 for (int i=0; i<newReceivers.size(); i++) {
18931 ResolveInfo ri = newReceivers.get(i);
18932 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18933 ComponentName cn = new ComponentName(
18934 ri.activityInfo.packageName, ri.activityInfo.name);
18935 if (singleUserReceivers == null) {
18936 singleUserReceivers = new HashSet<ComponentName>();
18938 if (!singleUserReceivers.contains(cn)) {
18939 singleUserReceivers.add(cn);
18948 } catch (RemoteException ex) {
18949 // pm is in same process, this will never happen.
18954 private boolean isPermittedShellBroadcast(Intent intent) {
18955 // remote bugreport should always be allowed to be taken
18956 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18959 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18960 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18961 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18962 // Don't yell about broadcasts sent via shell
18966 final String action = intent.getAction();
18967 if (isProtectedBroadcast
18968 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18969 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18970 || Intent.ACTION_MEDIA_BUTTON.equals(action)
18971 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18972 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18973 || Intent.ACTION_MASTER_CLEAR.equals(action)
18974 || Intent.ACTION_FACTORY_RESET.equals(action)
18975 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18976 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18977 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18978 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18979 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18980 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18981 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18982 // Broadcast is either protected, or it's a public action that
18983 // we've relaxed, so it's fine for system internals to send.
18987 // This broadcast may be a problem... but there are often system components that
18988 // want to send an internal broadcast to themselves, which is annoying to have to
18989 // explicitly list each action as a protected broadcast, so we will check for that
18990 // one safe case and allow it: an explicit broadcast, only being received by something
18991 // that has protected itself.
18992 if (receivers != null && receivers.size() > 0
18993 && (intent.getPackage() != null || intent.getComponent() != null)) {
18994 boolean allProtected = true;
18995 for (int i = receivers.size()-1; i >= 0; i--) {
18996 Object target = receivers.get(i);
18997 if (target instanceof ResolveInfo) {
18998 ResolveInfo ri = (ResolveInfo)target;
18999 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19000 allProtected = false;
19004 BroadcastFilter bf = (BroadcastFilter)target;
19005 if (bf.requiredPermission == null) {
19006 allProtected = false;
19011 if (allProtected) {
19017 // The vast majority of broadcasts sent from system internals
19018 // should be protected to avoid security holes, so yell loudly
19019 // to ensure we examine these cases.
19020 if (callerApp != null) {
19021 Log.wtf(TAG, "Sending non-protected broadcast " + action
19022 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19025 Log.wtf(TAG, "Sending non-protected broadcast " + action
19026 + " from system uid " + UserHandle.formatUid(callingUid)
19027 + " pkg " + callerPackage,
19032 final int broadcastIntentLocked(ProcessRecord callerApp,
19033 String callerPackage, Intent intent, String resolvedType,
19034 IIntentReceiver resultTo, int resultCode, String resultData,
19035 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19036 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19037 intent = new Intent(intent);
19039 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19040 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19041 if (callerInstantApp) {
19042 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19045 // By default broadcasts do not go to stopped apps.
19046 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19048 // If we have not finished booting, don't allow this to launch new processes.
19049 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19050 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19053 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19054 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19055 + " ordered=" + ordered + " userid=" + userId);
19056 if ((resultTo != null) && !ordered) {
19057 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19060 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19061 ALLOW_NON_FULL, "broadcast", callerPackage);
19063 // Make sure that the user who is receiving this broadcast is running.
19064 // If not, we will just skip it. Make an exception for shutdown broadcasts
19065 // and upgrade steps.
19067 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19068 if ((callingUid != SYSTEM_UID
19069 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19070 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19071 Slog.w(TAG, "Skipping broadcast of " + intent
19072 + ": user " + userId + " is stopped");
19073 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19077 BroadcastOptions brOptions = null;
19078 if (bOptions != null) {
19079 brOptions = new BroadcastOptions(bOptions);
19080 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19081 // See if the caller is allowed to do this. Note we are checking against
19082 // the actual real caller (not whoever provided the operation as say a
19083 // PendingIntent), because that who is actually supplied the arguments.
19084 if (checkComponentPermission(
19085 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19086 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19087 != PackageManager.PERMISSION_GRANTED) {
19088 String msg = "Permission Denial: " + intent.getAction()
19089 + " broadcast from " + callerPackage + " (pid=" + callingPid
19090 + ", uid=" + callingUid + ")"
19092 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19094 throw new SecurityException(msg);
19099 // Verify that protected broadcasts are only being sent by system code,
19100 // and that system code is only sending protected broadcasts.
19101 final String action = intent.getAction();
19102 final boolean isProtectedBroadcast;
19104 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19105 } catch (RemoteException e) {
19106 Slog.w(TAG, "Remote exception", e);
19107 return ActivityManager.BROADCAST_SUCCESS;
19110 final boolean isCallerSystem;
19111 switch (UserHandle.getAppId(callingUid)) {
19115 case BLUETOOTH_UID:
19117 isCallerSystem = true;
19120 isCallerSystem = (callerApp != null) && callerApp.persistent;
19124 // First line security check before anything else: stop non-system apps from
19125 // sending protected broadcasts.
19126 if (!isCallerSystem) {
19127 if (isProtectedBroadcast) {
19128 String msg = "Permission Denial: not allowed to send broadcast "
19129 + action + " from pid="
19130 + callingPid + ", uid=" + callingUid;
19132 throw new SecurityException(msg);
19134 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19135 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19136 // Special case for compatibility: we don't want apps to send this,
19137 // but historically it has not been protected and apps may be using it
19138 // to poke their own app widget. So, instead of making it protected,
19139 // just limit it to the caller.
19140 if (callerPackage == null) {
19141 String msg = "Permission Denial: not allowed to send broadcast "
19142 + action + " from unknown caller.";
19144 throw new SecurityException(msg);
19145 } else if (intent.getComponent() != null) {
19146 // They are good enough to send to an explicit component... verify
19147 // it is being sent to the calling app.
19148 if (!intent.getComponent().getPackageName().equals(
19150 String msg = "Permission Denial: not allowed to send broadcast "
19152 + intent.getComponent().getPackageName() + " from "
19155 throw new SecurityException(msg);
19158 // Limit broadcast to their own package.
19159 intent.setPackage(callerPackage);
19164 if (action != null) {
19165 if (getBackgroundLaunchBroadcasts().contains(action)) {
19166 if (DEBUG_BACKGROUND_CHECK) {
19167 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19169 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19173 case Intent.ACTION_UID_REMOVED:
19174 case Intent.ACTION_PACKAGE_REMOVED:
19175 case Intent.ACTION_PACKAGE_CHANGED:
19176 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19177 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19178 case Intent.ACTION_PACKAGES_SUSPENDED:
19179 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19180 // Handle special intents: if this broadcast is from the package
19181 // manager about a package being removed, we need to remove all of
19182 // its activities from the history stack.
19183 if (checkComponentPermission(
19184 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19185 callingPid, callingUid, -1, true)
19186 != PackageManager.PERMISSION_GRANTED) {
19187 String msg = "Permission Denial: " + intent.getAction()
19188 + " broadcast from " + callerPackage + " (pid=" + callingPid
19189 + ", uid=" + callingUid + ")"
19191 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19193 throw new SecurityException(msg);
19196 case Intent.ACTION_UID_REMOVED:
19197 final int uid = getUidFromIntent(intent);
19199 mBatteryStatsService.removeUid(uid);
19200 mAppOpsService.uidRemoved(uid);
19203 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19204 // If resources are unavailable just force stop all those packages
19205 // and flush the attribute cache as well.
19207 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19208 if (list != null && list.length > 0) {
19209 for (int i = 0; i < list.length; i++) {
19210 forceStopPackageLocked(list[i], -1, false, true, true,
19211 false, false, userId, "storage unmount");
19213 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19214 sendPackageBroadcastLocked(
19215 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19219 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19220 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19222 case Intent.ACTION_PACKAGE_REMOVED:
19223 case Intent.ACTION_PACKAGE_CHANGED:
19224 Uri data = intent.getData();
19226 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19227 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19228 final boolean replacing =
19229 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19230 final boolean killProcess =
19231 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19232 final boolean fullUninstall = removed && !replacing;
19235 forceStopPackageLocked(ssp, UserHandle.getAppId(
19236 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19237 false, true, true, false, fullUninstall, userId,
19238 removed ? "pkg removed" : "pkg changed");
19240 final int cmd = killProcess
19241 ? ApplicationThreadConstants.PACKAGE_REMOVED
19242 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19243 sendPackageBroadcastLocked(cmd,
19244 new String[] {ssp}, userId);
19245 if (fullUninstall) {
19246 mAppOpsService.packageRemoved(
19247 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19249 // Remove all permissions granted from/to this package
19250 removeUriPermissionsForPackageLocked(ssp, userId, true);
19252 removeTasksByPackageNameLocked(ssp, userId);
19254 mServices.forceStopPackageLocked(ssp, userId);
19256 // Hide the "unsupported display" dialog if necessary.
19257 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19258 mUnsupportedDisplaySizeDialog.getPackageName())) {
19259 mUnsupportedDisplaySizeDialog.dismiss();
19260 mUnsupportedDisplaySizeDialog = null;
19262 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19263 mBatteryStatsService.notePackageUninstalled(ssp);
19267 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19268 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19269 userId, ProcessList.INVALID_ADJ,
19270 false, true, true, false, "change " + ssp);
19272 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19273 intent.getStringArrayExtra(
19274 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19278 case Intent.ACTION_PACKAGES_SUSPENDED:
19279 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19280 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19281 intent.getAction());
19282 final String[] packageNames = intent.getStringArrayExtra(
19283 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19284 final int userHandle = intent.getIntExtra(
19285 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19287 synchronized(ActivityManagerService.this) {
19288 mRecentTasks.onPackagesSuspendedChanged(
19289 packageNames, suspended, userHandle);
19294 case Intent.ACTION_PACKAGE_REPLACED:
19296 final Uri data = intent.getData();
19298 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19299 ApplicationInfo aInfo = null;
19301 aInfo = AppGlobals.getPackageManager()
19302 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19303 } catch (RemoteException ignore) {}
19304 if (aInfo == null) {
19305 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19306 + " ssp=" + ssp + " data=" + data);
19307 return ActivityManager.BROADCAST_SUCCESS;
19309 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19310 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19311 new String[] {ssp}, userId);
19315 case Intent.ACTION_PACKAGE_ADDED:
19317 // Special case for adding a package: by default turn on compatibility mode.
19318 Uri data = intent.getData();
19320 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19321 final boolean replacing =
19322 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19323 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19326 ApplicationInfo ai = AppGlobals.getPackageManager().
19327 getApplicationInfo(ssp, 0, 0);
19328 mBatteryStatsService.notePackageInstalled(ssp,
19329 ai != null ? ai.versionCode : 0);
19330 } catch (RemoteException e) {
19335 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19337 Uri data = intent.getData();
19339 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19340 // Hide the "unsupported display" dialog if necessary.
19341 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19342 mUnsupportedDisplaySizeDialog.getPackageName())) {
19343 mUnsupportedDisplaySizeDialog.dismiss();
19344 mUnsupportedDisplaySizeDialog = null;
19346 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19350 case Intent.ACTION_TIMEZONE_CHANGED:
19351 // If this is the time zone changed action, queue up a message that will reset
19352 // the timezone of all currently running processes. This message will get
19353 // queued up before the broadcast happens.
19354 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19356 case Intent.ACTION_TIME_CHANGED:
19357 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19358 // the tri-state value it may contain and "unknown".
19359 // For convenience we re-use the Intent extra values.
19360 final int NO_EXTRA_VALUE_FOUND = -1;
19361 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19362 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19363 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19364 // Only send a message if the time preference is available.
19365 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19366 Message updateTimePreferenceMsg =
19367 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19368 timeFormatPreferenceMsgValue, 0);
19369 mHandler.sendMessage(updateTimePreferenceMsg);
19371 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19372 synchronized (stats) {
19373 stats.noteCurrentTimeChangedLocked();
19376 case Intent.ACTION_CLEAR_DNS_CACHE:
19377 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19379 case Proxy.PROXY_CHANGE_ACTION:
19380 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19381 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19383 case android.hardware.Camera.ACTION_NEW_PICTURE:
19384 case android.hardware.Camera.ACTION_NEW_VIDEO:
19385 // In N we just turned these off; in O we are turing them back on partly,
19386 // only for registered receivers. This will still address the main problem
19387 // (a spam of apps waking up when a picture is taken putting significant
19388 // memory pressure on the system at a bad point), while still allowing apps
19389 // that are already actively running to know about this happening.
19390 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19392 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19393 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19395 case "com.android.launcher.action.INSTALL_SHORTCUT":
19396 // As of O, we no longer support this broadcasts, even for pre-O apps.
19397 // Apps should now be using ShortcutManager.pinRequestShortcut().
19398 Log.w(TAG, "Broadcast " + action
19399 + " no longer supported. It will not be delivered.");
19400 return ActivityManager.BROADCAST_SUCCESS;
19403 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19404 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19405 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19406 final int uid = getUidFromIntent(intent);
19408 final UidRecord uidRec = mActiveUids.get(uid);
19409 if (uidRec != null) {
19410 uidRec.updateHasInternetPermission();
19416 // Add to the sticky list if requested.
19418 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19419 callingPid, callingUid)
19420 != PackageManager.PERMISSION_GRANTED) {
19421 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19422 + callingPid + ", uid=" + callingUid
19423 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19425 throw new SecurityException(msg);
19427 if (requiredPermissions != null && requiredPermissions.length > 0) {
19428 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19429 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19430 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19432 if (intent.getComponent() != null) {
19433 throw new SecurityException(
19434 "Sticky broadcasts can't target a specific component");
19436 // We use userId directly here, since the "all" target is maintained
19437 // as a separate set of sticky broadcasts.
19438 if (userId != UserHandle.USER_ALL) {
19439 // But first, if this is not a broadcast to all users, then
19440 // make sure it doesn't conflict with an existing broadcast to
19442 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19443 UserHandle.USER_ALL);
19444 if (stickies != null) {
19445 ArrayList<Intent> list = stickies.get(intent.getAction());
19446 if (list != null) {
19447 int N = list.size();
19449 for (i=0; i<N; i++) {
19450 if (intent.filterEquals(list.get(i))) {
19451 throw new IllegalArgumentException(
19452 "Sticky broadcast " + intent + " for user "
19453 + userId + " conflicts with existing global broadcast");
19459 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19460 if (stickies == null) {
19461 stickies = new ArrayMap<>();
19462 mStickyBroadcasts.put(userId, stickies);
19464 ArrayList<Intent> list = stickies.get(intent.getAction());
19465 if (list == null) {
19466 list = new ArrayList<>();
19467 stickies.put(intent.getAction(), list);
19469 final int stickiesCount = list.size();
19471 for (i = 0; i < stickiesCount; i++) {
19472 if (intent.filterEquals(list.get(i))) {
19473 // This sticky already exists, replace it.
19474 list.set(i, new Intent(intent));
19478 if (i >= stickiesCount) {
19479 list.add(new Intent(intent));
19484 if (userId == UserHandle.USER_ALL) {
19485 // Caller wants broadcast to go to all started users.
19486 users = mUserController.getStartedUserArrayLocked();
19488 // Caller wants broadcast to go to one specific user.
19489 users = new int[] {userId};
19492 // Figure out who all will receive this broadcast.
19493 List receivers = null;
19494 List<BroadcastFilter> registeredReceivers = null;
19495 // Need to resolve the intent to interested receivers...
19496 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19498 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19500 if (intent.getComponent() == null) {
19501 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19502 // Query one target user at a time, excluding shell-restricted users
19503 for (int i = 0; i < users.length; i++) {
19504 if (mUserController.hasUserRestriction(
19505 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19508 List<BroadcastFilter> registeredReceiversForUser =
19509 mReceiverResolver.queryIntent(intent,
19510 resolvedType, false /*defaultOnly*/, users[i]);
19511 if (registeredReceivers == null) {
19512 registeredReceivers = registeredReceiversForUser;
19513 } else if (registeredReceiversForUser != null) {
19514 registeredReceivers.addAll(registeredReceiversForUser);
19518 registeredReceivers = mReceiverResolver.queryIntent(intent,
19519 resolvedType, false /*defaultOnly*/, userId);
19523 final boolean replacePending =
19524 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19526 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19527 + " replacePending=" + replacePending);
19529 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19530 if (!ordered && NR > 0) {
19531 // If we are not serializing this broadcast, then send the
19532 // registered receivers separately so they don't wait for the
19533 // components to be launched.
19534 if (isCallerSystem) {
19535 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19536 isProtectedBroadcast, registeredReceivers);
19538 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19539 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19540 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19541 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19542 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19543 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19544 final boolean replaced = replacePending
19545 && (queue.replaceParallelBroadcastLocked(r) != null);
19546 // Note: We assume resultTo is null for non-ordered broadcasts.
19548 queue.enqueueParallelBroadcastLocked(r);
19549 queue.scheduleBroadcastsLocked();
19551 registeredReceivers = null;
19555 // Merge into one list.
19557 if (receivers != null) {
19558 // A special case for PACKAGE_ADDED: do not allow the package
19559 // being added to see this broadcast. This prevents them from
19560 // using this as a back door to get run as soon as they are
19561 // installed. Maybe in the future we want to have a special install
19562 // broadcast or such for apps, but we'd like to deliberately make
19564 String skipPackages[] = null;
19565 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19566 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19567 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19568 Uri data = intent.getData();
19569 if (data != null) {
19570 String pkgName = data.getSchemeSpecificPart();
19571 if (pkgName != null) {
19572 skipPackages = new String[] { pkgName };
19575 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19576 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19578 if (skipPackages != null && (skipPackages.length > 0)) {
19579 for (String skipPackage : skipPackages) {
19580 if (skipPackage != null) {
19581 int NT = receivers.size();
19582 for (int it=0; it<NT; it++) {
19583 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19584 if (curt.activityInfo.packageName.equals(skipPackage)) {
19585 receivers.remove(it);
19594 int NT = receivers != null ? receivers.size() : 0;
19596 ResolveInfo curt = null;
19597 BroadcastFilter curr = null;
19598 while (it < NT && ir < NR) {
19599 if (curt == null) {
19600 curt = (ResolveInfo)receivers.get(it);
19602 if (curr == null) {
19603 curr = registeredReceivers.get(ir);
19605 if (curr.getPriority() >= curt.priority) {
19606 // Insert this broadcast record into the final list.
19607 receivers.add(it, curr);
19613 // Skip to the next ResolveInfo in the final list.
19620 if (receivers == null) {
19621 receivers = new ArrayList();
19623 receivers.add(registeredReceivers.get(ir));
19627 if (isCallerSystem) {
19628 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19629 isProtectedBroadcast, receivers);
19632 if ((receivers != null && receivers.size() > 0)
19633 || resultTo != null) {
19634 BroadcastQueue queue = broadcastQueueForIntent(intent);
19635 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19636 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19637 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19638 resultData, resultExtras, ordered, sticky, false, userId);
19640 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19641 + ": prev had " + queue.mOrderedBroadcasts.size());
19642 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19643 "Enqueueing broadcast " + r.intent.getAction());
19645 final BroadcastRecord oldRecord =
19646 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19647 if (oldRecord != null) {
19648 // Replaced, fire the result-to receiver.
19649 if (oldRecord.resultTo != null) {
19650 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19652 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19654 Activity.RESULT_CANCELED, null, null,
19655 false, false, oldRecord.userId);
19656 } catch (RemoteException e) {
19657 Slog.w(TAG, "Failure ["
19658 + queue.mQueueName + "] sending broadcast result of "
19664 queue.enqueueOrderedBroadcastLocked(r);
19665 queue.scheduleBroadcastsLocked();
19668 // There was nobody interested in the broadcast, but we still want to record
19669 // that it happened.
19670 if (intent.getComponent() == null && intent.getPackage() == null
19671 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19672 // This was an implicit broadcast... let's record it for posterity.
19673 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19677 return ActivityManager.BROADCAST_SUCCESS;
19681 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19683 private int getUidFromIntent(Intent intent) {
19684 if (intent == null) {
19687 final Bundle intentExtras = intent.getExtras();
19688 return intent.hasExtra(Intent.EXTRA_UID)
19689 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19692 final void rotateBroadcastStatsIfNeededLocked() {
19693 final long now = SystemClock.elapsedRealtime();
19694 if (mCurBroadcastStats == null ||
19695 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19696 mLastBroadcastStats = mCurBroadcastStats;
19697 if (mLastBroadcastStats != null) {
19698 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19699 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19701 mCurBroadcastStats = new BroadcastStats();
19705 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19706 int skipCount, long dispatchTime) {
19707 rotateBroadcastStatsIfNeededLocked();
19708 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19711 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19712 rotateBroadcastStatsIfNeededLocked();
19713 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19716 final Intent verifyBroadcastLocked(Intent intent) {
19717 // Refuse possible leaked file descriptors
19718 if (intent != null && intent.hasFileDescriptors() == true) {
19719 throw new IllegalArgumentException("File descriptors passed in Intent");
19722 int flags = intent.getFlags();
19724 if (!mProcessesReady) {
19725 // if the caller really truly claims to know what they're doing, go
19726 // ahead and allow the broadcast without launching any receivers
19727 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19728 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19729 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19730 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19731 + " before boot completion");
19732 throw new IllegalStateException("Cannot broadcast before boot completed");
19736 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19737 throw new IllegalArgumentException(
19738 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19741 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19742 switch (Binder.getCallingUid()) {
19747 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19748 + Binder.getCallingUid());
19749 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19757 public final int broadcastIntent(IApplicationThread caller,
19758 Intent intent, String resolvedType, IIntentReceiver resultTo,
19759 int resultCode, String resultData, Bundle resultExtras,
19760 String[] requiredPermissions, int appOp, Bundle bOptions,
19761 boolean serialized, boolean sticky, int userId) {
19762 enforceNotIsolatedCaller("broadcastIntent");
19763 synchronized(this) {
19764 intent = verifyBroadcastLocked(intent);
19766 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19767 final int callingPid = Binder.getCallingPid();
19768 final int callingUid = Binder.getCallingUid();
19769 final long origId = Binder.clearCallingIdentity();
19770 int res = broadcastIntentLocked(callerApp,
19771 callerApp != null ? callerApp.info.packageName : null,
19772 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19773 requiredPermissions, appOp, bOptions, serialized, sticky,
19774 callingPid, callingUid, userId);
19775 Binder.restoreCallingIdentity(origId);
19781 int broadcastIntentInPackage(String packageName, int uid,
19782 Intent intent, String resolvedType, IIntentReceiver resultTo,
19783 int resultCode, String resultData, Bundle resultExtras,
19784 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19786 synchronized(this) {
19787 intent = verifyBroadcastLocked(intent);
19789 final long origId = Binder.clearCallingIdentity();
19790 String[] requiredPermissions = requiredPermission == null ? null
19791 : new String[] {requiredPermission};
19792 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19793 resultTo, resultCode, resultData, resultExtras,
19794 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19795 sticky, -1, uid, userId);
19796 Binder.restoreCallingIdentity(origId);
19801 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19802 // Refuse possible leaked file descriptors
19803 if (intent != null && intent.hasFileDescriptors() == true) {
19804 throw new IllegalArgumentException("File descriptors passed in Intent");
19807 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19808 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19810 synchronized(this) {
19811 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19812 != PackageManager.PERMISSION_GRANTED) {
19813 String msg = "Permission Denial: unbroadcastIntent() from pid="
19814 + Binder.getCallingPid()
19815 + ", uid=" + Binder.getCallingUid()
19816 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19818 throw new SecurityException(msg);
19820 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19821 if (stickies != null) {
19822 ArrayList<Intent> list = stickies.get(intent.getAction());
19823 if (list != null) {
19824 int N = list.size();
19826 for (i=0; i<N; i++) {
19827 if (intent.filterEquals(list.get(i))) {
19832 if (list.size() <= 0) {
19833 stickies.remove(intent.getAction());
19836 if (stickies.size() <= 0) {
19837 mStickyBroadcasts.remove(userId);
19843 void backgroundServicesFinishedLocked(int userId) {
19844 for (BroadcastQueue queue : mBroadcastQueues) {
19845 queue.backgroundServicesFinishedLocked(userId);
19849 public void finishReceiver(IBinder who, int resultCode, String resultData,
19850 Bundle resultExtras, boolean resultAbort, int flags) {
19851 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19853 // Refuse possible leaked file descriptors
19854 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19855 throw new IllegalArgumentException("File descriptors passed in Bundle");
19858 final long origId = Binder.clearCallingIdentity();
19860 boolean doNext = false;
19863 synchronized(this) {
19864 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19865 ? mFgBroadcastQueue : mBgBroadcastQueue;
19866 r = queue.getMatchingOrderedReceiver(who);
19868 doNext = r.queue.finishReceiverLocked(r, resultCode,
19869 resultData, resultExtras, resultAbort, true);
19874 r.queue.processNextBroadcast(false);
19876 trimApplications();
19878 Binder.restoreCallingIdentity(origId);
19882 // =========================================================
19884 // =========================================================
19886 public boolean startInstrumentation(ComponentName className,
19887 String profileFile, int flags, Bundle arguments,
19888 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19889 int userId, String abiOverride) {
19890 enforceNotIsolatedCaller("startInstrumentation");
19891 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19892 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19893 // Refuse possible leaked file descriptors
19894 if (arguments != null && arguments.hasFileDescriptors()) {
19895 throw new IllegalArgumentException("File descriptors passed in Bundle");
19898 synchronized(this) {
19899 InstrumentationInfo ii = null;
19900 ApplicationInfo ai = null;
19902 ii = mContext.getPackageManager().getInstrumentationInfo(
19903 className, STOCK_PM_FLAGS);
19904 ai = AppGlobals.getPackageManager().getApplicationInfo(
19905 ii.targetPackage, STOCK_PM_FLAGS, userId);
19906 } catch (PackageManager.NameNotFoundException e) {
19907 } catch (RemoteException e) {
19910 reportStartInstrumentationFailureLocked(watcher, className,
19911 "Unable to find instrumentation info for: " + className);
19915 reportStartInstrumentationFailureLocked(watcher, className,
19916 "Unable to find instrumentation target package: " + ii.targetPackage);
19919 if (!ai.hasCode()) {
19920 reportStartInstrumentationFailureLocked(watcher, className,
19921 "Instrumentation target has no code: " + ii.targetPackage);
19925 int match = mContext.getPackageManager().checkSignatures(
19926 ii.targetPackage, ii.packageName);
19927 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19928 String msg = "Permission Denial: starting instrumentation "
19929 + className + " from pid="
19930 + Binder.getCallingPid()
19931 + ", uid=" + Binder.getCallingPid()
19932 + " not allowed because package " + ii.packageName
19933 + " does not have a signature matching the target "
19934 + ii.targetPackage;
19935 reportStartInstrumentationFailureLocked(watcher, className, msg);
19936 throw new SecurityException(msg);
19939 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19940 activeInstr.mClass = className;
19941 String defProcess = ai.processName;;
19942 if (ii.targetProcesses == null) {
19943 activeInstr.mTargetProcesses = new String[]{ai.processName};
19944 } else if (ii.targetProcesses.equals("*")) {
19945 activeInstr.mTargetProcesses = new String[0];
19947 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19948 defProcess = activeInstr.mTargetProcesses[0];
19950 activeInstr.mTargetInfo = ai;
19951 activeInstr.mProfileFile = profileFile;
19952 activeInstr.mArguments = arguments;
19953 activeInstr.mWatcher = watcher;
19954 activeInstr.mUiAutomationConnection = uiAutomationConnection;
19955 activeInstr.mResultClass = className;
19957 final long origId = Binder.clearCallingIdentity();
19958 // Instrumentation can kill and relaunch even persistent processes
19959 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19961 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19962 app.instr = activeInstr;
19963 activeInstr.mFinished = false;
19964 activeInstr.mRunningProcesses.add(app);
19965 if (!mActiveInstrumentation.contains(activeInstr)) {
19966 mActiveInstrumentation.add(activeInstr);
19968 Binder.restoreCallingIdentity(origId);
19975 * Report errors that occur while attempting to start Instrumentation. Always writes the
19976 * error to the logs, but if somebody is watching, send the report there too. This enables
19977 * the "am" command to report errors with more information.
19979 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
19980 * @param cn The component name of the instrumentation.
19981 * @param report The error report.
19983 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19984 ComponentName cn, String report) {
19985 Slog.w(TAG, report);
19986 if (watcher != null) {
19987 Bundle results = new Bundle();
19988 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19989 results.putString("Error", report);
19990 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19994 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19995 if (app.instr == null) {
19996 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20000 if (!app.instr.mFinished && results != null) {
20001 if (app.instr.mCurResults == null) {
20002 app.instr.mCurResults = new Bundle(results);
20004 app.instr.mCurResults.putAll(results);
20009 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20010 int userId = UserHandle.getCallingUserId();
20011 // Refuse possible leaked file descriptors
20012 if (results != null && results.hasFileDescriptors()) {
20013 throw new IllegalArgumentException("File descriptors passed in Intent");
20016 synchronized(this) {
20017 ProcessRecord app = getRecordForAppLocked(target);
20019 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20022 final long origId = Binder.clearCallingIdentity();
20023 addInstrumentationResultsLocked(app, results);
20024 Binder.restoreCallingIdentity(origId);
20028 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20029 if (app.instr == null) {
20030 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20034 if (!app.instr.mFinished) {
20035 if (app.instr.mWatcher != null) {
20036 Bundle finalResults = app.instr.mCurResults;
20037 if (finalResults != null) {
20038 if (app.instr.mCurResults != null && results != null) {
20039 finalResults.putAll(results);
20042 finalResults = results;
20044 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20045 app.instr.mClass, resultCode, finalResults);
20048 // Can't call out of the system process with a lock held, so post a message.
20049 if (app.instr.mUiAutomationConnection != null) {
20050 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20051 app.instr.mUiAutomationConnection).sendToTarget();
20053 app.instr.mFinished = true;
20056 app.instr.removeProcess(app);
20059 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20063 public void finishInstrumentation(IApplicationThread target,
20064 int resultCode, Bundle results) {
20065 int userId = UserHandle.getCallingUserId();
20066 // Refuse possible leaked file descriptors
20067 if (results != null && results.hasFileDescriptors()) {
20068 throw new IllegalArgumentException("File descriptors passed in Intent");
20071 synchronized(this) {
20072 ProcessRecord app = getRecordForAppLocked(target);
20074 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20077 final long origId = Binder.clearCallingIdentity();
20078 finishInstrumentationLocked(app, resultCode, results);
20079 Binder.restoreCallingIdentity(origId);
20083 // =========================================================
20085 // =========================================================
20087 public ConfigurationInfo getDeviceConfigurationInfo() {
20088 ConfigurationInfo config = new ConfigurationInfo();
20089 synchronized (this) {
20090 final Configuration globalConfig = getGlobalConfiguration();
20091 config.reqTouchScreen = globalConfig.touchscreen;
20092 config.reqKeyboardType = globalConfig.keyboard;
20093 config.reqNavigation = globalConfig.navigation;
20094 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20095 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20096 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20098 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20099 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20100 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20102 config.reqGlEsVersion = GL_ES_VERSION;
20107 ActivityStack getFocusedStack() {
20108 return mStackSupervisor.getFocusedStack();
20112 public int getFocusedStackId() throws RemoteException {
20113 ActivityStack focusedStack = getFocusedStack();
20114 if (focusedStack != null) {
20115 return focusedStack.getStackId();
20120 public Configuration getConfiguration() {
20122 synchronized(this) {
20123 ci = new Configuration(getGlobalConfiguration());
20124 ci.userSetLocale = false;
20130 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20131 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20132 synchronized (this) {
20133 mSuppressResizeConfigChanges = suppress;
20138 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20139 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20140 * activity and clearing the task at the same time.
20143 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20144 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20145 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20146 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20148 synchronized (this) {
20149 final long origId = Binder.clearCallingIdentity();
20151 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20153 Binder.restoreCallingIdentity(origId);
20159 public void updatePersistentConfiguration(Configuration values) {
20160 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20161 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20162 if (values == null) {
20163 throw new NullPointerException("Configuration must not be null");
20166 int userId = UserHandle.getCallingUserId();
20168 synchronized(this) {
20169 updatePersistentConfigurationLocked(values, userId);
20173 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20174 final long origId = Binder.clearCallingIdentity();
20176 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20178 Binder.restoreCallingIdentity(origId);
20182 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20183 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20184 FONT_SCALE, 1.0f, userId);
20186 synchronized (this) {
20187 if (getGlobalConfiguration().fontScale == scaleFactor) {
20191 final Configuration configuration
20192 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20193 configuration.fontScale = scaleFactor;
20194 updatePersistentConfigurationLocked(configuration, userId);
20198 private void enforceWriteSettingsPermission(String func) {
20199 int uid = Binder.getCallingUid();
20200 if (uid == ROOT_UID) {
20204 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20205 Settings.getPackageNameForUid(mContext, uid), false)) {
20209 String msg = "Permission Denial: " + func + " from pid="
20210 + Binder.getCallingPid()
20212 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20214 throw new SecurityException(msg);
20218 public boolean updateConfiguration(Configuration values) {
20219 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20221 synchronized(this) {
20222 if (values == null && mWindowManager != null) {
20223 // sentinel: fetch the current configuration from the window manager
20224 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20227 if (mWindowManager != null) {
20228 // Update OOM levels based on display size.
20229 mProcessList.applyDisplaySize(mWindowManager);
20232 final long origId = Binder.clearCallingIdentity();
20234 if (values != null) {
20235 Settings.System.clearConfiguration(values);
20237 updateConfigurationLocked(values, null, false, false /* persistent */,
20238 UserHandle.USER_NULL, false /* deferResume */,
20239 mTmpUpdateConfigurationResult);
20240 return mTmpUpdateConfigurationResult.changes != 0;
20242 Binder.restoreCallingIdentity(origId);
20247 void updateUserConfigurationLocked() {
20248 final Configuration configuration = new Configuration(getGlobalConfiguration());
20249 final int currentUserId = mUserController.getCurrentUserIdLocked();
20250 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20251 currentUserId, Settings.System.canWrite(mContext));
20252 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20253 false /* persistent */, currentUserId, false /* deferResume */);
20256 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20257 boolean initLocale) {
20258 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20261 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20262 boolean initLocale, boolean deferResume) {
20263 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20264 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20265 UserHandle.USER_NULL, deferResume);
20268 // To cache the list of supported system locales
20269 private String[] mSupportedSystemLocales = null;
20271 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20272 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20273 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20274 deferResume, null /* result */);
20278 * Do either or both things: (1) change the current configuration, and (2)
20279 * make sure the given activity is running with the (now) current
20280 * configuration. Returns true if the activity has been left running, or
20281 * false if <var>starting</var> is being destroyed to match the new
20284 * @param userId is only used when persistent parameter is set to true to persist configuration
20285 * for that particular user
20287 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20288 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20289 UpdateConfigurationResult result) {
20291 boolean kept = true;
20293 if (mWindowManager != null) {
20294 mWindowManager.deferSurfaceLayout();
20297 if (values != null) {
20298 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20302 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20304 if (mWindowManager != null) {
20305 mWindowManager.continueSurfaceLayout();
20309 if (result != null) {
20310 result.changes = changes;
20311 result.activityRelaunched = !kept;
20316 /** Update default (global) configuration and notify listeners about changes. */
20317 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20318 boolean persistent, int userId, boolean deferResume) {
20319 mTempConfig.setTo(getGlobalConfiguration());
20320 final int changes = mTempConfig.updateFrom(values);
20321 if (changes == 0) {
20322 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20323 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20324 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20325 // (even if there are no actual changes) to unfreeze the window.
20326 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20330 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20331 "Updating global configuration to: " + values);
20333 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20335 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20336 final LocaleList locales = values.getLocales();
20337 int bestLocaleIndex = 0;
20338 if (locales.size() > 1) {
20339 if (mSupportedSystemLocales == null) {
20340 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20342 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20344 SystemProperties.set("persist.sys.locale",
20345 locales.get(bestLocaleIndex).toLanguageTag());
20346 LocaleList.setDefault(locales, bestLocaleIndex);
20347 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20348 locales.get(bestLocaleIndex)));
20351 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20352 mTempConfig.seq = mConfigurationSeq;
20354 // Update stored global config and notify everyone about the change.
20355 mStackSupervisor.onConfigurationChanged(mTempConfig);
20357 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20358 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20359 mUsageStatsService.reportConfigurationChange(mTempConfig,
20360 mUserController.getCurrentUserIdLocked());
20362 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20363 mShowDialogs = shouldShowDialogs(mTempConfig);
20365 AttributeCache ac = AttributeCache.instance();
20367 ac.updateConfiguration(mTempConfig);
20370 // Make sure all resources in our process are updated right now, so that anyone who is going
20371 // to retrieve resource values after we return will be sure to get the new ones. This is
20372 // especially important during boot, where the first config change needs to guarantee all
20373 // resources have that config before following boot code is executed.
20374 mSystemThread.applyConfigurationToResources(mTempConfig);
20376 // We need another copy of global config because we're scheduling some calls instead of
20377 // running them in place. We need to be sure that object we send will be handled unchanged.
20378 final Configuration configCopy = new Configuration(mTempConfig);
20379 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20380 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20381 msg.obj = configCopy;
20383 mHandler.sendMessage(msg);
20386 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20387 ProcessRecord app = mLruProcesses.get(i);
20389 if (app.thread != null) {
20390 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20391 + app.processName + " new config " + configCopy);
20392 app.thread.scheduleConfigurationChanged(configCopy);
20394 } catch (Exception e) {
20398 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20399 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20400 | Intent.FLAG_RECEIVER_FOREGROUND
20401 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20402 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20403 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20404 UserHandle.USER_ALL);
20405 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20406 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20407 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20408 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20409 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20410 if (initLocale || !mProcessesReady) {
20411 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20413 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20414 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20415 UserHandle.USER_ALL);
20418 // Override configuration of the default display duplicates global config, so we need to
20419 // update it also. This will also notify WindowManager about changes.
20420 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20427 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20428 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20430 synchronized (this) {
20431 // Check if display is initialized in AM.
20432 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20433 // Call might come when display is not yet added or has already been removed.
20434 if (DEBUG_CONFIGURATION) {
20435 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20441 if (values == null && mWindowManager != null) {
20442 // sentinel: fetch the current configuration from the window manager
20443 values = mWindowManager.computeNewConfiguration(displayId);
20446 if (mWindowManager != null) {
20447 // Update OOM levels based on display size.
20448 mProcessList.applyDisplaySize(mWindowManager);
20451 final long origId = Binder.clearCallingIdentity();
20453 if (values != null) {
20454 Settings.System.clearConfiguration(values);
20456 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20457 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20458 return mTmpUpdateConfigurationResult.changes != 0;
20460 Binder.restoreCallingIdentity(origId);
20465 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20466 boolean deferResume, int displayId) {
20467 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20468 displayId, null /* result */);
20472 * Updates override configuration specific for the selected display. If no config is provided,
20473 * new one will be computed in WM based on current display info.
20475 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20476 ActivityRecord starting, boolean deferResume, int displayId,
20477 UpdateConfigurationResult result) {
20479 boolean kept = true;
20481 if (mWindowManager != null) {
20482 mWindowManager.deferSurfaceLayout();
20485 if (values != null) {
20486 if (displayId == DEFAULT_DISPLAY) {
20487 // Override configuration of the default display duplicates global config, so
20488 // we're calling global config update instead for default display. It will also
20489 // apply the correct override config.
20490 changes = updateGlobalConfiguration(values, false /* initLocale */,
20491 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20493 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20497 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20499 if (mWindowManager != null) {
20500 mWindowManager.continueSurfaceLayout();
20504 if (result != null) {
20505 result.changes = changes;
20506 result.activityRelaunched = !kept;
20511 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20513 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20514 final int changes = mTempConfig.updateFrom(values);
20515 if (changes != 0) {
20516 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20517 + mTempConfig + " for displayId=" + displayId);
20518 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20520 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20521 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20522 // Reset the unsupported display size dialog.
20523 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20525 killAllBackgroundProcessesExcept(N,
20526 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20530 // Update the configuration with WM first and check if any of the stacks need to be resized
20531 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20532 // necessary. This way we don't need to relaunch again afterwards in
20533 // ensureActivityConfigurationLocked().
20534 if (mWindowManager != null) {
20535 final int[] resizedStacks =
20536 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20537 if (resizedStacks != null) {
20538 for (int stackId : resizedStacks) {
20539 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20547 /** Applies latest configuration and/or visibility updates if needed. */
20548 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20549 boolean kept = true;
20550 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20551 // mainStack is null during startup.
20552 if (mainStack != null) {
20553 if (changes != 0 && starting == null) {
20554 // If the configuration changed, and the caller is not already
20555 // in the process of starting an activity, then find the top
20556 // activity to check if its configuration needs to change.
20557 starting = mainStack.topRunningActivityLocked();
20560 if (starting != null) {
20561 kept = starting.ensureActivityConfigurationLocked(changes,
20562 false /* preserveWindow */);
20563 // And we need to make sure at this point that all other activities
20564 // are made visible with the correct configuration.
20565 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20566 !PRESERVE_WINDOWS);
20573 /** Helper method that requests bounds from WM and applies them to stack. */
20574 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20575 final Rect newStackBounds = new Rect();
20576 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20577 mStackSupervisor.resizeStackLocked(
20578 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20579 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20580 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20584 * Decide based on the configuration whether we should show the ANR,
20585 * crash, etc dialogs. The idea is that if there is no affordance to
20586 * press the on-screen buttons, or the user experience would be more
20587 * greatly impacted than the crash itself, we shouldn't show the dialog.
20589 * A thought: SystemUI might also want to get told about this, the Power
20590 * dialog / global actions also might want different behaviors.
20592 private static boolean shouldShowDialogs(Configuration config) {
20593 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20594 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20595 && config.navigation == Configuration.NAVIGATION_NONAV);
20596 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20597 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20598 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20599 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20600 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20601 return inputMethodExists && uiModeSupportsDialogs;
20605 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20606 synchronized (this) {
20607 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20608 if (srec != null) {
20609 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20615 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20616 Intent resultData) {
20618 synchronized (this) {
20619 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20621 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20627 public int getLaunchedFromUid(IBinder activityToken) {
20628 ActivityRecord srec;
20629 synchronized (this) {
20630 srec = ActivityRecord.forTokenLocked(activityToken);
20632 if (srec == null) {
20635 return srec.launchedFromUid;
20638 public String getLaunchedFromPackage(IBinder activityToken) {
20639 ActivityRecord srec;
20640 synchronized (this) {
20641 srec = ActivityRecord.forTokenLocked(activityToken);
20643 if (srec == null) {
20646 return srec.launchedFromPackage;
20649 // =========================================================
20650 // LIFETIME MANAGEMENT
20651 // =========================================================
20653 // Returns whether the app is receiving broadcast.
20654 // If receiving, fetch all broadcast queues which the app is
20655 // the current [or imminent] receiver on.
20656 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20657 ArraySet<BroadcastQueue> receivingQueues) {
20658 if (!app.curReceivers.isEmpty()) {
20659 for (BroadcastRecord r : app.curReceivers) {
20660 receivingQueues.add(r.queue);
20665 // It's not the current receiver, but it might be starting up to become one
20666 for (BroadcastQueue queue : mBroadcastQueues) {
20667 final BroadcastRecord r = queue.mPendingBroadcast;
20668 if (r != null && r.curApp == app) {
20669 // found it; report which queue it's in
20670 receivingQueues.add(queue);
20674 return !receivingQueues.isEmpty();
20677 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20678 int targetUid, ComponentName targetComponent, String targetProcess) {
20679 if (!mTrackingAssociations) {
20682 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20683 = mAssociations.get(targetUid);
20684 if (components == null) {
20685 components = new ArrayMap<>();
20686 mAssociations.put(targetUid, components);
20688 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20689 if (sourceUids == null) {
20690 sourceUids = new SparseArray<>();
20691 components.put(targetComponent, sourceUids);
20693 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20694 if (sourceProcesses == null) {
20695 sourceProcesses = new ArrayMap<>();
20696 sourceUids.put(sourceUid, sourceProcesses);
20698 Association ass = sourceProcesses.get(sourceProcess);
20700 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20702 sourceProcesses.put(sourceProcess, ass);
20706 if (ass.mNesting == 1) {
20707 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20708 ass.mLastState = sourceState;
20713 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20714 ComponentName targetComponent) {
20715 if (!mTrackingAssociations) {
20718 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20719 = mAssociations.get(targetUid);
20720 if (components == null) {
20723 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20724 if (sourceUids == null) {
20727 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20728 if (sourceProcesses == null) {
20731 Association ass = sourceProcesses.get(sourceProcess);
20732 if (ass == null || ass.mNesting <= 0) {
20736 if (ass.mNesting == 0) {
20737 long uptime = SystemClock.uptimeMillis();
20738 ass.mTime += uptime - ass.mStartTime;
20739 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20740 += uptime - ass.mLastStateUptime;
20741 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20745 private void noteUidProcessState(final int uid, final int state) {
20746 mBatteryStatsService.noteUidProcessState(uid, state);
20747 if (mTrackingAssociations) {
20748 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20749 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20750 = mAssociations.valueAt(i1);
20751 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20752 SparseArray<ArrayMap<String, Association>> sourceUids
20753 = targetComponents.valueAt(i2);
20754 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20755 if (sourceProcesses != null) {
20756 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20757 Association ass = sourceProcesses.valueAt(i4);
20758 if (ass.mNesting >= 1) {
20759 // currently associated
20760 long uptime = SystemClock.uptimeMillis();
20761 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20762 += uptime - ass.mLastStateUptime;
20763 ass.mLastState = state;
20764 ass.mLastStateUptime = uptime;
20773 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20774 boolean doingAll, long now) {
20775 if (mAdjSeq == app.adjSeq) {
20776 // This adjustment has already been computed.
20777 return app.curRawAdj;
20780 if (app.thread == null) {
20781 app.adjSeq = mAdjSeq;
20782 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20783 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20784 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20787 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20788 app.adjSource = null;
20789 app.adjTarget = null;
20791 app.cached = false;
20793 final int activitiesSize = app.activities.size();
20795 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20796 // The max adjustment doesn't allow this app to be anything
20797 // below foreground, so it is not worth doing work for it.
20798 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20799 app.adjType = "fixed";
20800 app.adjSeq = mAdjSeq;
20801 app.curRawAdj = app.maxAdj;
20802 app.foregroundActivities = false;
20803 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20804 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20805 // System processes can do UI, and when they do we want to have
20806 // them trim their memory after the user leaves the UI. To
20807 // facilitate this, here we need to determine whether or not it
20808 // is currently showing UI.
20809 app.systemNoUi = true;
20810 if (app == TOP_APP) {
20811 app.systemNoUi = false;
20812 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20813 app.adjType = "pers-top-activity";
20814 } else if (app.hasTopUi) {
20815 app.systemNoUi = false;
20816 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20817 app.adjType = "pers-top-ui";
20818 } else if (activitiesSize > 0) {
20819 for (int j = 0; j < activitiesSize; j++) {
20820 final ActivityRecord r = app.activities.get(j);
20822 app.systemNoUi = false;
20826 if (!app.systemNoUi) {
20827 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20829 return (app.curAdj=app.maxAdj);
20832 app.systemNoUi = false;
20834 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20836 // Determine the importance of the process, starting with most
20837 // important to least, and assign an appropriate OOM adjustment.
20841 boolean foregroundActivities = false;
20842 mTmpBroadcastQueue.clear();
20843 if (app == TOP_APP) {
20844 // The last app on the list is the foreground app.
20845 adj = ProcessList.FOREGROUND_APP_ADJ;
20846 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20847 app.adjType = "top-activity";
20848 foregroundActivities = true;
20849 procState = PROCESS_STATE_CUR_TOP;
20850 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20851 } else if (app.instr != null) {
20852 // Don't want to kill running instrumentation.
20853 adj = ProcessList.FOREGROUND_APP_ADJ;
20854 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20855 app.adjType = "instrumentation";
20856 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20857 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20858 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20859 // An app that is currently receiving a broadcast also
20860 // counts as being in the foreground for OOM killer purposes.
20861 // It's placed in a sched group based on the nature of the
20862 // broadcast as reflected by which queue it's active in.
20863 adj = ProcessList.FOREGROUND_APP_ADJ;
20864 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20865 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20866 app.adjType = "broadcast";
20867 procState = ActivityManager.PROCESS_STATE_RECEIVER;
20868 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20869 } else if (app.executingServices.size() > 0) {
20870 // An app that is currently executing a service callback also
20871 // counts as being in the foreground.
20872 adj = ProcessList.FOREGROUND_APP_ADJ;
20873 schedGroup = app.execServicesFg ?
20874 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20875 app.adjType = "exec-service";
20876 procState = ActivityManager.PROCESS_STATE_SERVICE;
20877 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20878 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20880 // As far as we know the process is empty. We may change our mind later.
20881 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20882 // At this point we don't actually know the adjustment. Use the cached adj
20883 // value that the caller wants us to.
20885 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20888 app.adjType = "cch-empty";
20889 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20892 // Examine all activities if not already foreground.
20893 if (!foregroundActivities && activitiesSize > 0) {
20894 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20895 for (int j = 0; j < activitiesSize; j++) {
20896 final ActivityRecord r = app.activities.get(j);
20897 if (r.app != app) {
20898 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20899 + " instead of expected " + app);
20900 if (r.app == null || (r.app.uid == app.uid)) {
20901 // Only fix things up when they look sane
20908 // App has a visible activity; only upgrade adjustment.
20909 if (adj > ProcessList.VISIBLE_APP_ADJ) {
20910 adj = ProcessList.VISIBLE_APP_ADJ;
20911 app.adjType = "vis-activity";
20912 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20914 if (procState > PROCESS_STATE_CUR_TOP) {
20915 procState = PROCESS_STATE_CUR_TOP;
20916 app.adjType = "vis-activity";
20917 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20919 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20920 app.cached = false;
20922 foregroundActivities = true;
20923 final TaskRecord task = r.getTask();
20924 if (task != null && minLayer > 0) {
20925 final int layer = task.mLayerRank;
20926 if (layer >= 0 && minLayer > layer) {
20931 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20932 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20933 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20934 app.adjType = "pause-activity";
20935 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20937 if (procState > PROCESS_STATE_CUR_TOP) {
20938 procState = PROCESS_STATE_CUR_TOP;
20939 app.adjType = "pause-activity";
20940 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20942 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20943 app.cached = false;
20945 foregroundActivities = true;
20946 } else if (r.state == ActivityState.STOPPING) {
20947 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20948 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20949 app.adjType = "stop-activity";
20950 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20952 // For the process state, we will at this point consider the
20953 // process to be cached. It will be cached either as an activity
20954 // or empty depending on whether the activity is finishing. We do
20955 // this so that we can treat the process as cached for purposes of
20956 // memory trimming (determing current memory level, trim command to
20957 // send to process) since there can be an arbitrary number of stopping
20958 // processes and they should soon all go into the cached state.
20959 if (!r.finishing) {
20960 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20961 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20962 app.adjType = "stop-activity";
20963 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20966 app.cached = false;
20968 foregroundActivities = true;
20970 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20971 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20972 app.adjType = "cch-act";
20973 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20977 if (adj == ProcessList.VISIBLE_APP_ADJ) {
20982 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20983 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20984 if (app.foregroundServices) {
20985 // The user is aware of this app, so make it visible.
20986 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20987 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20988 app.cached = false;
20989 app.adjType = "fg-service";
20990 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20991 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
20992 } else if (app.hasOverlayUi) {
20993 // The process is display an overlay UI.
20994 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20995 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20996 app.cached = false;
20997 app.adjType = "has-overlay-ui";
20998 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20999 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21003 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21004 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21005 if (app.forcingToImportant != null) {
21006 // This is currently used for toasts... they are not interactive, and
21007 // we don't want them to cause the app to become fully foreground (and
21008 // thus out of background check), so we yes the best background level we can.
21009 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21010 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21011 app.cached = false;
21012 app.adjType = "force-imp";
21013 app.adjSource = app.forcingToImportant;
21014 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21015 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21019 if (app == mHeavyWeightProcess) {
21020 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21021 // We don't want to kill the current heavy-weight process.
21022 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21023 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21024 app.cached = false;
21025 app.adjType = "heavy";
21026 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21028 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21029 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21030 app.adjType = "heavy";
21031 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21035 if (app == mHomeProcess) {
21036 if (adj > ProcessList.HOME_APP_ADJ) {
21037 // This process is hosting what we currently consider to be the
21038 // home app, so we don't want to let it go into the background.
21039 adj = ProcessList.HOME_APP_ADJ;
21040 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21041 app.cached = false;
21042 app.adjType = "home";
21043 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21045 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21046 procState = ActivityManager.PROCESS_STATE_HOME;
21047 app.adjType = "home";
21048 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21052 if (app == mPreviousProcess && app.activities.size() > 0) {
21053 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21054 // This was the previous process that showed UI to the user.
21055 // We want to try to keep it around more aggressively, to give
21056 // a good experience around switching between two apps.
21057 adj = ProcessList.PREVIOUS_APP_ADJ;
21058 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21059 app.cached = false;
21060 app.adjType = "previous";
21061 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21063 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21064 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21065 app.adjType = "previous";
21066 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21070 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21071 + " reason=" + app.adjType);
21073 // By default, we use the computed adjustment. It may be changed if
21074 // there are applications dependent on our services or providers, but
21075 // this gives us a baseline and makes sure we don't get into an
21076 // infinite recursion.
21077 app.adjSeq = mAdjSeq;
21078 app.curRawAdj = adj;
21079 app.hasStartedServices = false;
21081 if (mBackupTarget != null && app == mBackupTarget.app) {
21082 // If possible we want to avoid killing apps while they're being backed up
21083 if (adj > ProcessList.BACKUP_APP_ADJ) {
21084 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21085 adj = ProcessList.BACKUP_APP_ADJ;
21086 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21087 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21089 app.adjType = "backup";
21090 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21091 app.cached = false;
21093 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21094 procState = ActivityManager.PROCESS_STATE_BACKUP;
21095 app.adjType = "backup";
21096 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21100 boolean mayBeTop = false;
21101 String mayBeTopType = null;
21102 Object mayBeTopSource = null;
21103 Object mayBeTopTarget = null;
21105 for (int is = app.services.size()-1;
21106 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21107 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21108 || procState > ActivityManager.PROCESS_STATE_TOP);
21110 ServiceRecord s = app.services.valueAt(is);
21111 if (s.startRequested) {
21112 app.hasStartedServices = true;
21113 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21114 procState = ActivityManager.PROCESS_STATE_SERVICE;
21115 app.adjType = "started-services";
21116 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21118 if (app.hasShownUi && app != mHomeProcess) {
21119 // If this process has shown some UI, let it immediately
21120 // go to the LRU list because it may be pretty heavy with
21121 // UI stuff. We'll tag it with a label just to help
21122 // debug and understand what is going on.
21123 if (adj > ProcessList.SERVICE_ADJ) {
21124 app.adjType = "cch-started-ui-services";
21127 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21128 // This service has seen some activity within
21129 // recent memory, so we will keep its process ahead
21130 // of the background processes.
21131 if (adj > ProcessList.SERVICE_ADJ) {
21132 adj = ProcessList.SERVICE_ADJ;
21133 app.adjType = "started-services";
21134 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21135 app.cached = false;
21138 // If we have let the service slide into the background
21139 // state, still have some text describing what it is doing
21140 // even though the service no longer has an impact.
21141 if (adj > ProcessList.SERVICE_ADJ) {
21142 app.adjType = "cch-started-services";
21147 for (int conni = s.connections.size()-1;
21148 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21149 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21150 || procState > ActivityManager.PROCESS_STATE_TOP);
21152 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21154 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21155 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21156 || procState > ActivityManager.PROCESS_STATE_TOP);
21158 // XXX should compute this based on the max of
21159 // all connected clients.
21160 ConnectionRecord cr = clist.get(i);
21161 if (cr.binding.client == app) {
21162 // Binding to ourself is not interesting.
21166 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21167 ProcessRecord client = cr.binding.client;
21168 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21169 TOP_APP, doingAll, now);
21170 int clientProcState = client.curProcState;
21171 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21172 // If the other app is cached for any reason, for purposes here
21173 // we are going to consider it empty. The specific cached state
21174 // doesn't propagate except under certain conditions.
21175 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21177 String adjType = null;
21178 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21179 // Not doing bind OOM management, so treat
21180 // this guy more like a started service.
21181 if (app.hasShownUi && app != mHomeProcess) {
21182 // If this process has shown some UI, let it immediately
21183 // go to the LRU list because it may be pretty heavy with
21184 // UI stuff. We'll tag it with a label just to help
21185 // debug and understand what is going on.
21186 if (adj > clientAdj) {
21187 adjType = "cch-bound-ui-services";
21189 app.cached = false;
21191 clientProcState = procState;
21193 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21194 // This service has not seen activity within
21195 // recent memory, so allow it to drop to the
21196 // LRU list if there is no other reason to keep
21197 // it around. We'll also tag it with a label just
21198 // to help debug and undertand what is going on.
21199 if (adj > clientAdj) {
21200 adjType = "cch-bound-services";
21206 if (adj > clientAdj) {
21207 // If this process has recently shown UI, and
21208 // the process that is binding to it is less
21209 // important than being visible, then we don't
21210 // care about the binding as much as we care
21211 // about letting this process get into the LRU
21212 // list to be killed and restarted if needed for
21214 if (app.hasShownUi && app != mHomeProcess
21215 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21216 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21217 adjType = "cch-bound-ui-services";
21221 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21222 |Context.BIND_IMPORTANT)) != 0) {
21223 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21224 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21225 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21226 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21227 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21228 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21229 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21230 newAdj = clientAdj;
21232 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21233 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21238 if (!client.cached) {
21239 app.cached = false;
21241 if (adj > newAdj) {
21243 adjType = "service";
21247 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21248 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21249 // This will treat important bound services identically to
21250 // the top app, which may behave differently than generic
21251 // foreground work.
21252 if (client.curSchedGroup > schedGroup) {
21253 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21254 schedGroup = client.curSchedGroup;
21256 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21259 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21260 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21261 // Special handling of clients who are in the top state.
21262 // We *may* want to consider this process to be in the
21263 // top state as well, but only if there is not another
21264 // reason for it to be running. Being on the top is a
21265 // special state, meaning you are specifically running
21266 // for the current top app. If the process is already
21267 // running in the background for some other reason, it
21268 // is more important to continue considering it to be
21269 // in the background state.
21271 mayBeTopType = "service";
21272 mayBeTopSource = cr.binding.client;
21273 mayBeTopTarget = s.name;
21274 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21276 // Special handling for above-top states (persistent
21277 // processes). These should not bring the current process
21278 // into the top state, since they are not on top. Instead
21279 // give them the best state after that.
21280 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21282 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21283 } else if (mWakefulness
21284 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21285 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21288 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21291 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21295 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21296 if (clientProcState <
21297 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21299 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21302 if (clientProcState <
21303 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21305 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21308 if (procState > clientProcState) {
21309 procState = clientProcState;
21310 if (adjType == null) {
21311 adjType = "service";
21314 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21315 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21316 app.pendingUiClean = true;
21318 if (adjType != null) {
21319 app.adjType = adjType;
21320 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21321 .REASON_SERVICE_IN_USE;
21322 app.adjSource = cr.binding.client;
21323 app.adjSourceProcState = clientProcState;
21324 app.adjTarget = s.name;
21325 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21326 + ": " + app + ", due to " + cr.binding.client
21327 + " adj=" + adj + " procState=" + procState);
21330 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21331 app.treatLikeActivity = true;
21333 final ActivityRecord a = cr.activity;
21334 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21335 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21336 (a.visible || a.state == ActivityState.RESUMED ||
21337 a.state == ActivityState.PAUSING)) {
21338 adj = ProcessList.FOREGROUND_APP_ADJ;
21339 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21340 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21341 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21343 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21346 app.cached = false;
21347 app.adjType = "service";
21348 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21349 .REASON_SERVICE_IN_USE;
21351 app.adjSourceProcState = procState;
21352 app.adjTarget = s.name;
21353 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21361 for (int provi = app.pubProviders.size()-1;
21362 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21363 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21364 || procState > ActivityManager.PROCESS_STATE_TOP);
21366 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21367 for (int i = cpr.connections.size()-1;
21368 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21369 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21370 || procState > ActivityManager.PROCESS_STATE_TOP);
21372 ContentProviderConnection conn = cpr.connections.get(i);
21373 ProcessRecord client = conn.client;
21374 if (client == app) {
21375 // Being our own client is not interesting.
21378 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21379 int clientProcState = client.curProcState;
21380 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21381 // If the other app is cached for any reason, for purposes here
21382 // we are going to consider it empty.
21383 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21385 String adjType = null;
21386 if (adj > clientAdj) {
21387 if (app.hasShownUi && app != mHomeProcess
21388 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21389 adjType = "cch-ui-provider";
21391 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21392 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21393 adjType = "provider";
21395 app.cached &= client.cached;
21397 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21398 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21399 // Special handling of clients who are in the top state.
21400 // We *may* want to consider this process to be in the
21401 // top state as well, but only if there is not another
21402 // reason for it to be running. Being on the top is a
21403 // special state, meaning you are specifically running
21404 // for the current top app. If the process is already
21405 // running in the background for some other reason, it
21406 // is more important to continue considering it to be
21407 // in the background state.
21409 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21410 mayBeTopType = adjType = "provider-top";
21411 mayBeTopSource = client;
21412 mayBeTopTarget = cpr.name;
21414 // Special handling for above-top states (persistent
21415 // processes). These should not bring the current process
21416 // into the top state, since they are not on top. Instead
21417 // give them the best state after that.
21419 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21420 if (adjType == null) {
21421 adjType = "provider";
21425 if (procState > clientProcState) {
21426 procState = clientProcState;
21428 if (client.curSchedGroup > schedGroup) {
21429 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21431 if (adjType != null) {
21432 app.adjType = adjType;
21433 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21434 .REASON_PROVIDER_IN_USE;
21435 app.adjSource = client;
21436 app.adjSourceProcState = clientProcState;
21437 app.adjTarget = cpr.name;
21438 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21439 + ": " + app + ", due to " + client
21440 + " adj=" + adj + " procState=" + procState);
21443 // If the provider has external (non-framework) process
21444 // dependencies, ensure that its adjustment is at least
21445 // FOREGROUND_APP_ADJ.
21446 if (cpr.hasExternalProcessHandles()) {
21447 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21448 adj = ProcessList.FOREGROUND_APP_ADJ;
21449 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21450 app.cached = false;
21451 app.adjType = "ext-provider";
21452 app.adjTarget = cpr.name;
21453 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21455 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21456 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21461 if (app.lastProviderTime > 0 &&
21462 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21463 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21464 adj = ProcessList.PREVIOUS_APP_ADJ;
21465 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21466 app.cached = false;
21467 app.adjType = "recent-provider";
21468 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21470 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21471 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21472 app.adjType = "recent-provider";
21473 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21477 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21478 // A client of one of our services or providers is in the top state. We
21479 // *may* want to be in the top state, but not if we are already running in
21480 // the background for some other reason. For the decision here, we are going
21481 // to pick out a few specific states that we want to remain in when a client
21482 // is top (states that tend to be longer-term) and otherwise allow it to go
21483 // to the top state.
21484 switch (procState) {
21485 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21486 // Something else is keeping it at this level, just leave it.
21488 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21489 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21490 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21491 case ActivityManager.PROCESS_STATE_SERVICE:
21492 // These all are longer-term states, so pull them up to the top
21493 // of the background states, but not all the way to the top state.
21494 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21495 app.adjType = mayBeTopType;
21496 app.adjSource = mayBeTopSource;
21497 app.adjTarget = mayBeTopTarget;
21498 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21499 + ": " + app + ", due to " + mayBeTopSource
21500 + " adj=" + adj + " procState=" + procState);
21503 // Otherwise, top is a better choice, so take it.
21504 procState = ActivityManager.PROCESS_STATE_TOP;
21505 app.adjType = mayBeTopType;
21506 app.adjSource = mayBeTopSource;
21507 app.adjTarget = mayBeTopTarget;
21508 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21509 + ": " + app + ", due to " + mayBeTopSource
21510 + " adj=" + adj + " procState=" + procState);
21515 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21516 if (app.hasClientActivities) {
21517 // This is a cached process, but with client activities. Mark it so.
21518 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21519 app.adjType = "cch-client-act";
21520 } else if (app.treatLikeActivity) {
21521 // This is a cached process, but somebody wants us to treat it like it has
21522 // an activity, okay!
21523 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21524 app.adjType = "cch-as-act";
21528 if (adj == ProcessList.SERVICE_ADJ) {
21530 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21531 mNewNumServiceProcs++;
21532 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21533 if (!app.serviceb) {
21534 // This service isn't far enough down on the LRU list to
21535 // normally be a B service, but if we are low on RAM and it
21536 // is large we want to force it down since we would prefer to
21537 // keep launcher over it.
21538 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21539 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21540 app.serviceHighRam = true;
21541 app.serviceb = true;
21542 //Slog.i(TAG, "ADJ " + app + " high ram!");
21544 mNewNumAServiceProcs++;
21545 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21548 app.serviceHighRam = false;
21551 if (app.serviceb) {
21552 adj = ProcessList.SERVICE_B_ADJ;
21556 app.curRawAdj = adj;
21558 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21559 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21560 if (adj > app.maxAdj) {
21562 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21563 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21567 // Do final modification to adj. Everything we do between here and applying
21568 // the final setAdj must be done in this function, because we will also use
21569 // it when computing the final cached adj later. Note that we don't need to
21570 // worry about this for max adj above, since max adj will always be used to
21571 // keep it out of the cached vaues.
21572 app.curAdj = app.modifyRawOomAdj(adj);
21573 app.curSchedGroup = schedGroup;
21574 app.curProcState = procState;
21575 app.foregroundActivities = foregroundActivities;
21577 return app.curRawAdj;
21581 * Record new PSS sample for a process.
21583 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21585 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21587 proc.lastPssTime = now;
21588 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21589 if (DEBUG_PSS) Slog.d(TAG_PSS,
21590 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21591 + " state=" + ProcessList.makeProcStateString(procState));
21592 if (proc.initialIdlePss == 0) {
21593 proc.initialIdlePss = pss;
21595 proc.lastPss = pss;
21596 proc.lastSwapPss = swapPss;
21597 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21598 proc.lastCachedPss = pss;
21599 proc.lastCachedSwapPss = swapPss;
21602 final SparseArray<Pair<Long, String>> watchUids
21603 = mMemWatchProcesses.getMap().get(proc.processName);
21605 if (watchUids != null) {
21606 Pair<Long, String> val = watchUids.get(proc.uid);
21608 val = watchUids.get(0);
21614 if (check != null) {
21615 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21616 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21617 if (!isDebuggable) {
21618 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21619 isDebuggable = true;
21622 if (isDebuggable) {
21623 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21624 final ProcessRecord myProc = proc;
21625 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21626 mMemWatchDumpProcName = proc.processName;
21627 mMemWatchDumpFile = heapdumpFile.toString();
21628 mMemWatchDumpPid = proc.pid;
21629 mMemWatchDumpUid = proc.uid;
21630 BackgroundThread.getHandler().post(new Runnable() {
21632 public void run() {
21633 revokeUriPermission(ActivityThread.currentActivityThread()
21634 .getApplicationThread(),
21635 null, DumpHeapActivity.JAVA_URI,
21636 Intent.FLAG_GRANT_READ_URI_PERMISSION
21637 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21638 UserHandle.myUserId());
21639 ParcelFileDescriptor fd = null;
21641 heapdumpFile.delete();
21642 fd = ParcelFileDescriptor.open(heapdumpFile,
21643 ParcelFileDescriptor.MODE_CREATE |
21644 ParcelFileDescriptor.MODE_TRUNCATE |
21645 ParcelFileDescriptor.MODE_WRITE_ONLY |
21646 ParcelFileDescriptor.MODE_APPEND);
21647 IApplicationThread thread = myProc.thread;
21648 if (thread != null) {
21650 if (DEBUG_PSS) Slog.d(TAG_PSS,
21651 "Requesting dump heap from "
21652 + myProc + " to " + heapdumpFile);
21653 thread.dumpHeap(true, heapdumpFile.toString(), fd);
21654 } catch (RemoteException e) {
21657 } catch (FileNotFoundException e) {
21658 e.printStackTrace();
21663 } catch (IOException e) {
21670 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21671 + ", but debugging not enabled");
21678 * Schedule PSS collection of a process.
21680 void requestPssLocked(ProcessRecord proc, int procState) {
21681 if (mPendingPssProcesses.contains(proc)) {
21684 if (mPendingPssProcesses.size() == 0) {
21685 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21687 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21688 proc.pssProcState = procState;
21689 mPendingPssProcesses.add(proc);
21693 * Schedule PSS collection of all processes.
21695 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21697 if (now < (mLastFullPssTime +
21698 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21699 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21703 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21704 mLastFullPssTime = now;
21705 mFullPssPending = true;
21706 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21707 mPendingPssProcesses.clear();
21708 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21709 ProcessRecord app = mLruProcesses.get(i);
21710 if (app.thread == null
21711 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21714 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21715 app.pssProcState = app.setProcState;
21716 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21717 mTestPssMode, isSleepingLocked(), now);
21718 mPendingPssProcesses.add(app);
21721 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21724 public void setTestPssMode(boolean enabled) {
21725 synchronized (this) {
21726 mTestPssMode = enabled;
21728 // Whenever we enable the mode, we want to take a snapshot all of current
21729 // process mem use.
21730 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21736 * Ask a given process to GC right now.
21738 final void performAppGcLocked(ProcessRecord app) {
21740 app.lastRequestedGc = SystemClock.uptimeMillis();
21741 if (app.thread != null) {
21742 if (app.reportLowMemory) {
21743 app.reportLowMemory = false;
21744 app.thread.scheduleLowMemory();
21746 app.thread.processInBackground();
21749 } catch (Exception e) {
21755 * Returns true if things are idle enough to perform GCs.
21757 private final boolean canGcNowLocked() {
21758 boolean processingBroadcasts = false;
21759 for (BroadcastQueue q : mBroadcastQueues) {
21760 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21761 processingBroadcasts = true;
21764 return !processingBroadcasts
21765 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21769 * Perform GCs on all processes that are waiting for it, but only
21770 * if things are idle.
21772 final void performAppGcsLocked() {
21773 final int N = mProcessesToGc.size();
21777 if (canGcNowLocked()) {
21778 while (mProcessesToGc.size() > 0) {
21779 ProcessRecord proc = mProcessesToGc.remove(0);
21780 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21781 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21782 <= SystemClock.uptimeMillis()) {
21783 // To avoid spamming the system, we will GC processes one
21784 // at a time, waiting a few seconds between each.
21785 performAppGcLocked(proc);
21786 scheduleAppGcsLocked();
21789 // It hasn't been long enough since we last GCed this
21790 // process... put it in the list to wait for its time.
21791 addProcessToGcListLocked(proc);
21797 scheduleAppGcsLocked();
21802 * If all looks good, perform GCs on all processes waiting for them.
21804 final void performAppGcsIfAppropriateLocked() {
21805 if (canGcNowLocked()) {
21806 performAppGcsLocked();
21809 // Still not idle, wait some more.
21810 scheduleAppGcsLocked();
21814 * Schedule the execution of all pending app GCs.
21816 final void scheduleAppGcsLocked() {
21817 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21819 if (mProcessesToGc.size() > 0) {
21820 // Schedule a GC for the time to the next process.
21821 ProcessRecord proc = mProcessesToGc.get(0);
21822 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21824 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21825 long now = SystemClock.uptimeMillis();
21826 if (when < (now+mConstants.GC_TIMEOUT)) {
21827 when = now + mConstants.GC_TIMEOUT;
21829 mHandler.sendMessageAtTime(msg, when);
21834 * Add a process to the array of processes waiting to be GCed. Keeps the
21835 * list in sorted order by the last GC time. The process can't already be
21838 final void addProcessToGcListLocked(ProcessRecord proc) {
21839 boolean added = false;
21840 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21841 if (mProcessesToGc.get(i).lastRequestedGc <
21842 proc.lastRequestedGc) {
21844 mProcessesToGc.add(i+1, proc);
21849 mProcessesToGc.add(0, proc);
21854 * Set up to ask a process to GC itself. This will either do it
21855 * immediately, or put it on the list of processes to gc the next
21856 * time things are idle.
21858 final void scheduleAppGcLocked(ProcessRecord app) {
21859 long now = SystemClock.uptimeMillis();
21860 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21863 if (!mProcessesToGc.contains(app)) {
21864 addProcessToGcListLocked(app);
21865 scheduleAppGcsLocked();
21869 final void checkExcessivePowerUsageLocked(boolean doKills) {
21870 updateCpuStatsNow();
21872 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21873 boolean doWakeKills = doKills;
21874 boolean doCpuKills = doKills;
21875 if (mLastPowerCheckRealtime == 0) {
21876 doWakeKills = false;
21878 if (mLastPowerCheckUptime == 0) {
21879 doCpuKills = false;
21881 if (stats.isScreenOn()) {
21882 doWakeKills = false;
21884 final long curRealtime = SystemClock.elapsedRealtime();
21885 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21886 final long curUptime = SystemClock.uptimeMillis();
21887 final long uptimeSince = curUptime - mLastPowerCheckUptime;
21888 mLastPowerCheckRealtime = curRealtime;
21889 mLastPowerCheckUptime = curUptime;
21890 if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21891 doWakeKills = false;
21893 if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21894 doCpuKills = false;
21896 int i = mLruProcesses.size();
21899 ProcessRecord app = mLruProcesses.get(i);
21900 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21902 synchronized (stats) {
21903 wtime = stats.getProcessWakeTime(app.info.uid,
21904 app.pid, curRealtime);
21906 long wtimeUsed = wtime - app.lastWakeTime;
21907 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21909 StringBuilder sb = new StringBuilder(128);
21910 sb.append("Wake for ");
21911 app.toShortString(sb);
21912 sb.append(": over ");
21913 TimeUtils.formatDuration(realtimeSince, sb);
21914 sb.append(" used ");
21915 TimeUtils.formatDuration(wtimeUsed, sb);
21917 sb.append((wtimeUsed*100)/realtimeSince);
21919 Slog.i(TAG_POWER, sb.toString());
21921 sb.append("CPU for ");
21922 app.toShortString(sb);
21923 sb.append(": over ");
21924 TimeUtils.formatDuration(uptimeSince, sb);
21925 sb.append(" used ");
21926 TimeUtils.formatDuration(cputimeUsed, sb);
21928 sb.append((cputimeUsed*100)/uptimeSince);
21930 Slog.i(TAG_POWER, sb.toString());
21932 // If a process has held a wake lock for more
21933 // than 50% of the time during this period,
21934 // that sounds bad. Kill!
21935 if (doWakeKills && realtimeSince > 0
21936 && ((wtimeUsed*100)/realtimeSince) >= 50) {
21937 synchronized (stats) {
21938 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21939 realtimeSince, wtimeUsed);
21941 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21942 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21943 } else if (doCpuKills && uptimeSince > 0
21944 && ((cputimeUsed*100)/uptimeSince) >= 25) {
21945 synchronized (stats) {
21946 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21947 uptimeSince, cputimeUsed);
21949 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21950 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21952 app.lastWakeTime = wtime;
21953 app.lastCpuTime = app.curCpuTime;
21959 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21961 boolean success = true;
21963 if (app.curRawAdj != app.setRawAdj) {
21964 app.setRawAdj = app.curRawAdj;
21969 if (app.curAdj != app.setAdj) {
21970 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21971 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21972 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21974 app.setAdj = app.curAdj;
21975 app.verifiedAdj = ProcessList.INVALID_ADJ;
21978 if (app.setSchedGroup != app.curSchedGroup) {
21979 int oldSchedGroup = app.setSchedGroup;
21980 app.setSchedGroup = app.curSchedGroup;
21981 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21982 "Setting sched group of " + app.processName
21983 + " to " + app.curSchedGroup);
21984 if (app.waitingToKill != null && app.curReceivers.isEmpty()
21985 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21986 app.kill(app.waitingToKill, true);
21990 switch (app.curSchedGroup) {
21991 case ProcessList.SCHED_GROUP_BACKGROUND:
21992 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21994 case ProcessList.SCHED_GROUP_TOP_APP:
21995 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21996 processGroup = THREAD_GROUP_TOP_APP;
21999 processGroup = THREAD_GROUP_DEFAULT;
22002 long oldId = Binder.clearCallingIdentity();
22004 setProcessGroup(app.pid, processGroup);
22005 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22006 // do nothing if we already switched to RT
22007 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22008 mVrController.onTopProcChangedLocked(app);
22009 if (mUseFifoUiScheduling) {
22010 // Switch UI pipeline for app to SCHED_FIFO
22011 app.savedPriority = Process.getThreadPriority(app.pid);
22012 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22013 if (app.renderThreadTid != 0) {
22014 scheduleAsFifoPriority(app.renderThreadTid,
22015 /* suppressLogs */true);
22016 if (DEBUG_OOM_ADJ) {
22017 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22018 app.renderThreadTid + ") to FIFO");
22021 if (DEBUG_OOM_ADJ) {
22022 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22026 // Boost priority for top app UI and render threads
22027 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22028 if (app.renderThreadTid != 0) {
22030 setThreadPriority(app.renderThreadTid,
22031 TOP_APP_PRIORITY_BOOST);
22032 } catch (IllegalArgumentException e) {
22033 // thread died, ignore
22038 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22039 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22040 mVrController.onTopProcChangedLocked(app);
22041 if (mUseFifoUiScheduling) {
22042 // Reset UI pipeline to SCHED_OTHER
22043 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22044 setThreadPriority(app.pid, app.savedPriority);
22045 if (app.renderThreadTid != 0) {
22046 setThreadScheduler(app.renderThreadTid,
22048 setThreadPriority(app.renderThreadTid, -4);
22051 // Reset priority for top app UI and render threads
22052 setThreadPriority(app.pid, 0);
22053 if (app.renderThreadTid != 0) {
22054 setThreadPriority(app.renderThreadTid, 0);
22058 } catch (Exception e) {
22060 Slog.w(TAG, "Failed setting process group of " + app.pid
22061 + " to " + app.curSchedGroup);
22062 Slog.w(TAG, "at location", e);
22065 Binder.restoreCallingIdentity(oldId);
22069 if (app.repForegroundActivities != app.foregroundActivities) {
22070 app.repForegroundActivities = app.foregroundActivities;
22071 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22073 if (app.repProcState != app.curProcState) {
22074 app.repProcState = app.curProcState;
22075 if (app.thread != null) {
22078 //RuntimeException h = new RuntimeException("here");
22079 Slog.i(TAG, "Sending new process state " + app.repProcState
22080 + " to " + app /*, h*/);
22082 app.thread.setProcessState(app.repProcState);
22083 } catch (RemoteException e) {
22087 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22088 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22089 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22090 // Experimental code to more aggressively collect pss while
22091 // running test... the problem is that this tends to collect
22092 // the data right when a process is transitioning between process
22093 // states, which well tend to give noisy data.
22094 long start = SystemClock.uptimeMillis();
22095 long pss = Debug.getPss(app.pid, mTmpLong, null);
22096 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22097 mPendingPssProcesses.remove(app);
22098 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22099 + " to " + app.curProcState + ": "
22100 + (SystemClock.uptimeMillis()-start) + "ms");
22102 app.lastStateTime = now;
22103 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22104 mTestPssMode, isSleepingLocked(), now);
22105 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22106 + ProcessList.makeProcStateString(app.setProcState) + " to "
22107 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22108 + (app.nextPssTime-now) + ": " + app);
22110 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22111 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22113 requestPssLocked(app, app.setProcState);
22114 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22115 mTestPssMode, isSleepingLocked(), now);
22116 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22117 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22119 if (app.setProcState != app.curProcState) {
22120 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22121 "Proc state change of " + app.processName
22122 + " to " + app.curProcState);
22123 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22124 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22125 if (setImportant && !curImportant) {
22126 // This app is no longer something we consider important enough to allow to
22127 // use arbitrary amounts of battery power. Note
22128 // its current wake lock time to later know to kill it if
22129 // it is not behaving well.
22130 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22131 synchronized (stats) {
22132 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
22133 app.pid, nowElapsed);
22135 app.lastCpuTime = app.curCpuTime;
22138 // Inform UsageStats of important process state change
22139 // Must be called before updating setProcState
22140 maybeUpdateUsageStatsLocked(app, nowElapsed);
22142 app.setProcState = app.curProcState;
22143 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22144 app.notCachedSinceIdle = false;
22147 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22149 app.procStateChanged = true;
22151 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22152 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22153 // For apps that sit around for a long time in the interactive state, we need
22154 // to report this at least once a day so they don't go idle.
22155 maybeUpdateUsageStatsLocked(app, nowElapsed);
22158 if (changes != 0) {
22159 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22160 "Changes in " + app + ": " + changes);
22161 int i = mPendingProcessChanges.size()-1;
22162 ProcessChangeItem item = null;
22164 item = mPendingProcessChanges.get(i);
22165 if (item.pid == app.pid) {
22166 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22167 "Re-using existing item: " + item);
22173 // No existing item in pending changes; need a new one.
22174 final int NA = mAvailProcessChanges.size();
22176 item = mAvailProcessChanges.remove(NA-1);
22177 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22178 "Retrieving available item: " + item);
22180 item = new ProcessChangeItem();
22181 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22182 "Allocating new item: " + item);
22185 item.pid = app.pid;
22186 item.uid = app.info.uid;
22187 if (mPendingProcessChanges.size() == 0) {
22188 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22189 "*** Enqueueing dispatch processes changed!");
22190 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22192 mPendingProcessChanges.add(item);
22194 item.changes |= changes;
22195 item.foregroundActivities = app.repForegroundActivities;
22196 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22197 "Item " + Integer.toHexString(System.identityHashCode(item))
22198 + " " + app.toShortString() + ": changes=" + item.changes
22199 + " foreground=" + item.foregroundActivities
22200 + " type=" + app.adjType + " source=" + app.adjSource
22201 + " target=" + app.adjTarget);
22207 private boolean isEphemeralLocked(int uid) {
22208 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22209 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22212 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22217 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22218 final UidRecord.ChangeItem pendingChange;
22219 if (uidRec == null || uidRec.pendingChange == null) {
22220 if (mPendingUidChanges.size() == 0) {
22221 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22222 "*** Enqueueing dispatch uid changed!");
22223 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22225 final int NA = mAvailUidChanges.size();
22227 pendingChange = mAvailUidChanges.remove(NA-1);
22228 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22229 "Retrieving available item: " + pendingChange);
22231 pendingChange = new UidRecord.ChangeItem();
22232 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22233 "Allocating new item: " + pendingChange);
22235 if (uidRec != null) {
22236 uidRec.pendingChange = pendingChange;
22237 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
22238 // If this uid is going away, and we haven't yet reported it is gone,
22240 change = UidRecord.CHANGE_GONE_IDLE;
22242 } else if (uid < 0) {
22243 throw new IllegalArgumentException("No UidRecord or uid");
22245 pendingChange.uidRecord = uidRec;
22246 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22247 mPendingUidChanges.add(pendingChange);
22249 pendingChange = uidRec.pendingChange;
22250 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
22251 change = UidRecord.CHANGE_GONE_IDLE;
22254 pendingChange.change = change;
22255 pendingChange.processState = uidRec != null
22256 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22257 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22258 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22259 if (uidRec != null) {
22260 uidRec.updateLastDispatchedProcStateSeq(change);
22263 // Directly update the power manager, since we sit on top of it and it is critical
22264 // it be kept in sync (so wake locks will be held as soon as appropriate).
22265 if (mLocalPowerManager != null) {
22267 case UidRecord.CHANGE_GONE:
22268 case UidRecord.CHANGE_GONE_IDLE:
22269 mLocalPowerManager.uidGone(pendingChange.uid);
22271 case UidRecord.CHANGE_IDLE:
22272 mLocalPowerManager.uidIdle(pendingChange.uid);
22274 case UidRecord.CHANGE_ACTIVE:
22275 mLocalPowerManager.uidActive(pendingChange.uid);
22278 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22279 pendingChange.processState);
22285 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22286 String authority) {
22287 if (app == null) return;
22288 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22289 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22290 if (userState == null) return;
22291 final long now = SystemClock.elapsedRealtime();
22292 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22293 if (lastReported == null || lastReported < now - 60 * 1000L) {
22294 if (mSystemReady) {
22295 // Cannot touch the user stats if not system ready
22296 mUsageStatsService.reportContentProviderUsage(
22297 authority, providerPkgName, app.userId);
22299 userState.mProviderLastReportedFg.put(authority, now);
22304 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22305 if (DEBUG_USAGE_STATS) {
22306 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22307 + "] state changes: old = " + app.setProcState + ", new = "
22308 + app.curProcState);
22310 if (mUsageStatsService == null) {
22313 boolean isInteraction;
22314 // To avoid some abuse patterns, we are going to be careful about what we consider
22315 // to be an app interaction. Being the top activity doesn't count while the display
22316 // is sleeping, nor do short foreground services.
22317 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22318 isInteraction = true;
22319 app.fgInteractionTime = 0;
22320 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22321 if (app.fgInteractionTime == 0) {
22322 app.fgInteractionTime = nowElapsed;
22323 isInteraction = false;
22325 isInteraction = nowElapsed > app.fgInteractionTime
22326 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22329 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22330 app.fgInteractionTime = 0;
22332 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22333 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22334 app.interactionEventTime = nowElapsed;
22335 String[] packages = app.getPackageList();
22336 if (packages != null) {
22337 for (int i = 0; i < packages.length; i++) {
22338 mUsageStatsService.reportEvent(packages[i], app.userId,
22339 UsageEvents.Event.SYSTEM_INTERACTION);
22343 app.reportedInteraction = isInteraction;
22344 if (!isInteraction) {
22345 app.interactionEventTime = 0;
22349 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22350 if (proc.thread != null) {
22351 if (proc.baseProcessTracker != null) {
22352 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22357 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22358 ProcessRecord TOP_APP, boolean doingAll, long now) {
22359 if (app.thread == null) {
22363 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22365 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22368 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22370 if (isForeground != proc.foregroundServices) {
22371 proc.foregroundServices = isForeground;
22372 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22374 if (isForeground) {
22375 if (curProcs == null) {
22376 curProcs = new ArrayList<ProcessRecord>();
22377 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22379 if (!curProcs.contains(proc)) {
22380 curProcs.add(proc);
22381 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22382 proc.info.packageName, proc.info.uid);
22385 if (curProcs != null) {
22386 if (curProcs.remove(proc)) {
22387 mBatteryStatsService.noteEvent(
22388 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22389 proc.info.packageName, proc.info.uid);
22390 if (curProcs.size() <= 0) {
22391 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22397 updateOomAdjLocked();
22402 private final ActivityRecord resumedAppLocked() {
22403 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22407 pkg = act.packageName;
22408 uid = act.info.applicationInfo.uid;
22413 // Has the UID or resumed package name changed?
22414 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22415 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22416 if (mCurResumedPackage != null) {
22417 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22418 mCurResumedPackage, mCurResumedUid);
22420 mCurResumedPackage = pkg;
22421 mCurResumedUid = uid;
22422 if (mCurResumedPackage != null) {
22423 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22424 mCurResumedPackage, mCurResumedUid);
22431 * Update OomAdj for a specific process.
22432 * @param app The process to update
22433 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22434 * if necessary, or skip.
22435 * @return whether updateOomAdjLocked(app) was successful.
22437 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22438 final ActivityRecord TOP_ACT = resumedAppLocked();
22439 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22440 final boolean wasCached = app.cached;
22444 // This is the desired cached adjusment we want to tell it to use.
22445 // If our app is currently cached, we know it, and that is it. Otherwise,
22446 // we don't know it yet, and it needs to now be cached we will then
22447 // need to do a complete oom adj.
22448 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22449 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22450 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22451 SystemClock.uptimeMillis());
22453 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22454 // Changed to/from cached state, so apps after it in the LRU
22455 // list may also be changed.
22456 updateOomAdjLocked();
22461 final void updateOomAdjLocked() {
22462 final ActivityRecord TOP_ACT = resumedAppLocked();
22463 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22464 final long now = SystemClock.uptimeMillis();
22465 final long nowElapsed = SystemClock.elapsedRealtime();
22466 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22467 final int N = mLruProcesses.size();
22470 RuntimeException e = new RuntimeException();
22471 e.fillInStackTrace();
22472 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22475 // Reset state in all uid records.
22476 for (int i=mActiveUids.size()-1; i>=0; i--) {
22477 final UidRecord uidRec = mActiveUids.valueAt(i);
22478 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22479 "Starting update of " + uidRec);
22483 mStackSupervisor.rankTaskLayersIfNeeded();
22486 mNewNumServiceProcs = 0;
22487 mNewNumAServiceProcs = 0;
22489 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22490 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22492 // Let's determine how many processes we have running vs.
22493 // how many slots we have for background processes; we may want
22494 // to put multiple processes in a slot of there are enough of
22496 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22497 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22498 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22499 if (numEmptyProcs > cachedProcessLimit) {
22500 // If there are more empty processes than our limit on cached
22501 // processes, then use the cached process limit for the factor.
22502 // This ensures that the really old empty processes get pushed
22503 // down to the bottom, so if we are running low on memory we will
22504 // have a better chance at keeping around more cached processes
22505 // instead of a gazillion empty processes.
22506 numEmptyProcs = cachedProcessLimit;
22508 int emptyFactor = numEmptyProcs/numSlots;
22509 if (emptyFactor < 1) emptyFactor = 1;
22510 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22511 if (cachedFactor < 1) cachedFactor = 1;
22512 int stepCached = 0;
22516 int numTrimming = 0;
22518 mNumNonCachedProcs = 0;
22519 mNumCachedHiddenProcs = 0;
22521 // First update the OOM adjustment for each of the
22522 // application processes based on their current state.
22523 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22524 int nextCachedAdj = curCachedAdj+1;
22525 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22526 int nextEmptyAdj = curEmptyAdj+2;
22527 for (int i=N-1; i>=0; i--) {
22528 ProcessRecord app = mLruProcesses.get(i);
22529 if (!app.killedByAm && app.thread != null) {
22530 app.procStateChanged = false;
22531 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22533 // If we haven't yet assigned the final cached adj
22534 // to the process, do that now.
22535 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22536 switch (app.curProcState) {
22537 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22538 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22539 // This process is a cached process holding activities...
22540 // assign it the next cached value for that type, and then
22541 // step that cached level.
22542 app.curRawAdj = curCachedAdj;
22543 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22544 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22545 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22547 if (curCachedAdj != nextCachedAdj) {
22549 if (stepCached >= cachedFactor) {
22551 curCachedAdj = nextCachedAdj;
22552 nextCachedAdj += 2;
22553 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22554 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22560 // For everything else, assign next empty cached process
22561 // level and bump that up. Note that this means that
22562 // long-running services that have dropped down to the
22563 // cached level will be treated as empty (since their process
22564 // state is still as a service), which is what we want.
22565 app.curRawAdj = curEmptyAdj;
22566 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22567 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22568 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22570 if (curEmptyAdj != nextEmptyAdj) {
22572 if (stepEmpty >= emptyFactor) {
22574 curEmptyAdj = nextEmptyAdj;
22576 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22577 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22585 applyOomAdjLocked(app, true, now, nowElapsed);
22587 // Count the number of process types.
22588 switch (app.curProcState) {
22589 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22590 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22591 mNumCachedHiddenProcs++;
22593 if (numCached > cachedProcessLimit) {
22594 app.kill("cached #" + numCached, true);
22597 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22598 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22599 && app.lastActivityTime < oldTime) {
22600 app.kill("empty for "
22601 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22602 / 1000) + "s", true);
22605 if (numEmpty > emptyProcessLimit) {
22606 app.kill("empty #" + numEmpty, true);
22611 mNumNonCachedProcs++;
22615 if (app.isolated && app.services.size() <= 0) {
22616 // If this is an isolated process, and there are no
22617 // services running in it, then the process is no longer
22618 // needed. We agressively kill these because we can by
22619 // definition not re-use the same process again, and it is
22620 // good to avoid having whatever code was running in them
22621 // left sitting around after no longer needed.
22622 app.kill("isolated not needed", true);
22624 // Keeping this process, update its uid.
22625 final UidRecord uidRec = app.uidRecord;
22626 if (uidRec != null) {
22627 uidRec.ephemeral = app.info.isInstantApp();
22628 if (uidRec.curProcState > app.curProcState) {
22629 uidRec.curProcState = app.curProcState;
22631 if (app.foregroundServices) {
22632 uidRec.foregroundServices = true;
22637 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22638 && !app.killedByAm) {
22644 incrementProcStateSeqAndNotifyAppsLocked();
22646 mNumServiceProcs = mNewNumServiceProcs;
22648 // Now determine the memory trimming level of background processes.
22649 // Unfortunately we need to start at the back of the list to do this
22650 // properly. We only do this if the number of background apps we
22651 // are managing to keep around is less than half the maximum we desire;
22652 // if we are keeping a good number around, we'll let them use whatever
22653 // memory they want.
22654 final int numCachedAndEmpty = numCached + numEmpty;
22656 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22657 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22658 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22659 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22660 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22661 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22663 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22666 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22668 // We always allow the memory level to go up (better). We only allow it to go
22669 // down if we are in a state where that is allowed, *and* the total number of processes
22670 // has gone down since last time.
22671 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22672 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22673 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22674 if (memFactor > mLastMemoryLevel) {
22675 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22676 memFactor = mLastMemoryLevel;
22677 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22680 if (memFactor != mLastMemoryLevel) {
22681 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22683 mLastMemoryLevel = memFactor;
22684 mLastNumProcesses = mLruProcesses.size();
22685 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22686 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22687 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22688 if (mLowRamStartTime == 0) {
22689 mLowRamStartTime = now;
22693 switch (memFactor) {
22694 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22695 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22697 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22698 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22701 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22704 int factor = numTrimming/3;
22706 if (mHomeProcess != null) minFactor++;
22707 if (mPreviousProcess != null) minFactor++;
22708 if (factor < minFactor) factor = minFactor;
22709 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22710 for (int i=N-1; i>=0; i--) {
22711 ProcessRecord app = mLruProcesses.get(i);
22712 if (allChanged || app.procStateChanged) {
22713 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22714 app.procStateChanged = false;
22716 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22717 && !app.killedByAm) {
22718 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22720 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22721 "Trimming memory of " + app.processName + " to " + curLevel);
22722 app.thread.scheduleTrimMemory(curLevel);
22723 } catch (RemoteException e) {
22726 // For now we won't do this; our memory trimming seems
22727 // to be good enough at this point that destroying
22728 // activities causes more harm than good.
22729 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22730 && app != mHomeProcess && app != mPreviousProcess) {
22731 // Need to do this on its own message because the stack may not
22732 // be in a consistent state at this point.
22733 // For these apps we will also finish their activities
22734 // to help them free memory.
22735 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22739 app.trimMemoryLevel = curLevel;
22741 if (step >= factor) {
22743 switch (curLevel) {
22744 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22745 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22747 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22748 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22752 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22753 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22754 && app.thread != null) {
22756 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22757 "Trimming memory of heavy-weight " + app.processName
22758 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22759 app.thread.scheduleTrimMemory(
22760 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22761 } catch (RemoteException e) {
22764 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22766 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22767 || app.systemNoUi) && app.pendingUiClean) {
22768 // If this application is now in the background and it
22769 // had done UI, then give it the special trim level to
22770 // have it free UI resources.
22771 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22772 if (app.trimMemoryLevel < level && app.thread != null) {
22774 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22775 "Trimming memory of bg-ui " + app.processName
22777 app.thread.scheduleTrimMemory(level);
22778 } catch (RemoteException e) {
22781 app.pendingUiClean = false;
22783 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22785 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22786 "Trimming memory of fg " + app.processName
22787 + " to " + fgTrimLevel);
22788 app.thread.scheduleTrimMemory(fgTrimLevel);
22789 } catch (RemoteException e) {
22792 app.trimMemoryLevel = fgTrimLevel;
22796 if (mLowRamStartTime != 0) {
22797 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22798 mLowRamStartTime = 0;
22800 for (int i=N-1; i>=0; i--) {
22801 ProcessRecord app = mLruProcesses.get(i);
22802 if (allChanged || app.procStateChanged) {
22803 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22804 app.procStateChanged = false;
22806 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22807 || app.systemNoUi) && app.pendingUiClean) {
22808 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22809 && app.thread != null) {
22811 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22812 "Trimming memory of ui hidden " + app.processName
22813 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22814 app.thread.scheduleTrimMemory(
22815 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22816 } catch (RemoteException e) {
22819 app.pendingUiClean = false;
22821 app.trimMemoryLevel = 0;
22825 if (mAlwaysFinishActivities) {
22826 // Need to do this on its own message because the stack may not
22827 // be in a consistent state at this point.
22828 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22832 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22835 // Update from any uid changes.
22836 if (mLocalPowerManager != null) {
22837 mLocalPowerManager.startUidChanges();
22839 for (int i=mActiveUids.size()-1; i>=0; i--) {
22840 final UidRecord uidRec = mActiveUids.valueAt(i);
22841 int uidChange = UidRecord.CHANGE_PROCSTATE;
22842 if (uidRec.setProcState != uidRec.curProcState
22843 || uidRec.setWhitelist != uidRec.curWhitelist) {
22844 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22845 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22846 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22847 + " to " + uidRec.curWhitelist);
22848 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22849 && !uidRec.curWhitelist) {
22850 // UID is now in the background (and not on the temp whitelist). Was it
22851 // previously in the foreground (or on the temp whitelist)?
22852 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22853 || uidRec.setWhitelist) {
22854 uidRec.lastBackgroundTime = nowElapsed;
22855 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22856 // Note: the background settle time is in elapsed realtime, while
22857 // the handler time base is uptime. All this means is that we may
22858 // stop background uids later than we had intended, but that only
22859 // happens because the device was sleeping so we are okay anyway.
22860 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22861 mConstants.BACKGROUND_SETTLE_TIME);
22866 uidChange = UidRecord.CHANGE_ACTIVE;
22867 EventLogTags.writeAmUidActive(uidRec.uid);
22868 uidRec.idle = false;
22870 uidRec.lastBackgroundTime = 0;
22872 uidRec.setProcState = uidRec.curProcState;
22873 uidRec.setWhitelist = uidRec.curWhitelist;
22874 enqueueUidChangeLocked(uidRec, -1, uidChange);
22875 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22876 if (uidRec.foregroundServices) {
22877 mServices.foregroundServiceProcStateChangedLocked(uidRec);
22881 if (mLocalPowerManager != null) {
22882 mLocalPowerManager.finishUidChanges();
22885 if (mProcessStats.shouldWriteNowLocked(now)) {
22886 mHandler.post(new Runnable() {
22887 @Override public void run() {
22888 synchronized (ActivityManagerService.this) {
22889 mProcessStats.writeStateAsyncLocked();
22895 if (DEBUG_OOM_ADJ) {
22896 final long duration = SystemClock.uptimeMillis() - now;
22898 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22899 new RuntimeException("here").fillInStackTrace());
22901 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22907 public void makePackageIdle(String packageName, int userId) {
22908 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22909 != PackageManager.PERMISSION_GRANTED) {
22910 String msg = "Permission Denial: makePackageIdle() from pid="
22911 + Binder.getCallingPid()
22912 + ", uid=" + Binder.getCallingUid()
22913 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22915 throw new SecurityException(msg);
22917 final int callingPid = Binder.getCallingPid();
22918 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22919 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22920 long callingId = Binder.clearCallingIdentity();
22921 synchronized(this) {
22923 IPackageManager pm = AppGlobals.getPackageManager();
22926 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22927 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22928 } catch (RemoteException e) {
22930 if (pkgUid == -1) {
22931 throw new IllegalArgumentException("Unknown package name " + packageName);
22934 if (mLocalPowerManager != null) {
22935 mLocalPowerManager.startUidChanges();
22937 final int appId = UserHandle.getAppId(pkgUid);
22938 final int N = mActiveUids.size();
22939 for (int i=N-1; i>=0; i--) {
22940 final UidRecord uidRec = mActiveUids.valueAt(i);
22941 final long bgTime = uidRec.lastBackgroundTime;
22942 if (bgTime > 0 && !uidRec.idle) {
22943 if (UserHandle.getAppId(uidRec.uid) == appId) {
22944 if (userId == UserHandle.USER_ALL ||
22945 userId == UserHandle.getUserId(uidRec.uid)) {
22946 EventLogTags.writeAmUidIdle(uidRec.uid);
22947 uidRec.idle = true;
22948 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22949 + " from package " + packageName + " user " + userId);
22950 doStopUidLocked(uidRec.uid, uidRec);
22956 if (mLocalPowerManager != null) {
22957 mLocalPowerManager.finishUidChanges();
22959 Binder.restoreCallingIdentity(callingId);
22964 final void idleUids() {
22965 synchronized (this) {
22966 final int N = mActiveUids.size();
22970 final long nowElapsed = SystemClock.elapsedRealtime();
22971 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22973 if (mLocalPowerManager != null) {
22974 mLocalPowerManager.startUidChanges();
22976 for (int i=N-1; i>=0; i--) {
22977 final UidRecord uidRec = mActiveUids.valueAt(i);
22978 final long bgTime = uidRec.lastBackgroundTime;
22979 if (bgTime > 0 && !uidRec.idle) {
22980 if (bgTime <= maxBgTime) {
22981 EventLogTags.writeAmUidIdle(uidRec.uid);
22982 uidRec.idle = true;
22983 doStopUidLocked(uidRec.uid, uidRec);
22985 if (nextTime == 0 || nextTime > bgTime) {
22991 if (mLocalPowerManager != null) {
22992 mLocalPowerManager.finishUidChanges();
22994 if (nextTime > 0) {
22995 mHandler.removeMessages(IDLE_UIDS_MSG);
22996 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22997 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23003 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23004 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23005 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23009 void incrementProcStateSeqAndNotifyAppsLocked() {
23010 if (mWaitForNetworkTimeoutMs <= 0) {
23013 // Used for identifying which uids need to block for network.
23014 ArrayList<Integer> blockingUids = null;
23015 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23016 final UidRecord uidRec = mActiveUids.valueAt(i);
23017 // If the network is not restricted for uid, then nothing to do here.
23018 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23021 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23024 // If process state is not changed, then there's nothing to do.
23025 if (uidRec.setProcState == uidRec.curProcState) {
23028 final int blockState = getBlockStateForUid(uidRec);
23029 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23030 // there's nothing the app needs to do in this scenario.
23031 if (blockState == NETWORK_STATE_NO_CHANGE) {
23034 synchronized (uidRec.networkStateLock) {
23035 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23036 if (blockState == NETWORK_STATE_BLOCK) {
23037 if (blockingUids == null) {
23038 blockingUids = new ArrayList<>();
23040 blockingUids.add(uidRec.uid);
23042 if (DEBUG_NETWORK) {
23043 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23044 + " threads for uid: " + uidRec);
23046 if (uidRec.waitingForNetwork) {
23047 uidRec.networkStateLock.notifyAll();
23053 // There are no uids that need to block, so nothing more to do.
23054 if (blockingUids == null) {
23058 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23059 final ProcessRecord app = mLruProcesses.get(i);
23060 if (!blockingUids.contains(app.uid)) {
23063 if (!app.killedByAm && app.thread != null) {
23064 final UidRecord uidRec = mActiveUids.get(app.uid);
23066 if (DEBUG_NETWORK) {
23067 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23070 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23071 } catch (RemoteException ignored) {
23078 * Checks if the uid is coming from background to foreground or vice versa and returns
23079 * appropriate block state based on this.
23081 * @return blockState based on whether the uid is coming from background to foreground or
23082 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23083 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23084 * {@link #NETWORK_STATE_NO_CHANGE}.
23087 int getBlockStateForUid(UidRecord uidRec) {
23088 // Denotes whether uid's process state is currently allowed network access.
23089 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23090 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23091 // Denotes whether uid's process state was previously allowed network access.
23092 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23093 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23095 // When the uid is coming to foreground, AMS should inform the app thread that it should
23096 // block for the network rules to get updated before launching an activity.
23097 if (!wasAllowed && isAllowed) {
23098 return NETWORK_STATE_BLOCK;
23100 // When the uid is going to background, AMS should inform the app thread that if an
23101 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23102 if (wasAllowed && !isAllowed) {
23103 return NETWORK_STATE_UNBLOCK;
23105 return NETWORK_STATE_NO_CHANGE;
23108 final void runInBackgroundDisabled(int uid) {
23109 synchronized (this) {
23110 UidRecord uidRec = mActiveUids.get(uid);
23111 if (uidRec != null) {
23112 // This uid is actually running... should it be considered background now?
23114 doStopUidLocked(uidRec.uid, uidRec);
23117 // This uid isn't actually running... still send a report about it being "stopped".
23118 doStopUidLocked(uid, null);
23123 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23124 mServices.stopInBackgroundLocked(uid);
23125 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23129 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23131 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23132 long duration, String tag) {
23133 if (DEBUG_WHITELISTS) {
23134 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23135 + targetUid + ", " + duration + ")");
23138 synchronized (mPidsSelfLocked) {
23139 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23141 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23145 if (!pr.whitelistManager) {
23146 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23147 != PackageManager.PERMISSION_GRANTED) {
23148 if (DEBUG_WHITELISTS) {
23149 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23150 + ": pid " + callerPid + " is not allowed");
23157 tempWhitelistUidLocked(targetUid, duration, tag);
23161 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23163 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23164 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23165 setUidTempWhitelistStateLocked(targetUid, true);
23166 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23169 void pushTempWhitelist() {
23171 final PendingTempWhitelist[] list;
23173 // First copy out the pending changes... we need to leave them in the map for now,
23174 // in case someone needs to check what is coming up while we don't have the lock held.
23175 synchronized(this) {
23176 N = mPendingTempWhitelist.size();
23177 list = new PendingTempWhitelist[N];
23178 for (int i = 0; i < N; i++) {
23179 list[i] = mPendingTempWhitelist.valueAt(i);
23183 // Now safely dispatch changes to device idle controller.
23184 for (int i = 0; i < N; i++) {
23185 PendingTempWhitelist ptw = list[i];
23186 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23187 ptw.duration, true, ptw.tag);
23190 // And now we can safely remove them from the map.
23191 synchronized(this) {
23192 for (int i = 0; i < N; i++) {
23193 PendingTempWhitelist ptw = list[i];
23194 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23195 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23196 mPendingTempWhitelist.removeAt(index);
23202 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23203 boolean changed = false;
23204 for (int i=mActiveUids.size()-1; i>=0; i--) {
23205 final UidRecord uidRec = mActiveUids.valueAt(i);
23206 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23207 uidRec.curWhitelist = onWhitelist;
23212 updateOomAdjLocked();
23216 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23217 boolean changed = false;
23218 final UidRecord uidRec = mActiveUids.get(uid);
23219 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23220 uidRec.curWhitelist = onWhitelist;
23221 updateOomAdjLocked();
23225 final void trimApplications() {
23226 synchronized (this) {
23229 // First remove any unused application processes whose package
23230 // has been removed.
23231 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23232 final ProcessRecord app = mRemovedProcesses.get(i);
23233 if (app.activities.size() == 0
23234 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23236 TAG, "Exiting empty application process "
23237 + app.toShortString() + " ("
23238 + (app.thread != null ? app.thread.asBinder() : null)
23240 if (app.pid > 0 && app.pid != MY_PID) {
23241 app.kill("empty", false);
23244 app.thread.scheduleExit();
23245 } catch (Exception e) {
23246 // Ignore exceptions.
23249 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23250 mRemovedProcesses.remove(i);
23252 if (app.persistent) {
23253 addAppLocked(app.info, null, false, null /* ABI override */);
23258 // Now update the oom adj for all processes.
23259 updateOomAdjLocked();
23263 /** This method sends the specified signal to each of the persistent apps */
23264 public void signalPersistentProcesses(int sig) throws RemoteException {
23265 if (sig != SIGNAL_USR1) {
23266 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23269 synchronized (this) {
23270 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23271 != PackageManager.PERMISSION_GRANTED) {
23272 throw new SecurityException("Requires permission "
23273 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23276 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23277 ProcessRecord r = mLruProcesses.get(i);
23278 if (r.thread != null && r.persistent) {
23279 sendSignal(r.pid, sig);
23285 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23286 if (proc == null || proc == mProfileProc) {
23287 proc = mProfileProc;
23288 profileType = mProfileType;
23289 clearProfilerLocked();
23291 if (proc == null) {
23295 proc.thread.profilerControl(false, null, profileType);
23296 } catch (RemoteException e) {
23297 throw new IllegalStateException("Process disappeared");
23301 private void clearProfilerLocked() {
23302 if (mProfileFd != null) {
23304 mProfileFd.close();
23305 } catch (IOException e) {
23308 mProfileApp = null;
23309 mProfileProc = null;
23310 mProfileFile = null;
23312 mAutoStopProfiler = false;
23313 mStreamingOutput = false;
23314 mSamplingInterval = 0;
23317 public boolean profileControl(String process, int userId, boolean start,
23318 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23321 synchronized (this) {
23322 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23323 // its own permission.
23324 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23325 != PackageManager.PERMISSION_GRANTED) {
23326 throw new SecurityException("Requires permission "
23327 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23330 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23331 throw new IllegalArgumentException("null profile info or fd");
23334 ProcessRecord proc = null;
23335 if (process != null) {
23336 proc = findProcessLocked(process, userId, "profileControl");
23339 if (start && (proc == null || proc.thread == null)) {
23340 throw new IllegalArgumentException("Unknown process: " + process);
23344 stopProfilerLocked(null, 0);
23345 setProfileApp(proc.info, proc.processName, profilerInfo);
23346 mProfileProc = proc;
23347 mProfileType = profileType;
23348 ParcelFileDescriptor fd = profilerInfo.profileFd;
23351 } catch (IOException e) {
23354 profilerInfo.profileFd = fd;
23355 proc.thread.profilerControl(start, profilerInfo, profileType);
23358 mProfileFd.close();
23359 } catch (IOException e) {
23363 stopProfilerLocked(proc, profileType);
23364 if (profilerInfo != null && profilerInfo.profileFd != null) {
23366 profilerInfo.profileFd.close();
23367 } catch (IOException e) {
23374 } catch (RemoteException e) {
23375 throw new IllegalStateException("Process disappeared");
23377 if (profilerInfo != null && profilerInfo.profileFd != null) {
23379 profilerInfo.profileFd.close();
23380 } catch (IOException e) {
23386 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23387 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23388 userId, true, ALLOW_FULL_ONLY, callName, null);
23389 ProcessRecord proc = null;
23391 int pid = Integer.parseInt(process);
23392 synchronized (mPidsSelfLocked) {
23393 proc = mPidsSelfLocked.get(pid);
23395 } catch (NumberFormatException e) {
23398 if (proc == null) {
23399 ArrayMap<String, SparseArray<ProcessRecord>> all
23400 = mProcessNames.getMap();
23401 SparseArray<ProcessRecord> procs = all.get(process);
23402 if (procs != null && procs.size() > 0) {
23403 proc = procs.valueAt(0);
23404 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23405 for (int i=1; i<procs.size(); i++) {
23406 ProcessRecord thisProc = procs.valueAt(i);
23407 if (thisProc.userId == userId) {
23419 public boolean dumpHeap(String process, int userId, boolean managed,
23420 String path, ParcelFileDescriptor fd) throws RemoteException {
23423 synchronized (this) {
23424 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23425 // its own permission (same as profileControl).
23426 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23427 != PackageManager.PERMISSION_GRANTED) {
23428 throw new SecurityException("Requires permission "
23429 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23433 throw new IllegalArgumentException("null fd");
23436 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23437 if (proc == null || proc.thread == null) {
23438 throw new IllegalArgumentException("Unknown process: " + process);
23441 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23442 if (!isDebuggable) {
23443 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23444 throw new SecurityException("Process not debuggable: " + proc);
23448 proc.thread.dumpHeap(managed, path, fd);
23452 } catch (RemoteException e) {
23453 throw new IllegalStateException("Process disappeared");
23458 } catch (IOException e) {
23465 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23466 String reportPackage) {
23467 if (processName != null) {
23468 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23469 "setDumpHeapDebugLimit()");
23471 synchronized (mPidsSelfLocked) {
23472 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23473 if (proc == null) {
23474 throw new SecurityException("No process found for calling pid "
23475 + Binder.getCallingPid());
23477 if (!Build.IS_DEBUGGABLE
23478 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23479 throw new SecurityException("Not running a debuggable build");
23481 processName = proc.processName;
23483 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23484 throw new SecurityException("Package " + reportPackage + " is not running in "
23489 synchronized (this) {
23490 if (maxMemSize > 0) {
23491 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23494 mMemWatchProcesses.remove(processName, uid);
23496 mMemWatchProcesses.getMap().remove(processName);
23503 public void dumpHeapFinished(String path) {
23504 synchronized (this) {
23505 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23506 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23507 + " does not match last pid " + mMemWatchDumpPid);
23510 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23511 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23512 + " does not match last path " + mMemWatchDumpFile);
23515 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23516 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23520 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23521 public void monitor() {
23522 synchronized (this) { }
23525 void onCoreSettingsChange(Bundle settings) {
23526 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23527 ProcessRecord processRecord = mLruProcesses.get(i);
23529 if (processRecord.thread != null) {
23530 processRecord.thread.setCoreSettings(settings);
23532 } catch (RemoteException re) {
23538 // Multi-user methods
23541 * Start user, if its not already running, but don't bring it to foreground.
23544 public boolean startUserInBackground(final int userId) {
23545 return mUserController.startUser(userId, /* foreground */ false);
23549 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23550 return mUserController.unlockUser(userId, token, secret, listener);
23554 public boolean switchUser(final int targetUserId) {
23555 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23557 UserInfo targetUserInfo;
23558 synchronized (this) {
23559 currentUserId = mUserController.getCurrentUserIdLocked();
23560 targetUserInfo = mUserController.getUserInfo(targetUserId);
23561 if (targetUserId == currentUserId) {
23562 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23565 if (targetUserInfo == null) {
23566 Slog.w(TAG, "No user info for user #" + targetUserId);
23569 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23570 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23571 + " when device is in demo mode");
23574 if (!targetUserInfo.supportsSwitchTo()) {
23575 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23578 if (targetUserInfo.isManagedProfile()) {
23579 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23582 mUserController.setTargetUserIdLocked(targetUserId);
23584 if (mUserController.mUserSwitchUiEnabled) {
23585 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23586 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23587 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23588 mUiHandler.sendMessage(mHandler.obtainMessage(
23589 START_USER_SWITCH_UI_MSG, userNames));
23591 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23592 mHandler.sendMessage(mHandler.obtainMessage(
23593 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23598 void scheduleStartProfilesLocked() {
23599 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23600 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23601 DateUtils.SECOND_IN_MILLIS);
23606 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23607 return mUserController.stopUser(userId, force, callback);
23611 public UserInfo getCurrentUser() {
23612 return mUserController.getCurrentUser();
23615 String getStartedUserState(int userId) {
23616 synchronized (this) {
23617 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23618 return UserState.stateToString(userState.state);
23623 public boolean isUserRunning(int userId, int flags) {
23624 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23625 && checkCallingPermission(INTERACT_ACROSS_USERS)
23626 != PackageManager.PERMISSION_GRANTED) {
23627 String msg = "Permission Denial: isUserRunning() from pid="
23628 + Binder.getCallingPid()
23629 + ", uid=" + Binder.getCallingUid()
23630 + " requires " + INTERACT_ACROSS_USERS;
23632 throw new SecurityException(msg);
23634 synchronized (this) {
23635 return mUserController.isUserRunningLocked(userId, flags);
23640 public int[] getRunningUserIds() {
23641 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23642 != PackageManager.PERMISSION_GRANTED) {
23643 String msg = "Permission Denial: isUserRunning() from pid="
23644 + Binder.getCallingPid()
23645 + ", uid=" + Binder.getCallingUid()
23646 + " requires " + INTERACT_ACROSS_USERS;
23648 throw new SecurityException(msg);
23650 synchronized (this) {
23651 return mUserController.getStartedUserArrayLocked();
23656 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23657 mUserController.registerUserSwitchObserver(observer, name);
23661 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23662 mUserController.unregisterUserSwitchObserver(observer);
23665 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23666 if (info == null) return null;
23667 ApplicationInfo newInfo = new ApplicationInfo(info);
23668 newInfo.initForUser(userId);
23672 public boolean isUserStopped(int userId) {
23673 synchronized (this) {
23674 return mUserController.getStartedUserStateLocked(userId) == null;
23678 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23680 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23684 ActivityInfo info = new ActivityInfo(aInfo);
23685 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23689 private boolean processSanityChecksLocked(ProcessRecord process) {
23690 if (process == null || process.thread == null) {
23694 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23695 if (!isDebuggable) {
23696 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23704 public boolean startBinderTracking() throws RemoteException {
23705 synchronized (this) {
23706 mBinderTransactionTrackingEnabled = true;
23707 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23708 // permission (same as profileControl).
23709 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23710 != PackageManager.PERMISSION_GRANTED) {
23711 throw new SecurityException("Requires permission "
23712 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23715 for (int i = 0; i < mLruProcesses.size(); i++) {
23716 ProcessRecord process = mLruProcesses.get(i);
23717 if (!processSanityChecksLocked(process)) {
23721 process.thread.startBinderTracking();
23722 } catch (RemoteException e) {
23723 Log.v(TAG, "Process disappared");
23730 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23732 synchronized (this) {
23733 mBinderTransactionTrackingEnabled = false;
23734 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23735 // permission (same as profileControl).
23736 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23737 != PackageManager.PERMISSION_GRANTED) {
23738 throw new SecurityException("Requires permission "
23739 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23743 throw new IllegalArgumentException("null fd");
23746 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23747 pw.println("Binder transaction traces for all processes.\n");
23748 for (ProcessRecord process : mLruProcesses) {
23749 if (!processSanityChecksLocked(process)) {
23753 pw.println("Traces for process: " + process.processName);
23756 TransferPipe tp = new TransferPipe();
23758 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23759 tp.go(fd.getFileDescriptor());
23763 } catch (IOException e) {
23764 pw.println("Failure while dumping IPC traces from " + process +
23765 ". Exception: " + e);
23767 } catch (RemoteException e) {
23768 pw.println("Got a RemoteException while dumping IPC traces from " +
23769 process + ". Exception: " + e);
23780 } catch (IOException e) {
23787 final class LocalService extends ActivityManagerInternal {
23789 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23790 int targetUserId) {
23791 synchronized (ActivityManagerService.this) {
23792 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23793 targetPkg, intent, null, targetUserId);
23798 public String checkContentProviderAccess(String authority, int userId) {
23799 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23803 public void onWakefulnessChanged(int wakefulness) {
23804 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23808 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23809 String processName, String abiOverride, int uid, Runnable crashHandler) {
23810 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23811 processName, abiOverride, uid, crashHandler);
23815 public SleepToken acquireSleepToken(String tag) {
23816 Preconditions.checkNotNull(tag);
23818 synchronized (ActivityManagerService.this) {
23819 SleepTokenImpl token = new SleepTokenImpl(tag);
23820 mSleepTokens.add(token);
23821 updateSleepIfNeededLocked();
23827 public ComponentName getHomeActivityForUser(int userId) {
23828 synchronized (ActivityManagerService.this) {
23829 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23830 return homeActivity == null ? null : homeActivity.realActivity;
23835 public void onUserRemoved(int userId) {
23836 synchronized (ActivityManagerService.this) {
23837 ActivityManagerService.this.onUserStoppedLocked(userId);
23842 public void onLocalVoiceInteractionStarted(IBinder activity,
23843 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23844 synchronized (ActivityManagerService.this) {
23845 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23846 voiceSession, voiceInteractor);
23851 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23852 synchronized (ActivityManagerService.this) {
23853 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23854 reasons, timestamp);
23859 public void notifyAppTransitionFinished() {
23860 synchronized (ActivityManagerService.this) {
23861 mStackSupervisor.notifyAppTransitionDone();
23866 public void notifyAppTransitionCancelled() {
23867 synchronized (ActivityManagerService.this) {
23868 mStackSupervisor.notifyAppTransitionDone();
23873 public List<IBinder> getTopVisibleActivities() {
23874 synchronized (ActivityManagerService.this) {
23875 return mStackSupervisor.getTopVisibleActivities();
23880 public void notifyDockedStackMinimizedChanged(boolean minimized) {
23881 synchronized (ActivityManagerService.this) {
23882 mStackSupervisor.setDockedStackMinimized(minimized);
23887 public void killForegroundAppsForUser(int userHandle) {
23888 synchronized (ActivityManagerService.this) {
23889 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23890 final int NP = mProcessNames.getMap().size();
23891 for (int ip = 0; ip < NP; ip++) {
23892 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23893 final int NA = apps.size();
23894 for (int ia = 0; ia < NA; ia++) {
23895 final ProcessRecord app = apps.valueAt(ia);
23896 if (app.persistent) {
23897 // We don't kill persistent processes.
23902 } else if (app.userId == userHandle && app.foregroundActivities) {
23903 app.removed = true;
23909 final int N = procs.size();
23910 for (int i = 0; i < N; i++) {
23911 removeProcessLocked(procs.get(i), false, true, "kill all fg");
23917 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23919 if (!(target instanceof PendingIntentRecord)) {
23920 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23923 synchronized (ActivityManagerService.this) {
23924 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23929 public void setDeviceIdleWhitelist(int[] appids) {
23930 synchronized (ActivityManagerService.this) {
23931 mDeviceIdleWhitelist = appids;
23936 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23937 synchronized (ActivityManagerService.this) {
23938 mDeviceIdleTempWhitelist = appids;
23939 setAppIdTempWhitelistStateLocked(changingAppId, adding);
23944 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23946 Preconditions.checkNotNull(values, "Configuration must not be null");
23947 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23948 synchronized (ActivityManagerService.this) {
23949 updateConfigurationLocked(values, null, false, true, userId,
23950 false /* deferResume */);
23955 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23957 Preconditions.checkNotNull(intents, "intents");
23958 final String[] resolvedTypes = new String[intents.length];
23959 for (int i = 0; i < intents.length; i++) {
23960 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23963 // UID of the package on user userId.
23964 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23965 // packageUid may not be initialized.
23966 int packageUid = 0;
23968 packageUid = AppGlobals.getPackageManager().getPackageUid(
23969 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23970 } catch (RemoteException e) {
23971 // Shouldn't happen.
23974 synchronized (ActivityManagerService.this) {
23975 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23976 /*resultTo*/ null, bOptions, userId);
23981 public int getUidProcessState(int uid) {
23982 return getUidState(uid);
23986 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23987 synchronized (ActivityManagerService.this) {
23989 // We might change the visibilities here, so prepare an empty app transition which
23990 // might be overridden later if we actually change visibilities.
23991 final boolean wasTransitionSet =
23992 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
23993 if (!wasTransitionSet) {
23994 mWindowManager.prepareAppTransition(TRANSIT_NONE,
23995 false /* alwaysKeepCurrent */);
23997 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23999 // If there was a transition set already we don't want to interfere with it as we
24000 // might be starting it too early.
24001 if (!wasTransitionSet) {
24002 mWindowManager.executeAppTransition();
24005 if (callback != null) {
24011 public boolean isSystemReady() {
24012 // no need to synchronize(this) just to read & return the value
24013 return mSystemReady;
24017 public void notifyKeyguardTrustedChanged() {
24018 synchronized (ActivityManagerService.this) {
24019 if (mKeyguardController.isKeyguardShowing()) {
24020 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24026 * Sets if the given pid has an overlay UI or not.
24028 * @param pid The pid we are setting overlay UI for.
24029 * @param hasOverlayUi True if the process has overlay UI.
24030 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24033 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24034 synchronized (ActivityManagerService.this) {
24035 final ProcessRecord pr;
24036 synchronized (mPidsSelfLocked) {
24037 pr = mPidsSelfLocked.get(pid);
24039 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24043 if (pr.hasOverlayUi == hasOverlayUi) {
24046 pr.hasOverlayUi = hasOverlayUi;
24047 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24048 updateOomAdjLocked(pr, true);
24053 * Called after the network policy rules are updated by
24054 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24055 * and {@param procStateSeq}.
24058 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24059 if (DEBUG_NETWORK) {
24060 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24061 + uid + " seq: " + procStateSeq);
24064 synchronized (ActivityManagerService.this) {
24065 record = mActiveUids.get(uid);
24066 if (record == null) {
24067 if (DEBUG_NETWORK) {
24068 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24069 + " procStateSeq: " + procStateSeq);
24074 synchronized (record.networkStateLock) {
24075 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24076 if (DEBUG_NETWORK) {
24077 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24078 + " been handled for uid: " + uid);
24082 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24083 if (record.curProcStateSeq > procStateSeq) {
24084 if (DEBUG_NETWORK) {
24085 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24086 + ", curProcstateSeq: " + record.curProcStateSeq
24087 + ", procStateSeq: " + procStateSeq);
24091 if (record.waitingForNetwork) {
24092 if (DEBUG_NETWORK) {
24093 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24094 + ", procStateSeq: " + procStateSeq);
24096 record.networkStateLock.notifyAll();
24102 * Called after virtual display Id is updated by
24103 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24104 * {@param vrVr2dDisplayId}.
24107 public void setVr2dDisplayId(int vr2dDisplayId) {
24109 Slog.d(TAG, "setVr2dDisplayId called for: " +
24112 synchronized (ActivityManagerService.this) {
24113 mVr2dDisplayId = vr2dDisplayId;
24118 public void saveANRState(String reason) {
24119 synchronized (ActivityManagerService.this) {
24120 final StringWriter sw = new StringWriter();
24121 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24122 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24123 if (reason != null) {
24124 pw.println(" Reason: " + reason);
24127 mActivityStarter.dump(pw, " ");
24129 pw.println("-------------------------------------------------------------------------------");
24130 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24131 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24136 mLastANRState = sw.toString();
24141 public void clearSavedANRState() {
24142 synchronized (ActivityManagerService.this) {
24143 mLastANRState = null;
24149 * Called by app main thread to wait for the network policy rules to get updated.
24151 * @param procStateSeq The sequence number indicating the process state change that the main
24152 * thread is interested in.
24155 public void waitForNetworkStateUpdate(long procStateSeq) {
24156 final int callingUid = Binder.getCallingUid();
24157 if (DEBUG_NETWORK) {
24158 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24161 synchronized (this) {
24162 record = mActiveUids.get(callingUid);
24163 if (record == null) {
24167 synchronized (record.networkStateLock) {
24168 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24169 if (DEBUG_NETWORK) {
24170 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24171 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24172 + " lastProcStateSeqDispatchedToObservers: "
24173 + record.lastDispatchedProcStateSeq);
24177 if (record.curProcStateSeq > procStateSeq) {
24178 if (DEBUG_NETWORK) {
24179 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24180 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24181 + ", procStateSeq: " + procStateSeq);
24185 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24186 if (DEBUG_NETWORK) {
24187 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24188 + procStateSeq + ", so no need to wait. Uid: "
24189 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24190 + record.lastNetworkUpdatedProcStateSeq);
24195 if (DEBUG_NETWORK) {
24196 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24197 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24199 final long startTime = SystemClock.uptimeMillis();
24200 record.waitingForNetwork = true;
24201 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24202 record.waitingForNetwork = false;
24203 final long totalTime = SystemClock.uptimeMillis() - startTime;
24204 if (totalTime >= mWaitForNetworkTimeoutMs) {
24205 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24206 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24207 + procStateSeq + " UidRec: " + record
24208 + " validateUidRec: " + mValidateUids.get(callingUid));
24210 } catch (InterruptedException e) {
24211 Thread.currentThread().interrupt();
24216 public void waitForBroadcastIdle(PrintWriter pw) {
24217 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24219 boolean idle = true;
24220 synchronized (this) {
24221 for (BroadcastQueue queue : mBroadcastQueues) {
24222 if (!queue.isIdle()) {
24223 final String msg = "Waiting for queue " + queue + " to become idle...";
24233 final String msg = "All broadcast queues are idle!";
24239 SystemClock.sleep(1000);
24245 * Return the user id of the last resumed activity.
24248 public @UserIdInt int getLastResumedActivityUserId() {
24249 enforceCallingPermission(
24250 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24251 synchronized (this) {
24252 if (mLastResumedActivity == null) {
24253 return mUserController.getCurrentUserIdLocked();
24255 return mLastResumedActivity.userId;
24259 private final class SleepTokenImpl extends SleepToken {
24260 private final String mTag;
24261 private final long mAcquireTime;
24263 public SleepTokenImpl(String tag) {
24265 mAcquireTime = SystemClock.uptimeMillis();
24269 public void release() {
24270 synchronized (ActivityManagerService.this) {
24271 if (mSleepTokens.remove(this)) {
24272 updateSleepIfNeededLocked();
24278 public String toString() {
24279 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
24284 * An implementation of IAppTask, that allows an app to manage its own tasks via
24285 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24286 * only the process that calls getAppTasks() can call the AppTask methods.
24288 class AppTaskImpl extends IAppTask.Stub {
24289 private int mTaskId;
24290 private int mCallingUid;
24292 public AppTaskImpl(int taskId, int callingUid) {
24294 mCallingUid = callingUid;
24297 private void checkCaller() {
24298 if (mCallingUid != Binder.getCallingUid()) {
24299 throw new SecurityException("Caller " + mCallingUid
24300 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24305 public void finishAndRemoveTask() {
24308 synchronized (ActivityManagerService.this) {
24309 long origId = Binder.clearCallingIdentity();
24311 // We remove the task from recents to preserve backwards
24312 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24313 REMOVE_FROM_RECENTS)) {
24314 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24317 Binder.restoreCallingIdentity(origId);
24323 public ActivityManager.RecentTaskInfo getTaskInfo() {
24326 synchronized (ActivityManagerService.this) {
24327 long origId = Binder.clearCallingIdentity();
24329 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24331 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24333 return createRecentTaskInfoFromTaskRecord(tr);
24335 Binder.restoreCallingIdentity(origId);
24341 public void moveToFront() {
24343 // Will bring task to front if it already has a root activity.
24344 final long origId = Binder.clearCallingIdentity();
24346 synchronized (this) {
24347 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24350 Binder.restoreCallingIdentity(origId);
24355 public int startActivity(IBinder whoThread, String callingPackage,
24356 Intent intent, String resolvedType, Bundle bOptions) {
24359 int callingUser = UserHandle.getCallingUserId();
24361 IApplicationThread appThread;
24362 synchronized (ActivityManagerService.this) {
24363 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24365 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24367 appThread = IApplicationThread.Stub.asInterface(whoThread);
24368 if (appThread == null) {
24369 throw new IllegalArgumentException("Bad app thread " + appThread);
24372 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24373 resolvedType, null, null, null, null, 0, 0, null, null,
24374 null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
24378 public void setExcludeFromRecents(boolean exclude) {
24381 synchronized (ActivityManagerService.this) {
24382 long origId = Binder.clearCallingIdentity();
24384 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24386 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24388 Intent intent = tr.getBaseIntent();
24390 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24392 intent.setFlags(intent.getFlags()
24393 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24396 Binder.restoreCallingIdentity(origId);
24403 * Kill processes for the user with id userId and that depend on the package named packageName
24406 public void killPackageDependents(String packageName, int userId) {
24407 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24408 if (packageName == null) {
24409 throw new NullPointerException(
24410 "Cannot kill the dependents of a package without its name.");
24413 long callingId = Binder.clearCallingIdentity();
24414 IPackageManager pm = AppGlobals.getPackageManager();
24417 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24418 } catch (RemoteException e) {
24420 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24421 throw new IllegalArgumentException(
24422 "Cannot kill dependents of non-existing package " + packageName);
24425 synchronized(this) {
24426 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24427 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24428 "dep: " + packageName);
24431 Binder.restoreCallingIdentity(callingId);
24436 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24437 throws RemoteException {
24438 final long callingId = Binder.clearCallingIdentity();
24440 mKeyguardController.dismissKeyguard(token, callback);
24442 Binder.restoreCallingIdentity(callingId);
24447 public int restartUserInBackground(final int userId) {
24448 return mUserController.restartUser(userId, /* foreground */ false);
24452 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24453 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24454 "scheduleApplicationInfoChanged()");
24456 synchronized (this) {
24457 final long origId = Binder.clearCallingIdentity();
24459 updateApplicationInfoLocked(packageNames, userId);
24461 Binder.restoreCallingIdentity(origId);
24466 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24467 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24468 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24469 final ProcessRecord app = mLruProcesses.get(i);
24470 if (app.thread == null) {
24474 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24478 final int packageCount = app.pkgList.size();
24479 for (int j = 0; j < packageCount; j++) {
24480 final String packageName = app.pkgList.keyAt(j);
24481 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24483 final ApplicationInfo ai = AppGlobals.getPackageManager()
24484 .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24486 app.thread.scheduleApplicationInfoChanged(ai);
24488 } catch (RemoteException e) {
24489 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24490 packageName, app));
24498 * Attach an agent to the specified process (proces name or PID)
24500 public void attachAgent(String process, String path) {
24502 synchronized (this) {
24503 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24504 if (proc == null || proc.thread == null) {
24505 throw new IllegalArgumentException("Unknown process: " + process);
24508 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24509 if (!isDebuggable) {
24510 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24511 throw new SecurityException("Process not debuggable: " + proc);
24515 proc.thread.attachAgent(path);
24517 } catch (RemoteException e) {
24518 throw new IllegalStateException("Process disappeared");
24523 public static class Injector {
24524 private NetworkManagementInternal mNmi;
24526 public Context getContext() {
24530 public AppOpsService getAppOpsService(File file, Handler handler) {
24531 return new AppOpsService(file, handler);
24534 public Handler getUiHandler(ActivityManagerService service) {
24535 return service.new UiHandler();
24538 public boolean isNetworkRestrictedForUid(int uid) {
24539 if (ensureHasNetworkManagementInternal()) {
24540 return mNmi.isNetworkRestrictedForUid(uid);
24545 private boolean ensureHasNetworkManagementInternal() {
24546 if (mNmi == null) {
24547 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24549 return mNmi != null;