2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import static android.Manifest.permission.CHANGE_CONFIGURATION;
20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25 import static android.Manifest.permission.READ_FRAME_BUFFER;
26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
32 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
35 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
36 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
37 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
38 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
39 import static android.content.pm.PackageManager.GET_PROVIDERS;
40 import static android.content.pm.PackageManager.MATCH_ANY_USER;
41 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
43 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
44 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
45 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
46 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
47 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
49 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
50 import static android.os.Build.VERSION_CODES.N;
51 import static android.os.Process.BLUETOOTH_UID;
52 import static android.os.Process.FIRST_APPLICATION_UID;
53 import static android.os.Process.FIRST_ISOLATED_UID;
54 import static android.os.Process.LAST_ISOLATED_UID;
55 import static android.os.Process.NFC_UID;
56 import static android.os.Process.PHONE_UID;
57 import static android.os.Process.PROC_CHAR;
58 import static android.os.Process.PROC_OUT_LONG;
59 import static android.os.Process.PROC_PARENS;
60 import static android.os.Process.PROC_SPACE_TERM;
61 import static android.os.Process.ProcessStartResult;
62 import static android.os.Process.ROOT_UID;
63 import static android.os.Process.SCHED_FIFO;
64 import static android.os.Process.SCHED_OTHER;
65 import static android.os.Process.SCHED_RESET_ON_FORK;
66 import static android.os.Process.SHELL_UID;
67 import static android.os.Process.SIGNAL_QUIT;
68 import static android.os.Process.SIGNAL_USR1;
69 import static android.os.Process.SYSTEM_UID;
70 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
71 import static android.os.Process.THREAD_GROUP_DEFAULT;
72 import static android.os.Process.THREAD_GROUP_TOP_APP;
73 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
74 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
75 import static android.os.Process.getFreeMemory;
76 import static android.os.Process.getTotalMemory;
77 import static android.os.Process.isThreadInProcess;
78 import static android.os.Process.killProcess;
79 import static android.os.Process.killProcessQuiet;
80 import static android.os.Process.myPid;
81 import static android.os.Process.myUid;
82 import static android.os.Process.readProcFile;
83 import static android.os.Process.removeAllProcessGroups;
84 import static android.os.Process.sendSignal;
85 import static android.os.Process.setProcessGroup;
86 import static android.os.Process.setThreadPriority;
87 import static android.os.Process.setThreadScheduler;
88 import static android.os.Process.startWebView;
89 import static android.os.Process.zygoteProcess;
90 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
91 import static android.provider.Settings.Global.DEBUG_APP;
92 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
94 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
95 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
96 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
97 import static android.provider.Settings.System.FONT_SCALE;
98 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
99 import static android.text.format.DateUtils.DAY_IN_MILLIS;
100 import static android.view.Display.DEFAULT_DISPLAY;
101 import static android.view.Display.INVALID_DISPLAY;
102 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
103 import static com.android.internal.util.XmlUtils.readIntAttribute;
104 import static com.android.internal.util.XmlUtils.readLongAttribute;
105 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
106 import static com.android.internal.util.XmlUtils.writeIntAttribute;
107 import static com.android.internal.util.XmlUtils.writeLongAttribute;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
165 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
167 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188 import static org.xmlpull.v1.XmlPullParser.START_TAG;
190 import android.Manifest;
191 import android.Manifest.permission;
192 import android.annotation.NonNull;
193 import android.annotation.Nullable;
194 import android.annotation.UserIdInt;
195 import android.app.Activity;
196 import android.app.ActivityManager;
197 import android.app.ActivityManager.RunningTaskInfo;
198 import android.app.ActivityManager.StackId;
199 import android.app.ActivityManager.StackInfo;
200 import android.app.ActivityManager.TaskSnapshot;
201 import android.app.ActivityManager.TaskThumbnailInfo;
202 import android.app.ActivityManagerInternal;
203 import android.app.ActivityManagerInternal.ScreenObserver;
204 import android.app.ActivityManagerInternal.SleepToken;
205 import android.app.ActivityOptions;
206 import android.app.ActivityThread;
207 import android.app.AlertDialog;
208 import android.app.AppGlobals;
209 import android.app.AppOpsManager;
210 import android.app.ApplicationErrorReport;
211 import android.app.ApplicationThreadConstants;
212 import android.app.BroadcastOptions;
213 import android.app.ContentProviderHolder;
214 import android.app.Dialog;
215 import android.app.IActivityController;
216 import android.app.IActivityManager;
217 import android.app.IAppTask;
218 import android.app.IApplicationThread;
219 import android.app.IInstrumentationWatcher;
220 import android.app.INotificationManager;
221 import android.app.IProcessObserver;
222 import android.app.IServiceConnection;
223 import android.app.IStopUserCallback;
224 import android.app.ITaskStackListener;
225 import android.app.IUiAutomationConnection;
226 import android.app.IUidObserver;
227 import android.app.IUserSwitchObserver;
228 import android.app.Instrumentation;
229 import android.app.Notification;
230 import android.app.NotificationManager;
231 import android.app.PendingIntent;
232 import android.app.PictureInPictureParams;
233 import android.app.ProfilerInfo;
234 import android.app.RemoteAction;
235 import android.app.WaitResult;
236 import android.app.admin.DevicePolicyManager;
237 import android.app.assist.AssistContent;
238 import android.app.assist.AssistStructure;
239 import android.app.backup.IBackupManager;
240 import android.app.usage.UsageEvents;
241 import android.app.usage.UsageStatsManagerInternal;
242 import android.appwidget.AppWidgetManager;
243 import android.content.ActivityNotFoundException;
244 import android.content.BroadcastReceiver;
245 import android.content.ClipData;
246 import android.content.ComponentCallbacks2;
247 import android.content.ComponentName;
248 import android.content.ContentProvider;
249 import android.content.ContentResolver;
250 import android.content.Context;
251 import android.content.DialogInterface;
252 import android.content.IContentProvider;
253 import android.content.IIntentReceiver;
254 import android.content.IIntentSender;
255 import android.content.Intent;
256 import android.content.IntentFilter;
257 import android.content.pm.ActivityInfo;
258 import android.content.pm.ApplicationInfo;
259 import android.content.pm.ConfigurationInfo;
260 import android.content.pm.IPackageDataObserver;
261 import android.content.pm.IPackageManager;
262 import android.content.pm.InstrumentationInfo;
263 import android.content.pm.PackageInfo;
264 import android.content.pm.PackageManager;
265 import android.content.pm.PackageManager.NameNotFoundException;
266 import android.content.pm.PackageManagerInternal;
267 import android.content.pm.ParceledListSlice;
268 import android.content.pm.PathPermission;
269 import android.content.pm.PermissionInfo;
270 import android.content.pm.ProviderInfo;
271 import android.content.pm.ResolveInfo;
272 import android.content.pm.SELinuxUtil;
273 import android.content.pm.ServiceInfo;
274 import android.content.pm.UserInfo;
275 import android.content.res.CompatibilityInfo;
276 import android.content.res.Configuration;
277 import android.content.res.Resources;
278 import android.database.ContentObserver;
279 import android.graphics.Bitmap;
280 import android.graphics.Point;
281 import android.graphics.Rect;
282 import android.location.LocationManager;
283 import android.media.audiofx.AudioEffect;
284 import android.metrics.LogMaker;
285 import android.net.Proxy;
286 import android.net.ProxyInfo;
287 import android.net.Uri;
288 import android.os.BatteryStats;
289 import android.os.Binder;
290 import android.os.Build;
291 import android.os.Bundle;
292 import android.os.Debug;
293 import android.os.DropBoxManager;
294 import android.os.Environment;
295 import android.os.FactoryTest;
296 import android.os.FileObserver;
297 import android.os.FileUtils;
298 import android.os.Handler;
299 import android.os.IBinder;
300 import android.os.IDeviceIdentifiersPolicyService;
301 import android.os.IPermissionController;
302 import android.os.IProcessInfoService;
303 import android.os.IProgressListener;
304 import android.os.LocaleList;
305 import android.os.Looper;
306 import android.os.Message;
307 import android.os.Parcel;
308 import android.os.ParcelFileDescriptor;
309 import android.os.PersistableBundle;
310 import android.os.PowerManager;
311 import android.os.PowerManagerInternal;
312 import android.os.Process;
313 import android.os.RemoteCallbackList;
314 import android.os.RemoteException;
315 import android.os.ResultReceiver;
316 import android.os.ServiceManager;
317 import android.os.ShellCallback;
318 import android.os.StrictMode;
319 import android.os.SystemClock;
320 import android.os.SystemProperties;
321 import android.os.Trace;
322 import android.os.TransactionTooLargeException;
323 import android.os.UpdateLock;
324 import android.os.UserHandle;
325 import android.os.UserManager;
326 import android.os.WorkSource;
327 import android.os.storage.IStorageManager;
328 import android.os.storage.StorageManager;
329 import android.os.storage.StorageManagerInternal;
330 import android.provider.Downloads;
331 import android.provider.Settings;
332 import android.service.voice.IVoiceInteractionSession;
333 import android.service.voice.VoiceInteractionManagerInternal;
334 import android.service.voice.VoiceInteractionSession;
335 import android.telecom.TelecomManager;
336 import android.text.TextUtils;
337 import android.text.format.DateUtils;
338 import android.text.format.Time;
339 import android.text.style.SuggestionSpan;
340 import android.util.ArrayMap;
341 import android.util.ArraySet;
342 import android.util.AtomicFile;
343 import android.util.TimingsTraceLog;
344 import android.util.DebugUtils;
345 import android.util.DisplayMetrics;
346 import android.util.EventLog;
347 import android.util.Log;
348 import android.util.Pair;
349 import android.util.PrintWriterPrinter;
350 import android.util.Slog;
351 import android.util.SparseArray;
352 import android.util.SparseIntArray;
353 import android.util.TimeUtils;
354 import android.util.Xml;
355 import android.view.Gravity;
356 import android.view.LayoutInflater;
357 import android.view.View;
358 import android.view.WindowManager;
360 import com.android.server.job.JobSchedulerInternal;
361 import com.google.android.collect.Lists;
362 import com.google.android.collect.Maps;
364 import com.android.internal.R;
365 import com.android.internal.annotations.GuardedBy;
366 import com.android.internal.annotations.VisibleForTesting;
367 import com.android.internal.app.AssistUtils;
368 import com.android.internal.app.DumpHeapActivity;
369 import com.android.internal.app.IAppOpsCallback;
370 import com.android.internal.app.IAppOpsService;
371 import com.android.internal.app.IVoiceInteractor;
372 import com.android.internal.app.ProcessMap;
373 import com.android.internal.app.SystemUserHomeActivity;
374 import com.android.internal.app.procstats.ProcessStats;
375 import com.android.internal.logging.MetricsLogger;
376 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
377 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
378 import com.android.internal.notification.SystemNotificationChannels;
379 import com.android.internal.os.BackgroundThread;
380 import com.android.internal.os.BatteryStatsImpl;
381 import com.android.internal.os.IResultReceiver;
382 import com.android.internal.os.ProcessCpuTracker;
383 import com.android.internal.os.TransferPipe;
384 import com.android.internal.os.Zygote;
385 import com.android.internal.policy.IKeyguardDismissCallback;
386 import com.android.internal.telephony.TelephonyIntents;
387 import com.android.internal.util.ArrayUtils;
388 import com.android.internal.util.DumpUtils;
389 import com.android.internal.util.FastPrintWriter;
390 import com.android.internal.util.FastXmlSerializer;
391 import com.android.internal.util.MemInfoReader;
392 import com.android.internal.util.Preconditions;
393 import com.android.server.AppOpsService;
394 import com.android.server.AttributeCache;
395 import com.android.server.DeviceIdleController;
396 import com.android.server.IntentResolver;
397 import com.android.server.LocalServices;
398 import com.android.server.LockGuard;
399 import com.android.server.NetworkManagementInternal;
400 import com.android.server.RescueParty;
401 import com.android.server.ServiceThread;
402 import com.android.server.SystemConfig;
403 import com.android.server.SystemService;
404 import com.android.server.SystemServiceManager;
405 import com.android.server.ThreadPriorityBooster;
406 import com.android.server.Watchdog;
407 import com.android.server.am.ActivityStack.ActivityState;
408 import com.android.server.firewall.IntentFirewall;
409 import com.android.server.pm.Installer;
410 import com.android.server.pm.Installer.InstallerException;
411 import com.android.server.statusbar.StatusBarManagerInternal;
412 import com.android.server.vr.VrManagerInternal;
413 import com.android.server.wm.PinnedStackWindowController;
414 import com.android.server.wm.WindowManagerService;
416 import java.text.SimpleDateFormat;
417 import org.xmlpull.v1.XmlPullParser;
418 import org.xmlpull.v1.XmlPullParserException;
419 import org.xmlpull.v1.XmlSerializer;
422 import java.io.FileDescriptor;
423 import java.io.FileInputStream;
424 import java.io.FileNotFoundException;
425 import java.io.FileOutputStream;
426 import java.io.IOException;
427 import java.io.InputStreamReader;
428 import java.io.PrintWriter;
429 import java.io.StringWriter;
430 import java.io.UnsupportedEncodingException;
431 import java.lang.ref.WeakReference;
432 import java.nio.charset.StandardCharsets;
433 import java.text.DateFormat;
434 import java.util.ArrayList;
435 import java.util.Arrays;
436 import java.util.Collections;
437 import java.util.Comparator;
438 import java.util.Date;
439 import java.util.HashMap;
440 import java.util.HashSet;
441 import java.util.Iterator;
442 import java.util.List;
443 import java.util.Locale;
444 import java.util.Map;
445 import java.util.Objects;
446 import java.util.Set;
447 import java.util.concurrent.CountDownLatch;
448 import java.util.concurrent.atomic.AtomicBoolean;
449 import java.util.concurrent.atomic.AtomicLong;
451 import dalvik.system.VMRuntime;
452 import libcore.io.IoUtils;
453 import libcore.util.EmptyArray;
455 public class ActivityManagerService extends IActivityManager.Stub
456 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
459 * Priority we boost main thread and RT of top app to.
461 public static final int TOP_APP_PRIORITY_BOOST = -10;
463 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
464 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
465 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
466 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
467 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
468 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
469 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
470 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
471 private static final String TAG_LRU = TAG + POSTFIX_LRU;
472 private static final String TAG_MU = TAG + POSTFIX_MU;
473 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
474 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
475 private static final String TAG_POWER = TAG + POSTFIX_POWER;
476 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
477 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
478 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
479 private static final String TAG_PSS = TAG + POSTFIX_PSS;
480 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
481 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
482 private static final String TAG_STACK = TAG + POSTFIX_STACK;
483 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
484 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
485 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
486 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
488 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
489 // here so that while the job scheduler can depend on AMS, the other way around
490 // need not be the case.
491 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
493 /** Control over CPU and battery monitoring */
494 // write battery stats every 30 minutes.
495 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
496 static final boolean MONITOR_CPU_USAGE = true;
497 // don't sample cpu less than every 5 seconds.
498 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
499 // wait possibly forever for next cpu sample.
500 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
501 static final boolean MONITOR_THREAD_CPU_USAGE = false;
503 // The flags that are set for all calls we make to the package manager.
504 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
506 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
508 // Amount of time after a call to stopAppSwitches() during which we will
509 // prevent further untrusted switches from happening.
510 static final long APP_SWITCH_DELAY_TIME = 5*1000;
512 // How long we wait for a launched process to attach to the activity manager
513 // before we decide it's never going to come up for real.
514 static final int PROC_START_TIMEOUT = 10*1000;
515 // How long we wait for an attached process to publish its content providers
516 // before we decide it must be hung.
517 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
519 // How long we wait for a launched process to attach to the activity manager
520 // before we decide it's never going to come up for real, when the process was
521 // started with a wrapper for instrumentation (such as Valgrind) because it
522 // could take much longer than usual.
523 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
525 // How long we allow a receiver to run before giving up on it.
526 static final int BROADCAST_FG_TIMEOUT = 10*1000;
527 static final int BROADCAST_BG_TIMEOUT = 60*1000;
529 // How long we wait until we timeout on key dispatching.
530 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
532 // How long we wait until we timeout on key dispatching during instrumentation.
533 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
535 // How long to wait in getAssistContextExtras for the activity and foreground services
536 // to respond with the result.
537 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
539 // How long top wait when going through the modern assist (which doesn't need to block
540 // on getting this result before starting to launch its UI).
541 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
543 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
544 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
546 // Maximum number of persisted Uri grants a package is allowed
547 static final int MAX_PERSISTED_URI_GRANTS = 128;
549 static final int MY_PID = myPid();
551 static final String[] EMPTY_STRING_ARRAY = new String[0];
553 // How many bytes to write into the dropbox log before truncating
554 static final int DROPBOX_MAX_SIZE = 192 * 1024;
555 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
556 // as one line, but close enough for now.
557 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
559 // Access modes for handleIncomingUser.
560 static final int ALLOW_NON_FULL = 0;
561 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
562 static final int ALLOW_FULL_ONLY = 2;
564 // Necessary ApplicationInfo flags to mark an app as persistent
565 private static final int PERSISTENT_MASK =
566 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
568 // Intent sent when remote bugreport collection has been completed
569 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
570 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
572 // Used to indicate that an app transition should be animated.
573 static final boolean ANIMATE = true;
575 // Determines whether to take full screen screenshots
576 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
579 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
581 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
584 * State indicating that there is no need for any blocking for network.
587 static final int NETWORK_STATE_NO_CHANGE = 0;
590 * State indicating that the main thread needs to be informed about the network wait.
593 static final int NETWORK_STATE_BLOCK = 1;
596 * State indicating that any threads waiting for network state to get updated can be unblocked.
599 static final int NETWORK_STATE_UNBLOCK = 2;
601 // Max character limit for a notification title. If the notification title is larger than this
602 // the notification will not be legible to the user.
603 private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
605 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
607 /** All system services */
608 SystemServiceManager mSystemServiceManager;
609 AssistUtils mAssistUtils;
611 private Installer mInstaller;
613 /** Run all ActivityStacks through this */
614 final ActivityStackSupervisor mStackSupervisor;
615 private final KeyguardController mKeyguardController;
617 final ActivityStarter mActivityStarter;
619 final TaskChangeNotificationController mTaskChangeNotificationController;
621 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
623 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
625 public final IntentFirewall mIntentFirewall;
627 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
628 // default action automatically. Important for devices without direct input
630 private boolean mShowDialogs = true;
632 private final VrController mVrController;
634 // VR Vr2d Display Id.
635 int mVr2dDisplayId = INVALID_DISPLAY;
637 // Whether we should use SCHED_FIFO for UI and RenderThreads.
638 private boolean mUseFifoUiScheduling = false;
640 BroadcastQueue mFgBroadcastQueue;
641 BroadcastQueue mBgBroadcastQueue;
642 // Convenient for easy iteration over the queues. Foreground is first
643 // so that dispatch of foreground broadcasts gets precedence.
644 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
646 BroadcastStats mLastBroadcastStats;
647 BroadcastStats mCurBroadcastStats;
649 BroadcastQueue broadcastQueueForIntent(Intent intent) {
650 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
651 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
652 "Broadcast intent " + intent + " on "
653 + (isFg ? "foreground" : "background") + " queue");
654 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
658 * The last resumed activity. This is identical to the current resumed activity most
659 * of the time but could be different when we're pausing one activity before we resume
662 private ActivityRecord mLastResumedActivity;
665 * If non-null, we are tracking the time the user spends in the currently focused app.
667 private AppTimeTracker mCurAppTimeTracker;
670 * List of intents that were used to start the most recent tasks.
672 final RecentTasks mRecentTasks;
675 * For addAppTask: cached of the last activity component that was added.
677 ComponentName mLastAddedTaskComponent;
680 * For addAppTask: cached of the last activity uid that was added.
682 int mLastAddedTaskUid;
685 * For addAppTask: cached of the last ActivityInfo that was added.
687 ActivityInfo mLastAddedTaskActivity;
690 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
692 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
695 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
697 String mDeviceOwnerName;
699 final UserController mUserController;
701 final AppErrors mAppErrors;
704 * Dump of the activity state at the time of the last ANR. Cleared after
705 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
707 String mLastANRState;
710 * Indicates the maximum time spent waiting for the network rules to get updated.
713 long mWaitForNetworkTimeoutMs;
715 public boolean canShowErrorDialogs() {
716 return mShowDialogs && !mSleeping && !mShuttingDown
717 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
718 && !(UserManager.isDeviceInDemoMode(mContext)
719 && mUserController.getCurrentUser().isDemo());
722 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
723 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
725 static void boostPriorityForLockedSection() {
726 sThreadPriorityBooster.boost();
729 static void resetPriorityAfterLockedSection() {
730 sThreadPriorityBooster.reset();
733 public class PendingAssistExtras extends Binder implements Runnable {
734 public final ActivityRecord activity;
735 public boolean isHome;
736 public final Bundle extras;
737 public final Intent intent;
738 public final String hint;
739 public final IResultReceiver receiver;
740 public final int userHandle;
741 public boolean haveResult = false;
742 public Bundle result = null;
743 public AssistStructure structure = null;
744 public AssistContent content = null;
745 public Bundle receiverExtras;
747 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
748 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
749 activity = _activity;
753 receiver = _receiver;
754 receiverExtras = _receiverExtras;
755 userHandle = _userHandle;
760 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
761 synchronized (this) {
765 pendingAssistExtrasTimedOut(this);
769 final ArrayList<PendingAssistExtras> mPendingAssistExtras
770 = new ArrayList<PendingAssistExtras>();
773 * Process management.
775 final ProcessList mProcessList = new ProcessList();
778 * All of the applications we currently have running organized by name.
779 * The keys are strings of the application package name (as
780 * returned by the package manager), and the keys are ApplicationRecord
783 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
786 * Tracking long-term execution of processes to look for abuse and other
789 final ProcessStatsService mProcessStats;
792 * The currently running isolated processes.
794 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
797 * Counter for assigning isolated process uids, to avoid frequently reusing the
800 int mNextIsolatedProcessUid = 0;
803 * The currently running heavy-weight process, if any.
805 ProcessRecord mHeavyWeightProcess = null;
808 * Non-persistent appId whitelist for background restrictions
810 int[] mBackgroundAppIdWhitelist = new int[] {
815 * Broadcast actions that will always be deliverable to unlaunched/background apps
817 ArraySet<String> mBackgroundLaunchBroadcasts;
820 * All of the processes we currently have running organized by pid.
821 * The keys are the pid running the application.
823 * <p>NOTE: This object is protected by its own lock, NOT the global
824 * activity manager lock!
826 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
829 * All of the processes that have been forced to be important. The key
830 * is the pid of the caller who requested it (we hold a death
833 abstract class ImportanceToken implements IBinder.DeathRecipient {
838 ImportanceToken(int _pid, IBinder _token, String _reason) {
845 public String toString() {
846 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
847 + " " + reason + " " + pid + " " + token + " }";
850 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
853 * List of records for processes that someone had tried to start before the
854 * system was ready. We don't start them at that point, but ensure they
855 * are started by the time booting is complete.
857 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
860 * List of persistent applications that are in the process
863 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
866 * Processes that are being forcibly torn down.
868 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
871 * List of running applications, sorted by recent usage.
872 * The first entry in the list is the least recently used.
874 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
877 * Where in mLruProcesses that the processes hosting activities start.
879 int mLruProcessActivityStart = 0;
882 * Where in mLruProcesses that the processes hosting services start.
883 * This is after (lower index) than mLruProcessesActivityStart.
885 int mLruProcessServiceStart = 0;
888 * List of processes that should gc as soon as things are idle.
890 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
893 * Processes we want to collect PSS data from.
895 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
897 private boolean mBinderTransactionTrackingEnabled = false;
900 * Last time we requested PSS data of all processes.
902 long mLastFullPssTime = SystemClock.uptimeMillis();
905 * If set, the next time we collect PSS data we should do a full collection
906 * with data from native processes and the kernel.
908 boolean mFullPssPending = false;
911 * This is the process holding what we currently consider to be
912 * the "home" activity.
914 ProcessRecord mHomeProcess;
917 * This is the process holding the activity the user last visited that
918 * is in a different process from the one they are currently in.
920 ProcessRecord mPreviousProcess;
923 * The time at which the previous process was last visible.
925 long mPreviousProcessVisibleTime;
928 * Track all uids that have actively running processes.
930 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
933 * This is for verifying the UID report flow.
935 static final boolean VALIDATE_UID_STATES = true;
936 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
939 * Packages that the user has asked to have run in screen size
940 * compatibility mode instead of filling the screen.
942 final CompatModePackages mCompatModePackages;
945 * Set of IntentSenderRecord objects that are currently active.
947 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
948 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
951 * Fingerprints (hashCode()) of stack traces that we've
952 * already logged DropBox entries for. Guarded by itself. If
953 * something (rogue user app) forces this over
954 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
956 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
957 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
960 * Strict Mode background batched logging state.
962 * The string buffer is guarded by itself, and its lock is also
963 * used to determine if another batched write is already
966 private final StringBuilder mStrictModeBuffer = new StringBuilder();
969 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
970 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
972 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
975 * Resolver for broadcast intents to registered receivers.
976 * Holds BroadcastFilter (subclass of IntentFilter).
978 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
979 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
981 protected boolean allowFilterResult(
982 BroadcastFilter filter, List<BroadcastFilter> dest) {
983 IBinder target = filter.receiverList.receiver.asBinder();
984 for (int i = dest.size() - 1; i >= 0; i--) {
985 if (dest.get(i).receiverList.receiver.asBinder() == target) {
993 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
994 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
995 || userId == filter.owningUserId) {
996 return super.newResult(filter, match, userId);
1002 protected BroadcastFilter[] newArray(int size) {
1003 return new BroadcastFilter[size];
1007 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1008 return packageName.equals(filter.packageName);
1013 * State of all active sticky broadcasts per user. Keys are the action of the
1014 * sticky Intent, values are an ArrayList of all broadcasted intents with
1015 * that action (which should usually be one). The SparseArray is keyed
1016 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1017 * for stickies that are sent to all users.
1019 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1020 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1022 final ActiveServices mServices;
1024 final static class Association {
1025 final int mSourceUid;
1026 final String mSourceProcess;
1027 final int mTargetUid;
1028 final ComponentName mTargetComponent;
1029 final String mTargetProcess;
1037 // states of the source process when the bind occurred.
1038 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1039 long mLastStateUptime;
1040 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1041 - ActivityManager.MIN_PROCESS_STATE+1];
1043 Association(int sourceUid, String sourceProcess, int targetUid,
1044 ComponentName targetComponent, String targetProcess) {
1045 mSourceUid = sourceUid;
1046 mSourceProcess = sourceProcess;
1047 mTargetUid = targetUid;
1048 mTargetComponent = targetComponent;
1049 mTargetProcess = targetProcess;
1054 * When service association tracking is enabled, this is all of the associations we
1055 * have seen. Mapping is target uid -> target component -> source uid -> source process name
1056 * -> association data.
1058 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1059 mAssociations = new SparseArray<>();
1060 boolean mTrackingAssociations;
1063 * Backup/restore process management
1065 String mBackupAppName = null;
1066 BackupRecord mBackupTarget = null;
1068 final ProviderMap mProviderMap;
1071 * List of content providers who have clients waiting for them. The
1072 * application is currently being launched and the provider will be
1073 * removed from this list once it is published.
1075 final ArrayList<ContentProviderRecord> mLaunchingProviders
1076 = new ArrayList<ContentProviderRecord>();
1079 * File storing persisted {@link #mGrantedUriPermissions}.
1081 private final AtomicFile mGrantFile;
1083 /** XML constants used in {@link #mGrantFile} */
1084 private static final String TAG_URI_GRANTS = "uri-grants";
1085 private static final String TAG_URI_GRANT = "uri-grant";
1086 private static final String ATTR_USER_HANDLE = "userHandle";
1087 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1088 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1089 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1090 private static final String ATTR_TARGET_PKG = "targetPkg";
1091 private static final String ATTR_URI = "uri";
1092 private static final String ATTR_MODE_FLAGS = "modeFlags";
1093 private static final String ATTR_CREATED_TIME = "createdTime";
1094 private static final String ATTR_PREFIX = "prefix";
1097 * Global set of specific {@link Uri} permissions that have been granted.
1098 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1099 * to {@link UriPermission#uri} to {@link UriPermission}.
1102 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1103 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1105 public static class GrantUri {
1106 public final int sourceUserId;
1107 public final Uri uri;
1108 public boolean prefix;
1110 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1111 this.sourceUserId = sourceUserId;
1113 this.prefix = prefix;
1117 public int hashCode() {
1119 hashCode = 31 * hashCode + sourceUserId;
1120 hashCode = 31 * hashCode + uri.hashCode();
1121 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1126 public boolean equals(Object o) {
1127 if (o instanceof GrantUri) {
1128 GrantUri other = (GrantUri) o;
1129 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1130 && prefix == other.prefix;
1136 public String toString() {
1137 String result = uri.toString() + " [user " + sourceUserId + "]";
1138 if (prefix) result += " [prefix]";
1142 public String toSafeString() {
1143 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1144 if (prefix) result += " [prefix]";
1148 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1149 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1150 ContentProvider.getUriWithoutUserId(uri), false);
1154 CoreSettingsObserver mCoreSettingsObserver;
1156 FontScaleSettingObserver mFontScaleSettingObserver;
1158 private final class FontScaleSettingObserver extends ContentObserver {
1159 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1161 public FontScaleSettingObserver() {
1163 ContentResolver resolver = mContext.getContentResolver();
1164 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1168 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1169 if (mFontScaleUri.equals(uri)) {
1170 updateFontScaleIfNeeded(userId);
1176 * Thread-local storage used to carry caller permissions over through
1177 * indirect content-provider access.
1179 private class Identity {
1180 public final IBinder token;
1181 public final int pid;
1182 public final int uid;
1184 Identity(IBinder _token, int _pid, int _uid) {
1191 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1194 * All information we have collected about the runtime performance of
1195 * any user id that can impact battery performance.
1197 final BatteryStatsService mBatteryStatsService;
1200 * Information about component usage
1202 UsageStatsManagerInternal mUsageStatsService;
1205 * Access to DeviceIdleController service.
1207 DeviceIdleController.LocalService mLocalDeviceIdleController;
1210 * Set of app ids that are whitelisted for device idle and thus background check.
1212 int[] mDeviceIdleWhitelist = new int[0];
1215 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1217 int[] mDeviceIdleTempWhitelist = new int[0];
1219 static final class PendingTempWhitelist {
1220 final int targetUid;
1221 final long duration;
1224 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1225 targetUid = _targetUid;
1226 duration = _duration;
1231 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1234 * Information about and control over application operations
1236 final AppOpsService mAppOpsService;
1238 /** Current sequencing integer of the configuration, for skipping old configurations. */
1239 private int mConfigurationSeq;
1242 * Temp object used when global and/or display override configuration is updated. It is also
1243 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1246 private Configuration mTempConfig = new Configuration();
1248 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1249 new UpdateConfigurationResult();
1250 private static final class UpdateConfigurationResult {
1251 // Configuration changes that were updated.
1253 // If the activity was relaunched to match the new configuration.
1254 boolean activityRelaunched;
1258 activityRelaunched = false;
1262 boolean mSuppressResizeConfigChanges;
1265 * Hardware-reported OpenGLES version.
1267 final int GL_ES_VERSION;
1270 * List of initialization arguments to pass to all processes when binding applications to them.
1271 * For example, references to the commonly used services.
1273 HashMap<String, IBinder> mAppBindArgs;
1274 HashMap<String, IBinder> mIsolatedAppBindArgs;
1277 * Temporary to avoid allocations. Protected by main lock.
1279 final StringBuilder mStringBuilder = new StringBuilder(256);
1282 * Used to control how we initialize the service.
1284 ComponentName mTopComponent;
1285 String mTopAction = Intent.ACTION_MAIN;
1288 volatile boolean mProcessesReady = false;
1289 volatile boolean mSystemReady = false;
1290 volatile boolean mOnBattery = false;
1291 volatile int mFactoryTest;
1293 @GuardedBy("this") boolean mBooting = false;
1294 @GuardedBy("this") boolean mCallFinishBooting = false;
1295 @GuardedBy("this") boolean mBootAnimationComplete = false;
1296 @GuardedBy("this") boolean mLaunchWarningShown = false;
1297 @GuardedBy("this") boolean mCheckedForSetup = false;
1299 final Context mContext;
1302 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1303 * change at runtime. Use mContext for non-UI purposes.
1305 final Context mUiContext;
1308 * The time at which we will allow normal application switches again,
1309 * after a call to {@link #stopAppSwitches()}.
1311 long mAppSwitchesAllowedTime;
1314 * This is set to true after the first switch after mAppSwitchesAllowedTime
1315 * is set; any switches after that will clear the time.
1317 boolean mDidAppSwitch;
1320 * Last time (in uptime) at which we checked for power usage.
1322 long mLastPowerCheckUptime;
1325 * Set while we are wanting to sleep, to prevent any
1326 * activities from being started/resumed.
1328 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1330 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1331 * while in the sleep state until there is a pending transition out of sleep, in which case
1332 * mSleeping is set to false, and remains false while awake.
1334 * Whether mSleeping can quickly toggled between true/false without the device actually
1335 * display changing states is undefined.
1337 private boolean mSleeping = false;
1340 * The process state used for processes that are running the top activities.
1341 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1343 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1346 * Set while we are running a voice interaction. This overrides
1347 * sleeping while it is active.
1349 IVoiceInteractionSession mRunningVoice;
1352 * For some direct access we need to power manager.
1354 PowerManagerInternal mLocalPowerManager;
1357 * We want to hold a wake lock while running a voice interaction session, since
1358 * this may happen with the screen off and we need to keep the CPU running to
1359 * be able to continue to interact with the user.
1361 PowerManager.WakeLock mVoiceWakeLock;
1364 * State of external calls telling us if the device is awake or asleep.
1366 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1369 * Set if we are shutting down the system, similar to sleeping.
1371 boolean mShuttingDown = false;
1374 * Current sequence id for oom_adj computation traversal.
1379 * Current sequence id for process LRU updating.
1384 * Keep track of the non-cached/empty process we last found, to help
1385 * determine how to distribute cached/empty processes next time.
1387 int mNumNonCachedProcs = 0;
1390 * Keep track of the number of cached hidden procs, to balance oom adj
1391 * distribution between those and empty procs.
1393 int mNumCachedHiddenProcs = 0;
1396 * Keep track of the number of service processes we last found, to
1397 * determine on the next iteration which should be B services.
1399 int mNumServiceProcs = 0;
1400 int mNewNumAServiceProcs = 0;
1401 int mNewNumServiceProcs = 0;
1404 * Allow the current computed overall memory level of the system to go down?
1405 * This is set to false when we are killing processes for reasons other than
1406 * memory management, so that the now smaller process list will not be taken as
1407 * an indication that memory is tighter.
1409 boolean mAllowLowerMemLevel = false;
1412 * The last computed memory level, for holding when we are in a state that
1413 * processes are going away for other reasons.
1415 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1418 * The last total number of process we have, to determine if changes actually look
1419 * like a shrinking number of process due to lower RAM.
1421 int mLastNumProcesses;
1424 * The uptime of the last time we performed idle maintenance.
1426 long mLastIdleTime = SystemClock.uptimeMillis();
1429 * Total time spent with RAM that has been added in the past since the last idle time.
1431 long mLowRamTimeSinceLastIdle = 0;
1434 * If RAM is currently low, when that horrible situation started.
1436 long mLowRamStartTime = 0;
1439 * For reporting to battery stats the current top application.
1441 private String mCurResumedPackage = null;
1442 private int mCurResumedUid = -1;
1445 * For reporting to battery stats the apps currently running foreground
1446 * service. The ProcessMap is package/uid tuples; each of these contain
1447 * an array of the currently foreground processes.
1449 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1450 = new ProcessMap<ArrayList<ProcessRecord>>();
1453 * Set if the systemServer made a call to enterSafeMode.
1458 * If true, we are running under a test environment so will sample PSS from processes
1459 * much more rapidly to try to collect better data when the tests are rapidly
1460 * running through apps.
1462 boolean mTestPssMode = false;
1464 String mDebugApp = null;
1465 boolean mWaitForDebugger = false;
1466 boolean mDebugTransient = false;
1467 String mOrigDebugApp = null;
1468 boolean mOrigWaitForDebugger = false;
1469 boolean mAlwaysFinishActivities = false;
1470 boolean mForceResizableActivities;
1472 * Flag that indicates if multi-window is enabled.
1474 * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1475 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1476 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1477 * At least one of the forms of multi-window must be enabled in order for this flag to be
1478 * initialized to 'true'.
1480 * @see #mSupportsSplitScreenMultiWindow
1481 * @see #mSupportsFreeformWindowManagement
1482 * @see #mSupportsPictureInPicture
1483 * @see #mSupportsMultiDisplay
1485 boolean mSupportsMultiWindow;
1486 boolean mSupportsSplitScreenMultiWindow;
1487 boolean mSupportsFreeformWindowManagement;
1488 boolean mSupportsPictureInPicture;
1489 boolean mSupportsMultiDisplay;
1490 boolean mSupportsLeanbackOnly;
1491 IActivityController mController = null;
1492 boolean mControllerIsAMonkey = false;
1493 String mProfileApp = null;
1494 ProcessRecord mProfileProc = null;
1495 ProfilerInfo mProfilerInfo = null;
1498 * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1499 * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1500 * A non-null agent in mProfileInfo overrides this.
1502 private @Nullable Map<String, String> mAppAgentMap = null;
1504 int mProfileType = 0;
1505 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1506 String mMemWatchDumpProcName;
1507 String mMemWatchDumpFile;
1508 int mMemWatchDumpPid;
1509 int mMemWatchDumpUid;
1510 String mTrackAllocationApp = null;
1511 String mNativeDebuggingApp = null;
1513 final long[] mTmpLong = new long[2];
1515 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1518 * A global counter for generating sequence numbers.
1519 * This value will be used when incrementing sequence numbers in individual uidRecords.
1521 * Having a global counter ensures that seq numbers are monotonically increasing for a
1522 * particular uid even when the uidRecord is re-created.
1526 long mProcStateSeqCounter = 0;
1528 private final Injector mInjector;
1530 static final class ProcessChangeItem {
1531 static final int CHANGE_ACTIVITIES = 1<<0;
1536 boolean foregroundActivities;
1539 static final class UidObserverRegistration {
1545 final SparseIntArray lastProcStates;
1547 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1551 cutpoint = _cutpoint;
1552 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1553 lastProcStates = new SparseIntArray();
1555 lastProcStates = null;
1560 final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1562 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1563 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1565 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1566 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1568 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1569 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1571 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1572 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1574 OomAdjObserver mCurOomAdjObserver;
1577 interface OomAdjObserver {
1578 void onOomAdjMessage(String msg);
1582 * Runtime CPU use collection thread. This object's lock is used to
1583 * perform synchronization with the thread (notifying it to run).
1585 final Thread mProcessCpuThread;
1588 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1589 * Must acquire this object's lock when accessing it.
1590 * NOTE: this lock will be held while doing long operations (trawling
1591 * through all processes in /proc), so it should never be acquired by
1592 * any critical paths such as when holding the main activity manager lock.
1594 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1595 MONITOR_THREAD_CPU_USAGE);
1596 final AtomicLong mLastCpuTime = new AtomicLong(0);
1597 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1598 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1600 long mLastWriteTime = 0;
1603 * Used to retain an update lock when the foreground activity is in
1606 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1609 * Set to true after the system has finished booting.
1611 boolean mBooted = false;
1613 WindowManagerService mWindowManager;
1614 final ActivityThread mSystemThread;
1616 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1617 final ProcessRecord mApp;
1619 final IApplicationThread mAppThread;
1621 AppDeathRecipient(ProcessRecord app, int pid,
1622 IApplicationThread thread) {
1623 if (DEBUG_ALL) Slog.v(
1624 TAG, "New death recipient " + this
1625 + " for thread " + thread.asBinder());
1628 mAppThread = thread;
1632 public void binderDied() {
1633 if (DEBUG_ALL) Slog.v(
1634 TAG, "Death received in " + this
1635 + " for thread " + mAppThread.asBinder());
1636 synchronized(ActivityManagerService.this) {
1637 appDiedLocked(mApp, mPid, mAppThread, true);
1642 static final int SHOW_ERROR_UI_MSG = 1;
1643 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1644 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1645 static final int UPDATE_CONFIGURATION_MSG = 4;
1646 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1647 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1648 static final int SERVICE_TIMEOUT_MSG = 12;
1649 static final int UPDATE_TIME_ZONE = 13;
1650 static final int SHOW_UID_ERROR_UI_MSG = 14;
1651 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1652 static final int PROC_START_TIMEOUT_MSG = 20;
1653 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1654 static final int KILL_APPLICATION_MSG = 22;
1655 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1656 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1657 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1658 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1659 static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1660 static final int CLEAR_DNS_CACHE_MSG = 28;
1661 static final int UPDATE_HTTP_PROXY_MSG = 29;
1662 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1663 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1664 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1665 static final int REPORT_MEM_USAGE_MSG = 33;
1666 static final int REPORT_USER_SWITCH_MSG = 34;
1667 static final int CONTINUE_USER_SWITCH_MSG = 35;
1668 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1669 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1670 static final int PERSIST_URI_GRANTS_MSG = 38;
1671 static final int REQUEST_ALL_PSS_MSG = 39;
1672 static final int START_PROFILES_MSG = 40;
1673 static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1674 static final int SYSTEM_USER_START_MSG = 42;
1675 static final int SYSTEM_USER_CURRENT_MSG = 43;
1676 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1677 static final int FINISH_BOOTING_MSG = 45;
1678 static final int START_USER_SWITCH_UI_MSG = 46;
1679 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1680 static final int DISMISS_DIALOG_UI_MSG = 48;
1681 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1682 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1683 static final int DELETE_DUMPHEAP_MSG = 51;
1684 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1685 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1686 static final int REPORT_TIME_TRACKER_MSG = 54;
1687 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1688 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1689 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1690 static final int IDLE_UIDS_MSG = 58;
1691 static final int SYSTEM_USER_UNLOCK_MSG = 59;
1692 static final int LOG_STACK_STATE = 60;
1693 static final int VR_MODE_CHANGE_MSG = 61;
1694 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1695 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1696 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1697 static final int NOTIFY_VR_SLEEPING_MSG = 65;
1698 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1699 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1700 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1701 static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1702 static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1703 static final int DISPATCH_SCREEN_AWAKE_MSG = 71;
1704 static final int DISPATCH_SCREEN_KEYGUARD_MSG = 72;
1705 static final int START_USER_SWITCH_FG_MSG = 712;
1706 static final int NOTIFY_VR_KEYGUARD_MSG = 74;
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;
1748 private static String sTheRealBuildSerial = Build.UNKNOWN;
1751 * Current global configuration information. Contains general settings for the entire system,
1752 * also corresponds to the merged configuration of the default display.
1754 Configuration getGlobalConfiguration() {
1755 return mStackSupervisor.getConfiguration();
1758 final class KillHandler extends Handler {
1759 static final int KILL_PROCESS_GROUP_MSG = 4000;
1761 public KillHandler(Looper looper) {
1762 super(looper, null, true);
1766 public void handleMessage(Message msg) {
1768 case KILL_PROCESS_GROUP_MSG:
1770 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1771 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1772 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1777 super.handleMessage(msg);
1782 final class UiHandler extends Handler {
1783 public UiHandler() {
1784 super(com.android.server.UiThread.get().getLooper(), null, true);
1788 public void handleMessage(Message msg) {
1790 case SHOW_ERROR_UI_MSG: {
1791 mAppErrors.handleShowAppErrorUi(msg);
1792 ensureBootCompleted();
1794 case SHOW_NOT_RESPONDING_UI_MSG: {
1795 mAppErrors.handleShowAnrUi(msg);
1796 ensureBootCompleted();
1798 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1799 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1800 synchronized (ActivityManagerService.this) {
1801 ProcessRecord proc = (ProcessRecord) data.get("app");
1803 Slog.e(TAG, "App not found when showing strict mode dialog.");
1806 if (proc.crashDialog != null) {
1807 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1810 AppErrorResult res = (AppErrorResult) data.get("result");
1811 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1812 Dialog d = new StrictModeViolationDialog(mUiContext,
1813 ActivityManagerService.this, res, proc);
1815 proc.crashDialog = d;
1817 // The device is asleep, so just pretend that the user
1818 // saw a crash dialog and hit "force quit".
1822 ensureBootCompleted();
1824 case SHOW_FACTORY_ERROR_UI_MSG: {
1825 Dialog d = new FactoryErrorDialog(
1826 mUiContext, msg.getData().getCharSequence("msg"));
1828 ensureBootCompleted();
1830 case WAIT_FOR_DEBUGGER_UI_MSG: {
1831 synchronized (ActivityManagerService.this) {
1832 ProcessRecord app = (ProcessRecord)msg.obj;
1833 if (msg.arg1 != 0) {
1834 if (!app.waitedForDebugger) {
1835 Dialog d = new AppWaitingForDebuggerDialog(
1836 ActivityManagerService.this,
1839 app.waitedForDebugger = true;
1843 if (app.waitDialog != null) {
1844 app.waitDialog.dismiss();
1845 app.waitDialog = null;
1850 case SHOW_UID_ERROR_UI_MSG: {
1852 AlertDialog d = new BaseErrorDialog(mUiContext);
1853 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1854 d.setCancelable(false);
1855 d.setTitle(mUiContext.getText(R.string.android_system_label));
1856 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1857 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1858 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1862 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1864 AlertDialog d = new BaseErrorDialog(mUiContext);
1865 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1866 d.setCancelable(false);
1867 d.setTitle(mUiContext.getText(R.string.android_system_label));
1868 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1869 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1870 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1874 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1875 synchronized (ActivityManagerService.this) {
1876 ActivityRecord ar = (ActivityRecord) msg.obj;
1877 if (mCompatModeDialog != null) {
1878 if (mCompatModeDialog.mAppInfo.packageName.equals(
1879 ar.info.applicationInfo.packageName)) {
1882 mCompatModeDialog.dismiss();
1883 mCompatModeDialog = null;
1885 if (ar != null && false) {
1886 if (mCompatModePackages.getPackageAskCompatModeLocked(
1888 int mode = mCompatModePackages.computeCompatModeLocked(
1889 ar.info.applicationInfo);
1890 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1891 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1892 mCompatModeDialog = new CompatModeDialog(
1893 ActivityManagerService.this, mUiContext,
1894 ar.info.applicationInfo);
1895 mCompatModeDialog.show();
1902 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1903 synchronized (ActivityManagerService.this) {
1904 final ActivityRecord ar = (ActivityRecord) msg.obj;
1905 if (mUnsupportedDisplaySizeDialog != null) {
1906 mUnsupportedDisplaySizeDialog.dismiss();
1907 mUnsupportedDisplaySizeDialog = null;
1909 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1911 // TODO(multi-display): Show dialog on appropriate display.
1912 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1913 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1914 mUnsupportedDisplaySizeDialog.show();
1919 case START_USER_SWITCH_UI_MSG: {
1920 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1923 case DISMISS_DIALOG_UI_MSG: {
1924 final Dialog d = (Dialog) msg.obj;
1928 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1929 dispatchProcessesChanged();
1932 case DISPATCH_PROCESS_DIED_UI_MSG: {
1933 final int pid = msg.arg1;
1934 final int uid = msg.arg2;
1935 dispatchProcessDied(pid, uid);
1938 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1939 dispatchUidsChanged();
1941 case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1942 dispatchOomAdjObserver((String)msg.obj);
1944 case PUSH_TEMP_WHITELIST_UI_MSG: {
1945 pushTempWhitelist();
1951 final class MainHandler extends Handler {
1952 public MainHandler(Looper looper) {
1953 super(looper, null, true);
1957 public void handleMessage(Message msg) {
1959 case UPDATE_CONFIGURATION_MSG: {
1960 final ContentResolver resolver = mContext.getContentResolver();
1961 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1964 case GC_BACKGROUND_PROCESSES_MSG: {
1965 synchronized (ActivityManagerService.this) {
1966 performAppGcsIfAppropriateLocked();
1969 case SERVICE_TIMEOUT_MSG: {
1970 mServices.serviceTimeout((ProcessRecord)msg.obj);
1972 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1973 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1975 case SERVICE_FOREGROUND_CRASH_MSG: {
1976 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1978 case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1979 RemoteCallbackList<IResultReceiver> callbacks
1980 = (RemoteCallbackList<IResultReceiver>)msg.obj;
1981 int N = callbacks.beginBroadcast();
1982 for (int i = 0; i < N; i++) {
1984 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1985 } catch (RemoteException e) {
1988 callbacks.finishBroadcast();
1990 case UPDATE_TIME_ZONE: {
1991 synchronized (ActivityManagerService.this) {
1992 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1993 ProcessRecord r = mLruProcesses.get(i);
1994 if (r.thread != null) {
1996 r.thread.updateTimeZone();
1997 } catch (RemoteException ex) {
1998 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2004 case CLEAR_DNS_CACHE_MSG: {
2005 synchronized (ActivityManagerService.this) {
2006 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2007 ProcessRecord r = mLruProcesses.get(i);
2008 if (r.thread != null) {
2010 r.thread.clearDnsCache();
2011 } catch (RemoteException ex) {
2012 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2018 case UPDATE_HTTP_PROXY_MSG: {
2019 ProxyInfo proxy = (ProxyInfo)msg.obj;
2022 String exclList = "";
2023 Uri pacFileUrl = Uri.EMPTY;
2024 if (proxy != null) {
2025 host = proxy.getHost();
2026 port = Integer.toString(proxy.getPort());
2027 exclList = proxy.getExclusionListAsString();
2028 pacFileUrl = proxy.getPacFileUrl();
2030 synchronized (ActivityManagerService.this) {
2031 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2032 ProcessRecord r = mLruProcesses.get(i);
2033 if (r.thread != null) {
2035 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2036 } catch (RemoteException ex) {
2037 Slog.w(TAG, "Failed to update http proxy for: " +
2038 r.info.processName);
2044 case PROC_START_TIMEOUT_MSG: {
2045 ProcessRecord app = (ProcessRecord)msg.obj;
2046 synchronized (ActivityManagerService.this) {
2047 processStartTimedOutLocked(app);
2050 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2051 ProcessRecord app = (ProcessRecord)msg.obj;
2052 synchronized (ActivityManagerService.this) {
2053 processContentProviderPublishTimedOutLocked(app);
2056 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2057 synchronized (ActivityManagerService.this) {
2058 mActivityStarter.doPendingActivityLaunchesLocked(true);
2061 case KILL_APPLICATION_MSG: {
2062 synchronized (ActivityManagerService.this) {
2063 final int appId = msg.arg1;
2064 final int userId = msg.arg2;
2065 Bundle bundle = (Bundle)msg.obj;
2066 String pkg = bundle.getString("pkg");
2067 String reason = bundle.getString("reason");
2068 forceStopPackageLocked(pkg, appId, false, false, true, false,
2069 false, userId, reason);
2072 case FINALIZE_PENDING_INTENT_MSG: {
2073 ((PendingIntentRecord)msg.obj).completeFinalize();
2075 case POST_HEAVY_NOTIFICATION_MSG: {
2076 INotificationManager inm = NotificationManager.getService();
2081 ActivityRecord root = (ActivityRecord)msg.obj;
2082 ProcessRecord process = root.app;
2083 if (process == null) {
2088 Context context = mContext.createPackageContext(process.info.packageName, 0);
2089 String text = mContext.getString(R.string.heavy_weight_notification,
2090 context.getApplicationInfo().loadLabel(context.getPackageManager()));
2091 Notification notification =
2092 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2093 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2097 .setColor(mContext.getColor(
2098 com.android.internal.R.color.system_notification_accent_color))
2099 .setContentTitle(text)
2101 mContext.getText(R.string.heavy_weight_notification_detail))
2102 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2103 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2104 new UserHandle(root.userId)))
2107 inm.enqueueNotificationWithTag("android", "android", null,
2108 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2109 notification, root.userId);
2110 } catch (RuntimeException e) {
2111 Slog.w(ActivityManagerService.TAG,
2112 "Error showing notification for heavy-weight app", e);
2113 } catch (RemoteException e) {
2115 } catch (NameNotFoundException e) {
2116 Slog.w(TAG, "Unable to create context for heavy notification", e);
2119 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2120 INotificationManager inm = NotificationManager.getService();
2125 inm.cancelNotificationWithTag("android", null,
2126 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2127 } catch (RuntimeException e) {
2128 Slog.w(ActivityManagerService.TAG,
2129 "Error canceling notification for service", e);
2130 } catch (RemoteException e) {
2133 case CHECK_EXCESSIVE_POWER_USE_MSG: {
2134 synchronized (ActivityManagerService.this) {
2135 checkExcessivePowerUsageLocked();
2136 removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2137 Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2138 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2141 case REPORT_MEM_USAGE_MSG: {
2142 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2143 Thread thread = new Thread() {
2144 @Override public void run() {
2145 reportMemUsage(memInfos);
2151 case START_USER_SWITCH_FG_MSG: {
2152 mUserController.startUserInForeground(msg.arg1);
2155 case REPORT_USER_SWITCH_MSG: {
2156 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2159 case CONTINUE_USER_SWITCH_MSG: {
2160 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2163 case USER_SWITCH_TIMEOUT_MSG: {
2164 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2167 case IMMERSIVE_MODE_LOCK_MSG: {
2168 final boolean nextState = (msg.arg1 != 0);
2169 if (mUpdateLock.isHeld() != nextState) {
2170 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2171 "Applying new update lock state '" + nextState
2172 + "' for " + (ActivityRecord)msg.obj);
2174 mUpdateLock.acquire();
2176 mUpdateLock.release();
2181 case PERSIST_URI_GRANTS_MSG: {
2182 writeGrantedUriPermissions();
2185 case REQUEST_ALL_PSS_MSG: {
2186 synchronized (ActivityManagerService.this) {
2187 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2191 case START_PROFILES_MSG: {
2192 synchronized (ActivityManagerService.this) {
2193 mUserController.startProfilesLocked();
2197 case UPDATE_TIME_PREFERENCE_MSG: {
2198 // The user's time format preference might have changed.
2199 // For convenience we re-use the Intent extra values.
2200 synchronized (ActivityManagerService.this) {
2201 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2202 ProcessRecord r = mLruProcesses.get(i);
2203 if (r.thread != null) {
2205 r.thread.updateTimePrefs(msg.arg1);
2206 } catch (RemoteException ex) {
2207 Slog.w(TAG, "Failed to update preferences for: "
2208 + r.info.processName);
2215 case SYSTEM_USER_START_MSG: {
2216 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2217 Integer.toString(msg.arg1), msg.arg1);
2218 mSystemServiceManager.startUser(msg.arg1);
2221 case SYSTEM_USER_UNLOCK_MSG: {
2222 final int userId = msg.arg1;
2223 mSystemServiceManager.unlockUser(userId);
2224 synchronized (ActivityManagerService.this) {
2225 mRecentTasks.loadUserRecentsLocked(userId);
2227 if (userId == UserHandle.USER_SYSTEM) {
2228 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2230 installEncryptionUnawareProviders(userId);
2231 mUserController.finishUserUnlocked((UserState) msg.obj);
2234 case SYSTEM_USER_CURRENT_MSG: {
2235 mBatteryStatsService.noteEvent(
2236 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2237 Integer.toString(msg.arg2), msg.arg2);
2238 mBatteryStatsService.noteEvent(
2239 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2240 Integer.toString(msg.arg1), msg.arg1);
2241 mSystemServiceManager.switchUser(msg.arg1);
2244 case ENTER_ANIMATION_COMPLETE_MSG: {
2245 synchronized (ActivityManagerService.this) {
2246 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2247 if (r != null && r.app != null && r.app.thread != null) {
2249 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2250 } catch (RemoteException e) {
2256 case FINISH_BOOTING_MSG: {
2257 if (msg.arg1 != 0) {
2258 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2260 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2262 if (msg.arg2 != 0) {
2263 enableScreenAfterBoot();
2267 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2269 Locale l = (Locale) msg.obj;
2270 IBinder service = ServiceManager.getService("mount");
2271 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2272 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2273 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2274 } catch (RemoteException e) {
2275 Log.e(TAG, "Error storing locale for decryption UI", e);
2279 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2280 final int uid = msg.arg1;
2281 final byte[] firstPacket = (byte[]) msg.obj;
2283 synchronized (mPidsSelfLocked) {
2284 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2285 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2288 p.thread.notifyCleartextNetwork(firstPacket);
2289 } catch (RemoteException ignored) {
2296 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2297 final String procName;
2299 final long memLimit;
2300 final String reportPackage;
2301 synchronized (ActivityManagerService.this) {
2302 procName = mMemWatchDumpProcName;
2303 uid = mMemWatchDumpUid;
2304 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2306 val = mMemWatchProcesses.get(procName, 0);
2309 memLimit = val.first;
2310 reportPackage = val.second;
2313 reportPackage = null;
2316 if (procName == null) {
2320 if (DEBUG_PSS) Slog.d(TAG_PSS,
2321 "Showing dump heap notification from " + procName + "/" + uid);
2323 INotificationManager inm = NotificationManager.getService();
2328 String text = mContext.getString(R.string.dump_heap_notification, procName);
2331 Intent deleteIntent = new Intent();
2332 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2333 Intent intent = new Intent();
2334 intent.setClassName("android", DumpHeapActivity.class.getName());
2335 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2336 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2337 if (reportPackage != null) {
2338 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2340 int userId = UserHandle.getUserId(uid);
2341 Notification notification =
2342 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2343 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2346 .setAutoCancel(true)
2348 .setColor(mContext.getColor(
2349 com.android.internal.R.color.system_notification_accent_color))
2350 .setContentTitle(text)
2352 mContext.getText(R.string.dump_heap_notification_detail))
2353 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2354 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2355 new UserHandle(userId)))
2356 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2357 deleteIntent, 0, UserHandle.SYSTEM))
2361 inm.enqueueNotificationWithTag("android", "android", null,
2362 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2363 notification, userId);
2364 } catch (RuntimeException e) {
2365 Slog.w(ActivityManagerService.TAG,
2366 "Error showing notification for dump heap", e);
2367 } catch (RemoteException e) {
2370 case DELETE_DUMPHEAP_MSG: {
2371 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2372 null, DumpHeapActivity.JAVA_URI,
2373 Intent.FLAG_GRANT_READ_URI_PERMISSION
2374 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2375 UserHandle.myUserId());
2376 synchronized (ActivityManagerService.this) {
2377 mMemWatchDumpFile = null;
2378 mMemWatchDumpProcName = null;
2379 mMemWatchDumpPid = -1;
2380 mMemWatchDumpUid = -1;
2383 case FOREGROUND_PROFILE_CHANGED_MSG: {
2384 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2386 case REPORT_TIME_TRACKER_MSG: {
2387 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2388 tracker.deliverResult(mContext);
2390 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2391 mUserController.dispatchUserSwitchComplete(msg.arg1);
2393 case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2394 mUserController.dispatchLockedBootComplete(msg.arg1);
2396 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2397 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2399 connection.shutdown();
2400 } catch (RemoteException e) {
2401 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2403 // Only a UiAutomation can set this flag and now that
2404 // it is finished we make sure it is reset to its default.
2405 mUserIsMonkey = false;
2407 case IDLE_UIDS_MSG: {
2410 case VR_MODE_CHANGE_MSG: {
2411 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2414 synchronized (ActivityManagerService.this) {
2415 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2416 mWindowManager.disableNonVrUi(disableNonVrUi);
2417 if (disableNonVrUi) {
2418 // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2419 // then remove the pinned stack.
2420 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2422 if (pinnedStack != null) {
2423 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2428 case DISPATCH_SCREEN_AWAKE_MSG: {
2429 final boolean isAwake = msg.arg1 != 0;
2430 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2431 mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2434 case DISPATCH_SCREEN_KEYGUARD_MSG: {
2435 final boolean isShowing = msg.arg1 != 0;
2436 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2437 mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2440 case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2441 synchronized (ActivityManagerService.this) {
2442 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2443 ProcessRecord r = mLruProcesses.get(i);
2444 if (r.thread != null) {
2446 r.thread.handleTrustStorageUpdate();
2447 } catch (RemoteException ex) {
2448 Slog.w(TAG, "Failed to handle trust storage update for: " +
2449 r.info.processName);
2459 static final int COLLECT_PSS_BG_MSG = 1;
2461 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2463 public void handleMessage(Message msg) {
2465 case COLLECT_PSS_BG_MSG: {
2466 long start = SystemClock.uptimeMillis();
2467 MemInfoReader memInfo = null;
2468 synchronized (ActivityManagerService.this) {
2469 if (mFullPssPending) {
2470 mFullPssPending = false;
2471 memInfo = new MemInfoReader();
2474 if (memInfo != null) {
2475 updateCpuStatsNow();
2476 long nativeTotalPss = 0;
2477 final List<ProcessCpuTracker.Stats> stats;
2478 synchronized (mProcessCpuTracker) {
2479 stats = mProcessCpuTracker.getStats( (st)-> {
2480 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2483 final int N = stats.size();
2484 for (int j = 0; j < N; j++) {
2485 synchronized (mPidsSelfLocked) {
2486 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2487 // This is one of our own processes; skip it.
2491 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2493 memInfo.readMemInfo();
2494 synchronized (ActivityManagerService.this) {
2495 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2496 + (SystemClock.uptimeMillis()-start) + "ms");
2497 final long cachedKb = memInfo.getCachedSizeKb();
2498 final long freeKb = memInfo.getFreeSizeKb();
2499 final long zramKb = memInfo.getZramTotalSizeKb();
2500 final long kernelKb = memInfo.getKernelUsedSizeKb();
2501 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2502 kernelKb*1024, nativeTotalPss*1024);
2503 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2509 long[] tmp = new long[2];
2515 synchronized (ActivityManagerService.this) {
2516 if (mPendingPssProcesses.size() <= 0) {
2517 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2518 "Collected PSS of " + num + " processes in "
2519 + (SystemClock.uptimeMillis() - start) + "ms");
2520 mPendingPssProcesses.clear();
2523 proc = mPendingPssProcesses.remove(0);
2524 procState = proc.pssProcState;
2525 lastPssTime = proc.lastPssTime;
2526 if (proc.thread != null && procState == proc.setProcState
2527 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2528 < SystemClock.uptimeMillis()) {
2536 long pss = Debug.getPss(pid, tmp, null);
2537 synchronized (ActivityManagerService.this) {
2538 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2539 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2541 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2542 SystemClock.uptimeMillis());
2552 public void setSystemProcess() {
2554 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2555 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2556 ServiceManager.addService("meminfo", new MemBinder(this));
2557 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2558 ServiceManager.addService("dbinfo", new DbBinder(this));
2559 if (MONITOR_CPU_USAGE) {
2560 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2562 ServiceManager.addService("permission", new PermissionController(this));
2563 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2565 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2566 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2567 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2569 synchronized (this) {
2570 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2571 app.persistent = true;
2573 app.maxAdj = ProcessList.SYSTEM_ADJ;
2574 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2575 synchronized (mPidsSelfLocked) {
2576 mPidsSelfLocked.put(app.pid, app);
2578 updateLruProcessLocked(app, false, null);
2579 updateOomAdjLocked();
2581 } catch (PackageManager.NameNotFoundException e) {
2582 throw new RuntimeException(
2583 "Unable to find android system package", e);
2587 public void setWindowManager(WindowManagerService wm) {
2588 mWindowManager = wm;
2589 mStackSupervisor.setWindowManager(wm);
2590 mActivityStarter.setWindowManager(wm);
2593 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2594 mUsageStatsService = usageStatsManager;
2597 public void startObservingNativeCrashes() {
2598 final NativeCrashListener ncl = new NativeCrashListener(this);
2602 public IAppOpsService getAppOpsService() {
2603 return mAppOpsService;
2606 static class MemBinder extends Binder {
2607 ActivityManagerService mActivityManagerService;
2608 MemBinder(ActivityManagerService activityManagerService) {
2609 mActivityManagerService = activityManagerService;
2613 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2614 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2615 "meminfo", pw)) return;
2616 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2620 static class GraphicsBinder extends Binder {
2621 ActivityManagerService mActivityManagerService;
2622 GraphicsBinder(ActivityManagerService activityManagerService) {
2623 mActivityManagerService = activityManagerService;
2627 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2628 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2629 "gfxinfo", pw)) return;
2630 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2634 static class DbBinder extends Binder {
2635 ActivityManagerService mActivityManagerService;
2636 DbBinder(ActivityManagerService activityManagerService) {
2637 mActivityManagerService = activityManagerService;
2641 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2642 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2643 "dbinfo", pw)) return;
2644 mActivityManagerService.dumpDbInfo(fd, pw, args);
2648 static class CpuBinder extends Binder {
2649 ActivityManagerService mActivityManagerService;
2650 CpuBinder(ActivityManagerService activityManagerService) {
2651 mActivityManagerService = activityManagerService;
2655 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2656 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2657 "cpuinfo", pw)) return;
2658 synchronized (mActivityManagerService.mProcessCpuTracker) {
2659 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2660 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2661 SystemClock.uptimeMillis()));
2666 public static final class Lifecycle extends SystemService {
2667 private final ActivityManagerService mService;
2669 public Lifecycle(Context context) {
2671 mService = new ActivityManagerService(context);
2675 public void onStart() {
2680 public void onCleanupUser(int userId) {
2681 mService.mBatteryStatsService.onCleanupUser(userId);
2684 public ActivityManagerService getService() {
2690 public ActivityManagerService(Injector injector) {
2691 mInjector = injector;
2692 mContext = mInjector.getContext();
2695 mActivityStarter = null;
2697 mAppOpsService = mInjector.getAppOpsService(null, null);
2698 mBatteryStatsService = null;
2699 mCompatModePackages = null;
2703 mHandlerThread = null;
2704 mIntentFirewall = null;
2705 mKeyguardController = null;
2706 mPermissionReviewRequired = false;
2707 mProcessCpuThread = null;
2708 mProcessStats = null;
2709 mProviderMap = null;
2710 mRecentTasks = null;
2712 mStackSupervisor = null;
2713 mSystemThread = null;
2714 mTaskChangeNotificationController = null;
2715 mUiHandler = injector.getUiHandler(null);
2716 mUserController = null;
2717 mVrController = null;
2720 // Note: This method is invoked on the main thread but may need to attach various
2721 // handlers to other threads. So take care to be explicit about the looper.
2722 public ActivityManagerService(Context systemContext) {
2723 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2724 mInjector = new Injector();
2725 mContext = systemContext;
2727 mFactoryTest = FactoryTest.getMode();
2728 mSystemThread = ActivityThread.currentActivityThread();
2729 mUiContext = mSystemThread.getSystemUiContext();
2731 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2733 mPermissionReviewRequired = mContext.getResources().getBoolean(
2734 com.android.internal.R.bool.config_permissionReviewRequired);
2736 mHandlerThread = new ServiceThread(TAG,
2737 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2738 mHandlerThread.start();
2739 mHandler = new MainHandler(mHandlerThread.getLooper());
2740 mUiHandler = mInjector.getUiHandler(this);
2742 mConstants = new ActivityManagerConstants(this, mHandler);
2744 /* static; one-time init here */
2745 if (sKillHandler == null) {
2746 sKillThread = new ServiceThread(TAG + ":kill",
2747 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2748 sKillThread.start();
2749 sKillHandler = new KillHandler(sKillThread.getLooper());
2752 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2753 "foreground", BROADCAST_FG_TIMEOUT, false);
2754 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2755 "background", BROADCAST_BG_TIMEOUT, true);
2756 mBroadcastQueues[0] = mFgBroadcastQueue;
2757 mBroadcastQueues[1] = mBgBroadcastQueue;
2759 mServices = new ActiveServices(this);
2760 mProviderMap = new ProviderMap(this);
2761 mAppErrors = new AppErrors(mUiContext, this);
2763 // TODO: Move creation of battery stats service outside of activity manager service.
2764 File dataDir = Environment.getDataDirectory();
2765 File systemDir = new File(dataDir, "system");
2767 mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2768 mBatteryStatsService.getActiveStatistics().readLocked();
2769 mBatteryStatsService.scheduleWriteToDisk();
2770 mOnBattery = DEBUG_POWER ? true
2771 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2772 mBatteryStatsService.getActiveStatistics().setCallback(this);
2774 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2776 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2777 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2778 new IAppOpsCallback.Stub() {
2779 @Override public void opChanged(int op, int uid, String packageName) {
2780 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2781 if (mAppOpsService.checkOperation(op, uid, packageName)
2782 != AppOpsManager.MODE_ALLOWED) {
2783 runInBackgroundDisabled(uid);
2789 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2791 mUserController = new UserController(this);
2793 mVrController = new VrController(this);
2795 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2796 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2798 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2799 mUseFifoUiScheduling = true;
2802 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2803 mTempConfig.setToDefaults();
2804 mTempConfig.setLocales(LocaleList.getDefault());
2805 mConfigurationSeq = mTempConfig.seq = 1;
2806 mStackSupervisor = createStackSupervisor();
2807 mStackSupervisor.onConfigurationChanged(mTempConfig);
2808 mKeyguardController = mStackSupervisor.mKeyguardController;
2809 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2810 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2811 mTaskChangeNotificationController =
2812 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2813 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2814 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2816 mProcessCpuThread = new Thread("CpuTracker") {
2819 synchronized (mProcessCpuTracker) {
2820 mProcessCpuInitLatch.countDown();
2821 mProcessCpuTracker.init();
2826 synchronized(this) {
2827 final long now = SystemClock.uptimeMillis();
2828 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2829 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2830 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2831 // + ", write delay=" + nextWriteDelay);
2832 if (nextWriteDelay < nextCpuDelay) {
2833 nextCpuDelay = nextWriteDelay;
2835 if (nextCpuDelay > 0) {
2836 mProcessCpuMutexFree.set(true);
2837 this.wait(nextCpuDelay);
2840 } catch (InterruptedException e) {
2842 updateCpuStatsNow();
2843 } catch (Exception e) {
2844 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2850 Watchdog.getInstance().addMonitor(this);
2851 Watchdog.getInstance().addThread(mHandler);
2854 protected ActivityStackSupervisor createStackSupervisor() {
2855 return new ActivityStackSupervisor(this, mHandler.getLooper());
2858 public void setSystemServiceManager(SystemServiceManager mgr) {
2859 mSystemServiceManager = mgr;
2862 public void setInstaller(Installer installer) {
2863 mInstaller = installer;
2866 private void start() {
2867 removeAllProcessGroups();
2868 mProcessCpuThread.start();
2870 mBatteryStatsService.publish();
2871 mAppOpsService.publish(mContext);
2872 Slog.d("AppOps", "AppOpsService published");
2873 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2874 // Wait for the synchronized block started in mProcessCpuThread,
2875 // so that any other acccess to mProcessCpuTracker from main thread
2876 // will be blocked during mProcessCpuTracker initialization.
2878 mProcessCpuInitLatch.await();
2879 } catch (InterruptedException e) {
2880 Slog.wtf(TAG, "Interrupted wait during start", e);
2881 Thread.currentThread().interrupt();
2882 throw new IllegalStateException("Interrupted wait during start");
2886 void onUserStoppedLocked(int userId) {
2887 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2890 public void initPowerManagement() {
2891 mStackSupervisor.initPowerManagement();
2892 mBatteryStatsService.initPowerManagement();
2893 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2894 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2895 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2896 mVoiceWakeLock.setReferenceCounted(false);
2899 private ArraySet<String> getBackgroundLaunchBroadcasts() {
2900 if (mBackgroundLaunchBroadcasts == null) {
2901 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2903 return mBackgroundLaunchBroadcasts;
2907 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2908 throws RemoteException {
2909 if (code == SYSPROPS_TRANSACTION) {
2910 // We need to tell all apps about the system property change.
2911 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2912 synchronized(this) {
2913 final int NP = mProcessNames.getMap().size();
2914 for (int ip=0; ip<NP; ip++) {
2915 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2916 final int NA = apps.size();
2917 for (int ia=0; ia<NA; ia++) {
2918 ProcessRecord app = apps.valueAt(ia);
2919 if (app.thread != null) {
2920 procs.add(app.thread.asBinder());
2926 int N = procs.size();
2927 for (int i=0; i<N; i++) {
2928 Parcel data2 = Parcel.obtain();
2930 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2931 Binder.FLAG_ONEWAY);
2932 } catch (RemoteException e) {
2938 return super.onTransact(code, data, reply, flags);
2939 } catch (RuntimeException e) {
2940 // The activity manager only throws security exceptions, so let's
2942 if (!(e instanceof SecurityException)) {
2943 Slog.wtf(TAG, "Activity Manager Crash."
2944 + " UID:" + Binder.getCallingUid()
2945 + " PID:" + Binder.getCallingPid()
2946 + " TRANS:" + code, e);
2952 void updateCpuStats() {
2953 final long now = SystemClock.uptimeMillis();
2954 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2957 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2958 synchronized (mProcessCpuThread) {
2959 mProcessCpuThread.notify();
2964 void updateCpuStatsNow() {
2965 synchronized (mProcessCpuTracker) {
2966 mProcessCpuMutexFree.set(false);
2967 final long now = SystemClock.uptimeMillis();
2968 boolean haveNewCpuStats = false;
2970 if (MONITOR_CPU_USAGE &&
2971 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2972 mLastCpuTime.set(now);
2973 mProcessCpuTracker.update();
2974 if (mProcessCpuTracker.hasGoodLastStats()) {
2975 haveNewCpuStats = true;
2976 //Slog.i(TAG, mProcessCpu.printCurrentState());
2977 //Slog.i(TAG, "Total CPU usage: "
2978 // + mProcessCpu.getTotalCpuPercent() + "%");
2980 // Slog the cpu usage if the property is set.
2981 if ("true".equals(SystemProperties.get("events.cpu"))) {
2982 int user = mProcessCpuTracker.getLastUserTime();
2983 int system = mProcessCpuTracker.getLastSystemTime();
2984 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2985 int irq = mProcessCpuTracker.getLastIrqTime();
2986 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2987 int idle = mProcessCpuTracker.getLastIdleTime();
2989 int total = user + system + iowait + irq + softIrq + idle;
2990 if (total == 0) total = 1;
2992 EventLog.writeEvent(EventLogTags.CPU,
2993 ((user+system+iowait+irq+softIrq) * 100) / total,
2994 (user * 100) / total,
2995 (system * 100) / total,
2996 (iowait * 100) / total,
2997 (irq * 100) / total,
2998 (softIrq * 100) / total);
3003 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3004 synchronized(bstats) {
3005 synchronized(mPidsSelfLocked) {
3006 if (haveNewCpuStats) {
3007 if (bstats.startAddingCpuLocked()) {
3010 final int N = mProcessCpuTracker.countStats();
3011 for (int i=0; i<N; i++) {
3012 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3016 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3017 totalUTime += st.rel_utime;
3018 totalSTime += st.rel_stime;
3020 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3021 if (ps == null || !ps.isActive()) {
3022 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3023 pr.info.uid, pr.processName);
3025 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3026 pr.curCpuTime += st.rel_utime + st.rel_stime;
3027 if (pr.lastCpuTime == 0) {
3028 pr.lastCpuTime = pr.curCpuTime;
3031 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3032 if (ps == null || !ps.isActive()) {
3033 st.batteryStats = ps = bstats.getProcessStatsLocked(
3034 bstats.mapUid(st.uid), st.name);
3036 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3039 final int userTime = mProcessCpuTracker.getLastUserTime();
3040 final int systemTime = mProcessCpuTracker.getLastSystemTime();
3041 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3042 final int irqTime = mProcessCpuTracker.getLastIrqTime();
3043 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3044 final int idleTime = mProcessCpuTracker.getLastIdleTime();
3045 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3046 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3051 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3052 mLastWriteTime = now;
3053 mBatteryStatsService.scheduleWriteToDisk();
3060 public void batteryNeedsCpuUpdate() {
3061 updateCpuStatsNow();
3065 public void batteryPowerChanged(boolean onBattery) {
3066 // When plugging in, update the CPU stats first before changing
3068 updateCpuStatsNow();
3069 synchronized (this) {
3070 synchronized(mPidsSelfLocked) {
3071 mOnBattery = DEBUG_POWER ? true : onBattery;
3077 public void batterySendBroadcast(Intent intent) {
3078 synchronized (this) {
3079 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3080 AppOpsManager.OP_NONE, null, false, false,
3081 -1, SYSTEM_UID, UserHandle.USER_ALL);
3086 * Initialize the application bind args. These are passed to each
3087 * process when the bindApplication() IPC is sent to the process. They're
3088 * lazily setup to make sure the services are running when they're asked for.
3090 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3091 // Isolated processes won't get this optimization, so that we don't
3092 // violate the rules about which services they have access to.
3094 if (mIsolatedAppBindArgs == null) {
3095 mIsolatedAppBindArgs = new HashMap<>();
3096 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3098 return mIsolatedAppBindArgs;
3101 if (mAppBindArgs == null) {
3102 mAppBindArgs = new HashMap<>();
3104 // Setup the application init args
3105 mAppBindArgs.put("package", ServiceManager.getService("package"));
3106 mAppBindArgs.put("window", ServiceManager.getService("window"));
3107 mAppBindArgs.put(Context.ALARM_SERVICE,
3108 ServiceManager.getService(Context.ALARM_SERVICE));
3110 return mAppBindArgs;
3114 * Update AMS states when an activity is resumed. This should only be called by
3115 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3117 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3118 final TaskRecord task = r.getTask();
3119 if (task.isApplicationTask()) {
3120 if (mCurAppTimeTracker != r.appTimeTracker) {
3121 // We are switching app tracking. Complete the current one.
3122 if (mCurAppTimeTracker != null) {
3123 mCurAppTimeTracker.stop();
3124 mHandler.obtainMessage(
3125 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3126 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3127 mCurAppTimeTracker = null;
3129 if (r.appTimeTracker != null) {
3130 mCurAppTimeTracker = r.appTimeTracker;
3131 startTimeTrackingFocusedActivityLocked();
3134 startTimeTrackingFocusedActivityLocked();
3137 r.appTimeTracker = null;
3139 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3140 // TODO: Probably not, because we don't want to resume voice on switching
3141 // back to this activity
3142 if (task.voiceInteractor != null) {
3143 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3145 finishRunningVoiceLocked();
3147 if (mLastResumedActivity != null) {
3148 final IVoiceInteractionSession session;
3150 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3151 if (lastResumedActivityTask != null
3152 && lastResumedActivityTask.voiceSession != null) {
3153 session = lastResumedActivityTask.voiceSession;
3155 session = mLastResumedActivity.voiceSession;
3158 if (session != null) {
3159 // We had been in a voice interaction session, but now focused has
3160 // move to something different. Just finish the session, we can't
3161 // return to it and retain the proper state and synchronization with
3162 // the voice interaction service.
3163 finishVoiceTask(session);
3168 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3169 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3170 mHandler.obtainMessage(
3171 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3173 mLastResumedActivity = r;
3175 mWindowManager.setFocusedApp(r.appToken, true);
3177 applyUpdateLockStateLocked(r);
3178 applyUpdateVrModeLocked(r);
3180 EventLogTags.writeAmSetResumedActivity(
3181 r == null ? -1 : r.userId,
3182 r == null ? "NULL" : r.shortComponentName,
3187 public void setFocusedStack(int stackId) {
3188 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3189 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3190 final long callingId = Binder.clearCallingIdentity();
3192 synchronized (this) {
3193 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3194 if (stack == null) {
3197 final ActivityRecord r = stack.topRunningActivityLocked();
3198 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3199 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3203 Binder.restoreCallingIdentity(callingId);
3208 public void setFocusedTask(int taskId) {
3209 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3210 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3211 final long callingId = Binder.clearCallingIdentity();
3213 synchronized (this) {
3214 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3218 final ActivityRecord r = task.topRunningActivityLocked();
3219 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3220 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3224 Binder.restoreCallingIdentity(callingId);
3228 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3230 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3231 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3232 mTaskChangeNotificationController.registerTaskStackListener(listener);
3236 * Unregister a task stack listener so that it stops receiving callbacks.
3239 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3240 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3241 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3245 public void notifyActivityDrawn(IBinder token) {
3246 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3247 synchronized (this) {
3248 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3250 r.getStack().notifyActivityDrawnLocked(r);
3255 final void applyUpdateLockStateLocked(ActivityRecord r) {
3256 // Modifications to the UpdateLock state are done on our handler, outside
3257 // the activity manager's locks. The new state is determined based on the
3258 // state *now* of the relevant activity record. The object is passed to
3259 // the handler solely for logging detail, not to be consulted/modified.
3260 final boolean nextState = r != null && r.immersive;
3261 mHandler.sendMessage(
3262 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3265 final void applyUpdateVrModeLocked(ActivityRecord r) {
3266 // VR apps are expected to run in a main display. If an app is turning on VR for
3267 // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3268 // fullscreen stack before enabling VR Mode.
3269 // TODO: The goal of this code is to keep the VR app on the main display. When the
3270 // stack implementation changes in the future, keep in mind that the use of the fullscreen
3271 // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3272 // option would be a better choice here.
3273 if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3274 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3275 + " to main stack for VR");
3276 moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3278 mHandler.sendMessage(
3279 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3282 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3283 Message msg = Message.obtain();
3284 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3285 msg.obj = r.getTask().askedCompatMode ? null : r;
3286 mUiHandler.sendMessage(msg);
3289 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3290 final Configuration globalConfig = getGlobalConfiguration();
3291 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3292 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3293 final Message msg = Message.obtain();
3294 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3296 mUiHandler.sendMessage(msg);
3300 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3301 String what, Object obj, ProcessRecord srcApp) {
3302 app.lastActivityTime = now;
3304 if (app.activities.size() > 0) {
3305 // Don't want to touch dependent processes that are hosting activities.
3309 int lrui = mLruProcesses.lastIndexOf(app);
3311 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3312 + what + " " + obj + " from " + srcApp);
3316 if (lrui >= index) {
3317 // Don't want to cause this to move dependent processes *back* in the
3318 // list as if they were less frequently used.
3322 if (lrui >= mLruProcessActivityStart) {
3323 // Don't want to touch dependent processes that are hosting activities.
3327 mLruProcesses.remove(lrui);
3331 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3332 + " in LRU list: " + app);
3333 mLruProcesses.add(index, app);
3337 static void killProcessGroup(int uid, int pid) {
3338 if (sKillHandler != null) {
3339 sKillHandler.sendMessage(
3340 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3342 Slog.w(TAG, "Asked to kill process group before system bringup!");
3343 Process.killProcessGroup(uid, pid);
3347 final void removeLruProcessLocked(ProcessRecord app) {
3348 int lrui = mLruProcesses.lastIndexOf(app);
3351 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3352 killProcessQuiet(app.pid);
3353 killProcessGroup(app.uid, app.pid);
3355 if (lrui <= mLruProcessActivityStart) {
3356 mLruProcessActivityStart--;
3358 if (lrui <= mLruProcessServiceStart) {
3359 mLruProcessServiceStart--;
3361 mLruProcesses.remove(lrui);
3365 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3366 ProcessRecord client) {
3367 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3368 || app.treatLikeActivity;
3369 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3370 if (!activityChange && hasActivity) {
3371 // The process has activities, so we are only allowing activity-based adjustments
3372 // to move it. It should be kept in the front of the list with other
3373 // processes that have activities, and we don't want those to change their
3374 // order except due to activity operations.
3379 final long now = SystemClock.uptimeMillis();
3380 app.lastActivityTime = now;
3382 // First a quick reject: if the app is already at the position we will
3383 // put it, then there is nothing to do.
3385 final int N = mLruProcesses.size();
3386 if (N > 0 && mLruProcesses.get(N-1) == app) {
3387 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3391 if (mLruProcessServiceStart > 0
3392 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3393 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3398 int lrui = mLruProcesses.lastIndexOf(app);
3400 if (app.persistent && lrui >= 0) {
3401 // We don't care about the position of persistent processes, as long as
3402 // they are in the list.
3403 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3407 /* In progress: compute new position first, so we can avoid doing work
3408 if the process is not actually going to move. Not yet working.
3411 boolean inActivity = false, inService = false;
3413 // Process has activities, put it at the very tipsy-top.
3414 addIndex = mLruProcesses.size();
3415 nextIndex = mLruProcessServiceStart;
3417 } else if (hasService) {
3418 // Process has services, put it at the top of the service list.
3419 addIndex = mLruProcessActivityStart;
3420 nextIndex = mLruProcessServiceStart;
3424 // Process not otherwise of interest, it goes to the top of the non-service area.
3425 addIndex = mLruProcessServiceStart;
3426 if (client != null) {
3427 int clientIndex = mLruProcesses.lastIndexOf(client);
3428 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3430 if (clientIndex >= 0 && addIndex > clientIndex) {
3431 addIndex = clientIndex;
3434 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3437 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3438 + mLruProcessActivityStart + "): " + app);
3442 if (lrui < mLruProcessActivityStart) {
3443 mLruProcessActivityStart--;
3445 if (lrui < mLruProcessServiceStart) {
3446 mLruProcessServiceStart--;
3449 if (addIndex > lrui) {
3452 if (nextIndex > lrui) {
3456 mLruProcesses.remove(lrui);
3460 mLruProcesses.add(addIndex, app);
3462 mLruProcessActivityStart++;
3465 mLruProcessActivityStart++;
3471 final int N = mLruProcesses.size();
3472 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3473 // Process doesn't have activities, but has clients with
3474 // activities... move it up, but one below the top (the top
3475 // should always have a real activity).
3476 if (DEBUG_LRU) Slog.d(TAG_LRU,
3477 "Adding to second-top of LRU activity list: " + app);
3478 mLruProcesses.add(N - 1, app);
3479 // To keep it from spamming the LRU list (by making a bunch of clients),
3480 // we will push down any other entries owned by the app.
3481 final int uid = app.info.uid;
3482 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3483 ProcessRecord subProc = mLruProcesses.get(i);
3484 if (subProc.info.uid == uid) {
3485 // We want to push this one down the list. If the process after
3486 // it is for the same uid, however, don't do so, because we don't
3487 // want them internally to be re-ordered.
3488 if (mLruProcesses.get(i - 1).info.uid != uid) {
3489 if (DEBUG_LRU) Slog.d(TAG_LRU,
3490 "Pushing uid " + uid + " swapping at " + i + ": "
3491 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3492 ProcessRecord tmp = mLruProcesses.get(i);
3493 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3494 mLruProcesses.set(i - 1, tmp);
3498 // A gap, we can stop here.
3503 // Process has activities, put it at the very tipsy-top.
3504 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3505 mLruProcesses.add(app);
3507 nextIndex = mLruProcessServiceStart;
3508 } else if (hasService) {
3509 // Process has services, put it at the top of the service list.
3510 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3511 mLruProcesses.add(mLruProcessActivityStart, app);
3512 nextIndex = mLruProcessServiceStart;
3513 mLruProcessActivityStart++;
3515 // Process not otherwise of interest, it goes to the top of the non-service area.
3516 int index = mLruProcessServiceStart;
3517 if (client != null) {
3518 // If there is a client, don't allow the process to be moved up higher
3519 // in the list than that client.
3520 int clientIndex = mLruProcesses.lastIndexOf(client);
3521 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3522 + " when updating " + app);
3523 if (clientIndex <= lrui) {
3524 // Don't allow the client index restriction to push it down farther in the
3525 // list than it already is.
3528 if (clientIndex >= 0 && index > clientIndex) {
3529 index = clientIndex;
3532 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3533 mLruProcesses.add(index, app);
3534 nextIndex = index-1;
3535 mLruProcessActivityStart++;
3536 mLruProcessServiceStart++;
3539 // If the app is currently using a content provider or service,
3540 // bump those processes as well.
3541 for (int j=app.connections.size()-1; j>=0; j--) {
3542 ConnectionRecord cr = app.connections.valueAt(j);
3543 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3544 && cr.binding.service.app != null
3545 && cr.binding.service.app.lruSeq != mLruSeq
3546 && !cr.binding.service.app.persistent) {
3547 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3548 "service connection", cr, app);
3551 for (int j=app.conProviders.size()-1; j>=0; j--) {
3552 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3553 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3554 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3555 "provider reference", cpr, app);
3560 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3561 if (uid == SYSTEM_UID) {
3562 // The system gets to run in any process. If there are multiple
3563 // processes with the same uid, just pick the first (this
3564 // should never happen).
3565 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3566 if (procs == null) return null;
3567 final int procCount = procs.size();
3568 for (int i = 0; i < procCount; i++) {
3569 final int procUid = procs.keyAt(i);
3570 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3571 // Don't use an app process or different user process for system component.
3574 return procs.valueAt(i);
3577 ProcessRecord proc = mProcessNames.get(processName, uid);
3578 if (false && proc != null && !keepIfLarge
3579 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3580 && proc.lastCachedPss >= 4000) {
3581 // Turn this condition on to cause killing to happen regularly, for testing.
3582 if (proc.baseProcessTracker != null) {
3583 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3585 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3586 } else if (proc != null && !keepIfLarge
3587 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3588 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3589 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3590 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3591 if (proc.baseProcessTracker != null) {
3592 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3594 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3600 void notifyPackageUse(String packageName, int reason) {
3601 synchronized(this) {
3602 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3606 boolean isNextTransitionForward() {
3607 int transit = mWindowManager.getPendingAppTransition();
3608 return transit == TRANSIT_ACTIVITY_OPEN
3609 || transit == TRANSIT_TASK_OPEN
3610 || transit == TRANSIT_TASK_TO_FRONT;
3613 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3614 String processName, String abiOverride, int uid, Runnable crashHandler) {
3615 synchronized(this) {
3616 ApplicationInfo info = new ApplicationInfo();
3617 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3618 // For isolated processes, the former contains the parent's uid and the latter the
3619 // actual uid of the isolated process.
3620 // In the special case introduced by this method (which is, starting an isolated
3621 // process directly from the SystemServer without an actual parent app process) the
3622 // closest thing to a parent's uid is SYSTEM_UID.
3623 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3624 // the |isolated| logic in the ProcessRecord constructor.
3625 info.uid = SYSTEM_UID;
3626 info.processName = processName;
3627 info.className = entryPoint;
3628 info.packageName = "android";
3629 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3630 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3631 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3632 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3633 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3635 return proc != null ? proc.pid : 0;
3639 final ProcessRecord startProcessLocked(String processName,
3640 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3641 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3642 boolean isolated, boolean keepIfLarge) {
3643 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3644 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3645 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3646 null /* crashHandler */);
3649 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3650 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3651 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3652 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3653 long startTime = SystemClock.elapsedRealtime();
3656 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3657 checkTime(startTime, "startProcess: after getProcessRecord");
3659 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3660 // If we are in the background, then check to see if this process
3661 // is bad. If so, we will just silently fail.
3662 if (mAppErrors.isBadProcessLocked(info)) {
3663 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3664 + "/" + info.processName);
3668 // When the user is explicitly starting a process, then clear its
3669 // crash count so that we won't make it bad until they see at
3670 // least one crash dialog again, and make the process good again
3671 // if it had been bad.
3672 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3673 + "/" + info.processName);
3674 mAppErrors.resetProcessCrashTimeLocked(info);
3675 if (mAppErrors.isBadProcessLocked(info)) {
3676 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3677 UserHandle.getUserId(info.uid), info.uid,
3679 mAppErrors.clearBadProcessLocked(info);
3686 // If this is an isolated process, it can't re-use an existing process.
3690 // We don't have to do anything more if:
3691 // (1) There is an existing application record; and
3692 // (2) The caller doesn't think it is dead, OR there is no thread
3693 // object attached to it so we know it couldn't have crashed; and
3694 // (3) There is a pid assigned to it, so it is either starting or
3696 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3697 + " app=" + app + " knownToBeDead=" + knownToBeDead
3698 + " thread=" + (app != null ? app.thread : null)
3699 + " pid=" + (app != null ? app.pid : -1));
3700 if (app != null && app.pid > 0) {
3701 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3702 // We already have the app running, or are waiting for it to
3703 // come up (we have a pid but not yet its thread), so keep it.
3704 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3705 // If this is a new package in the process, add the package to the list
3706 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3707 checkTime(startTime, "startProcess: done, added package to proc");
3711 // An application record is attached to a previous process,
3713 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3714 checkTime(startTime, "startProcess: bad proc running, killing");
3715 killProcessGroup(app.uid, app.pid);
3716 handleAppDiedLocked(app, true, true);
3717 checkTime(startTime, "startProcess: done killing old proc");
3720 String hostingNameStr = hostingName != null
3721 ? hostingName.flattenToShortString() : null;
3724 checkTime(startTime, "startProcess: creating new process record");
3725 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3727 Slog.w(TAG, "Failed making new process record for "
3728 + processName + "/" + info.uid + " isolated=" + isolated);
3731 app.crashHandler = crashHandler;
3732 checkTime(startTime, "startProcess: done creating new process record");
3734 // If this is a new package in the process, add the package to the list
3735 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3736 checkTime(startTime, "startProcess: added package to existing proc");
3739 // If the system is not ready yet, then hold off on starting this
3740 // process until it is.
3741 if (!mProcessesReady
3742 && !isAllowedWhileBooting(info)
3743 && !allowWhileBooting) {
3744 if (!mProcessesOnHold.contains(app)) {
3745 mProcessesOnHold.add(app);
3747 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3748 "System not ready, putting on hold: " + app);
3749 checkTime(startTime, "startProcess: returning with proc on hold");
3753 checkTime(startTime, "startProcess: stepping in to startProcess");
3755 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3756 checkTime(startTime, "startProcess: done starting proc!");
3757 return (app.pid != 0) ? app : null;
3760 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3761 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3764 private final void startProcessLocked(ProcessRecord app,
3765 String hostingType, String hostingNameStr) {
3766 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3767 null /* entryPoint */, null /* entryPointArgs */);
3770 private final void startProcessLocked(ProcessRecord app, String hostingType,
3771 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3772 long startTime = SystemClock.elapsedRealtime();
3773 if (app.pid > 0 && app.pid != MY_PID) {
3774 checkTime(startTime, "startProcess: removing from pids map");
3775 synchronized (mPidsSelfLocked) {
3776 mPidsSelfLocked.remove(app.pid);
3777 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3779 checkTime(startTime, "startProcess: done removing from pids map");
3783 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3784 "startProcessLocked removing on hold: " + app);
3785 mProcessesOnHold.remove(app);
3787 checkTime(startTime, "startProcess: starting to update cpu stats");
3789 checkTime(startTime, "startProcess: done updating cpu stats");
3793 final int userId = UserHandle.getUserId(app.uid);
3794 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3795 } catch (RemoteException e) {
3796 throw e.rethrowAsRuntimeException();
3801 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3802 if (!app.isolated) {
3803 int[] permGids = null;
3805 checkTime(startTime, "startProcess: getting gids from package manager");
3806 final IPackageManager pm = AppGlobals.getPackageManager();
3807 permGids = pm.getPackageGids(app.info.packageName,
3808 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3809 StorageManagerInternal storageManagerInternal = LocalServices.getService(
3810 StorageManagerInternal.class);
3811 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3812 app.info.packageName);
3813 } catch (RemoteException e) {
3814 throw e.rethrowAsRuntimeException();
3818 * Add shared application and profile GIDs so applications can share some
3819 * resources like shared libraries and access user-wide resources
3821 if (ArrayUtils.isEmpty(permGids)) {
3824 gids = new int[permGids.length + 3];
3825 System.arraycopy(permGids, 0, gids, 3, permGids.length);
3827 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3828 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3829 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3831 // Replace any invalid GIDs
3832 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
3833 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
3835 checkTime(startTime, "startProcess: building args");
3836 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3837 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3838 && mTopComponent != null
3839 && app.processName.equals(mTopComponent.getPackageName())) {
3842 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3843 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3847 int runtimeFlags = 0;
3848 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3849 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3850 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3851 // Also turn on CheckJNI for debuggable apps. It's quite
3852 // awkward to turn on otherwise.
3853 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3855 // Run the app in safe mode if its manifest requests so or the
3856 // system is booted in safe mode.
3857 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3858 mSafeMode == true) {
3859 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3861 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3862 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3864 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3865 if ("true".equals(genDebugInfoProperty)) {
3866 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3868 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3869 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3871 if ("1".equals(SystemProperties.get("debug.assert"))) {
3872 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3874 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3875 // Enable all debug flags required by the native debugger.
3876 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3877 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3878 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3879 mNativeDebuggingApp = null;
3882 if (app.info.isPrivilegedApp() &&
3883 !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
3884 runtimeFlags |= Zygote.DISABLE_VERIFIER;
3885 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
3888 if (app.info.isAllowedToUseHiddenApi()) {
3889 // This app is allowed to use undocumented and private APIs. Set
3890 // up its runtime with the appropriate flag.
3891 runtimeFlags |= Zygote.DISABLE_HIDDEN_API_CHECKS;
3894 String invokeWith = null;
3895 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3896 // Debuggable apps may include a wrapper script with their library directory.
3897 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3898 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3900 if (new File(wrapperFileName).exists()) {
3901 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3904 StrictMode.setThreadPolicy(oldPolicy);
3908 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3909 if (requiredAbi == null) {
3910 requiredAbi = Build.SUPPORTED_ABIS[0];
3913 String instructionSet = null;
3914 if (app.info.primaryCpuAbi != null) {
3915 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3919 app.requiredAbi = requiredAbi;
3920 app.instructionSet = instructionSet;
3922 // the per-user SELinux context must be set
3923 if (TextUtils.isEmpty(app.info.seInfoUser)) {
3924 Slog.wtf(TAG, "SELinux tag not defined",
3925 new IllegalStateException("SELinux tag not defined for "
3926 + app.info.packageName + " (uid " + app.uid + ")"));
3928 final String seInfo = app.info.seInfo
3929 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3930 // Start the process. It will either succeed and return a result containing
3931 // the PID of the new process, or else throw a RuntimeException.
3932 boolean isActivityProcess = (entryPoint == null);
3933 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3934 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3936 checkTime(startTime, "startProcess: asking zygote to start proc");
3937 ProcessStartResult startResult;
3938 if (hostingType.equals("webview_service")) {
3939 startResult = startWebView(entryPoint,
3940 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3941 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3942 app.info.dataDir, null, entryPointArgs);
3944 startResult = Process.start(entryPoint,
3945 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3946 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3947 app.info.dataDir, invokeWith, entryPointArgs);
3949 checkTime(startTime, "startProcess: returned from zygote!");
3950 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3952 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3953 checkTime(startTime, "startProcess: done updating battery stats");
3955 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3956 UserHandle.getUserId(uid), startResult.pid, uid,
3957 app.processName, hostingType,
3958 hostingNameStr != null ? hostingNameStr : "");
3961 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3962 seInfo, app.info.sourceDir, startResult.pid);
3963 } catch (RemoteException ex) {
3967 if (app.persistent) {
3968 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3971 checkTime(startTime, "startProcess: building log message");
3972 StringBuilder buf = mStringBuilder;
3974 buf.append("Start proc ");
3975 buf.append(startResult.pid);
3977 buf.append(app.processName);
3979 UserHandle.formatUid(buf, uid);
3980 if (!isActivityProcess) {
3982 buf.append(entryPoint);
3985 buf.append(" for ");
3986 buf.append(hostingType);
3987 if (hostingNameStr != null) {
3989 buf.append(hostingNameStr);
3991 Slog.i(TAG, buf.toString());
3992 app.setPid(startResult.pid);
3993 app.usingWrapper = startResult.usingWrapper;
3994 app.removed = false;
3996 app.killedByAm = false;
3997 checkTime(startTime, "startProcess: starting to update pids map");
3998 ProcessRecord oldApp;
3999 synchronized (mPidsSelfLocked) {
4000 oldApp = mPidsSelfLocked.get(startResult.pid);
4002 // If there is already an app occupying that pid that hasn't been cleaned up
4003 if (oldApp != null && !app.isolated) {
4004 // Clean up anything relating to this pid first
4005 Slog.w(TAG, "Reusing pid " + startResult.pid
4006 + " while app is still mapped to it");
4007 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4008 true /*replacingPid*/);
4010 synchronized (mPidsSelfLocked) {
4011 this.mPidsSelfLocked.put(startResult.pid, app);
4012 if (isActivityProcess) {
4013 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4015 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4016 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4019 checkTime(startTime, "startProcess: done updating pids map");
4020 } catch (RuntimeException e) {
4021 Slog.e(TAG, "Failure starting process " + app.processName, e);
4023 // Something went very wrong while trying to start this process; one
4024 // common case is when the package is frozen due to an active
4025 // upgrade. To recover, clean up any active bookkeeping related to
4026 // starting this process. (We already invoked this method once when
4027 // the package was initially frozen through KILL_APPLICATION_MSG, so
4028 // it doesn't hurt to use it again.)
4029 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4030 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4034 void updateUsageStats(ActivityRecord component, boolean resumed) {
4035 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4036 "updateUsageStats: comp=" + component + "res=" + resumed);
4037 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4039 if (mUsageStatsService != null) {
4040 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4041 UsageEvents.Event.MOVE_TO_FOREGROUND);
4043 synchronized (stats) {
4044 stats.noteActivityResumedLocked(component.app.uid);
4047 if (mUsageStatsService != null) {
4048 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4049 UsageEvents.Event.MOVE_TO_BACKGROUND);
4051 synchronized (stats) {
4052 stats.noteActivityPausedLocked(component.app.uid);
4057 Intent getHomeIntent() {
4058 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4059 intent.setComponent(mTopComponent);
4060 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4061 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4062 intent.addCategory(Intent.CATEGORY_HOME);
4067 boolean startHomeActivityLocked(int userId, String reason) {
4068 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4069 && mTopAction == null) {
4070 // We are running in factory test mode, but unable to find
4071 // the factory test app, so just sit around displaying the
4072 // error message and don't try to start anything.
4075 Intent intent = getHomeIntent();
4076 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4077 if (aInfo != null) {
4078 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4079 // Don't do this if the home app is currently being
4081 aInfo = new ActivityInfo(aInfo);
4082 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4083 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4084 aInfo.applicationInfo.uid, true);
4085 if (app == null || app.instr == null) {
4086 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4087 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4088 // For ANR debugging to verify if the user activity is the one that actually
4090 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4091 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4094 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4100 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4101 ActivityInfo ai = null;
4102 ComponentName comp = intent.getComponent();
4106 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4108 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4110 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4114 ai = info.activityInfo;
4117 } catch (RemoteException e) {
4125 * Starts the "new version setup screen" if appropriate.
4127 void startSetupActivityLocked() {
4128 // Only do this once per boot.
4129 if (mCheckedForSetup) {
4133 // We will show this screen if the current one is a different
4134 // version than the last one shown, and we are not running in
4135 // low-level factory test mode.
4136 final ContentResolver resolver = mContext.getContentResolver();
4137 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4138 Settings.Global.getInt(resolver,
4139 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4140 mCheckedForSetup = true;
4142 // See if we should be showing the platform update setup UI.
4143 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4144 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4145 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4146 if (!ris.isEmpty()) {
4147 final ResolveInfo ri = ris.get(0);
4148 String vers = ri.activityInfo.metaData != null
4149 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4151 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4152 vers = ri.activityInfo.applicationInfo.metaData.getString(
4153 Intent.METADATA_SETUP_VERSION);
4155 String lastVers = Settings.Secure.getString(
4156 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4157 if (vers != null && !vers.equals(lastVers)) {
4158 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4159 intent.setComponent(new ComponentName(
4160 ri.activityInfo.packageName, ri.activityInfo.name));
4161 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4162 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4163 null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4169 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4170 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4173 void enforceNotIsolatedCaller(String caller) {
4174 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4175 throw new SecurityException("Isolated process not allowed to call " + caller);
4179 void enforceShellRestriction(String restriction, int userHandle) {
4180 if (Binder.getCallingUid() == SHELL_UID) {
4181 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4182 throw new SecurityException("Shell does not have permission to access user "
4189 public int getFrontActivityScreenCompatMode() {
4190 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4191 synchronized (this) {
4192 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4197 public void setFrontActivityScreenCompatMode(int mode) {
4198 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4199 "setFrontActivityScreenCompatMode");
4200 synchronized (this) {
4201 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4206 public int getPackageScreenCompatMode(String packageName) {
4207 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4208 synchronized (this) {
4209 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4214 public void setPackageScreenCompatMode(String packageName, int mode) {
4215 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4216 "setPackageScreenCompatMode");
4217 synchronized (this) {
4218 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4223 public boolean getPackageAskScreenCompat(String packageName) {
4224 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4225 synchronized (this) {
4226 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4231 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4232 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4233 "setPackageAskScreenCompat");
4234 synchronized (this) {
4235 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4239 private boolean hasUsageStatsPermission(String callingPackage) {
4240 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4241 Binder.getCallingUid(), callingPackage);
4242 if (mode == AppOpsManager.MODE_DEFAULT) {
4243 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4244 == PackageManager.PERMISSION_GRANTED;
4246 return mode == AppOpsManager.MODE_ALLOWED;
4250 public int getPackageProcessState(String packageName, String callingPackage) {
4251 if (!hasUsageStatsPermission(callingPackage)) {
4252 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4253 "getPackageProcessState");
4256 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4257 synchronized (this) {
4258 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4259 final ProcessRecord proc = mLruProcesses.get(i);
4260 if (procState > proc.setProcState) {
4261 if (proc.pkgList.containsKey(packageName) ||
4262 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4263 procState = proc.setProcState;
4272 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4273 throws RemoteException {
4274 synchronized (this) {
4275 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4277 throw new IllegalArgumentException("Unknown process: " + process);
4279 if (app.thread == null) {
4280 throw new IllegalArgumentException("Process has no app thread");
4282 if (app.trimMemoryLevel >= level) {
4283 throw new IllegalArgumentException(
4284 "Unable to set a higher trim level than current level");
4286 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4287 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4288 throw new IllegalArgumentException("Unable to set a background trim level "
4289 + "on a foreground process");
4291 app.thread.scheduleTrimMemory(level);
4292 app.trimMemoryLevel = level;
4297 private void dispatchProcessesChanged() {
4299 synchronized (this) {
4300 N = mPendingProcessChanges.size();
4301 if (mActiveProcessChanges.length < N) {
4302 mActiveProcessChanges = new ProcessChangeItem[N];
4304 mPendingProcessChanges.toArray(mActiveProcessChanges);
4305 mPendingProcessChanges.clear();
4306 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4307 "*** Delivering " + N + " process changes");
4310 int i = mProcessObservers.beginBroadcast();
4313 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4314 if (observer != null) {
4316 for (int j=0; j<N; j++) {
4317 ProcessChangeItem item = mActiveProcessChanges[j];
4318 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4319 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4320 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4321 + item.uid + ": " + item.foregroundActivities);
4322 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4323 item.foregroundActivities);
4326 } catch (RemoteException e) {
4330 mProcessObservers.finishBroadcast();
4332 synchronized (this) {
4333 for (int j=0; j<N; j++) {
4334 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4339 private void dispatchProcessDied(int pid, int uid) {
4340 int i = mProcessObservers.beginBroadcast();
4343 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4344 if (observer != null) {
4346 observer.onProcessDied(pid, uid);
4347 } catch (RemoteException e) {
4351 mProcessObservers.finishBroadcast();
4355 void dispatchUidsChanged() {
4357 synchronized (this) {
4358 N = mPendingUidChanges.size();
4359 if (mActiveUidChanges.length < N) {
4360 mActiveUidChanges = new UidRecord.ChangeItem[N];
4362 for (int i=0; i<N; i++) {
4363 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4364 mActiveUidChanges[i] = change;
4365 if (change.uidRecord != null) {
4366 change.uidRecord.pendingChange = null;
4367 change.uidRecord = null;
4370 mPendingUidChanges.clear();
4371 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4372 "*** Delivering " + N + " uid changes");
4375 int i = mUidObservers.beginBroadcast();
4378 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4379 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4381 mUidObservers.finishBroadcast();
4383 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4384 for (int j = 0; j < N; ++j) {
4385 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4386 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4387 mValidateUids.remove(item.uid);
4389 UidRecord validateUid = mValidateUids.get(item.uid);
4390 if (validateUid == null) {
4391 validateUid = new UidRecord(item.uid);
4392 mValidateUids.put(item.uid, validateUid);
4394 if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4395 validateUid.idle = true;
4396 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4397 validateUid.idle = false;
4399 validateUid.curProcState = validateUid.setProcState = item.processState;
4400 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4405 synchronized (this) {
4406 for (int j = 0; j < N; j++) {
4407 mAvailUidChanges.add(mActiveUidChanges[j]);
4412 private void dispatchUidsChangedForObserver(IUidObserver observer,
4413 UidObserverRegistration reg, int changesSize) {
4414 if (observer == null) {
4418 for (int j = 0; j < changesSize; j++) {
4419 UidRecord.ChangeItem item = mActiveUidChanges[j];
4420 final int change = item.change;
4421 if (change == UidRecord.CHANGE_PROCSTATE &&
4422 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4423 // No-op common case: no significant change, the observer is not
4424 // interested in all proc state changes.
4427 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4428 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4429 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4430 "UID idle uid=" + item.uid);
4431 observer.onUidIdle(item.uid, item.ephemeral);
4433 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4434 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4435 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4436 "UID active uid=" + item.uid);
4437 observer.onUidActive(item.uid);
4440 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4441 if ((change & UidRecord.CHANGE_CACHED) != 0) {
4442 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4443 "UID cached uid=" + item.uid);
4444 observer.onUidCachedChanged(item.uid, true);
4445 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4446 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4447 "UID active uid=" + item.uid);
4448 observer.onUidCachedChanged(item.uid, false);
4451 if ((change & UidRecord.CHANGE_GONE) != 0) {
4452 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4453 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4454 "UID gone uid=" + item.uid);
4455 observer.onUidGone(item.uid, item.ephemeral);
4457 if (reg.lastProcStates != null) {
4458 reg.lastProcStates.delete(item.uid);
4461 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4462 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4463 "UID CHANGED uid=" + item.uid
4464 + ": " + item.processState);
4465 boolean doReport = true;
4466 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4467 final int lastState = reg.lastProcStates.get(item.uid,
4468 ActivityManager.PROCESS_STATE_UNKNOWN);
4469 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4470 final boolean lastAboveCut = lastState <= reg.cutpoint;
4471 final boolean newAboveCut = item.processState <= reg.cutpoint;
4472 doReport = lastAboveCut != newAboveCut;
4474 doReport = item.processState
4475 != ActivityManager.PROCESS_STATE_NONEXISTENT;
4479 if (reg.lastProcStates != null) {
4480 reg.lastProcStates.put(item.uid, item.processState);
4482 observer.onUidStateChanged(item.uid, item.processState,
4488 } catch (RemoteException e) {
4492 void dispatchOomAdjObserver(String msg) {
4493 OomAdjObserver observer;
4494 synchronized (this) {
4495 observer = mCurOomAdjObserver;
4498 if (observer != null) {
4499 observer.onOomAdjMessage(msg);
4503 void setOomAdjObserver(int uid, OomAdjObserver observer) {
4504 synchronized (this) {
4505 mCurOomAdjUid = uid;
4506 mCurOomAdjObserver = observer;
4510 void clearOomAdjObserver() {
4511 synchronized (this) {
4513 mCurOomAdjObserver = null;
4517 void reportOomAdjMessageLocked(String tag, String msg) {
4519 if (mCurOomAdjObserver != null) {
4520 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4525 public final int startActivity(IApplicationThread caller, String callingPackage,
4526 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4527 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4528 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4529 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4530 UserHandle.getCallingUserId());
4534 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4535 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4536 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4537 enforceNotIsolatedCaller("startActivity");
4538 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4539 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4540 // TODO: Switch to user app stacks here.
4541 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4542 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4543 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4547 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4548 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4549 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4552 // This is very dangerous -- it allows you to perform a start activity (including
4553 // permission grants) as any app that may launch one of your own activities. So
4554 // we will only allow this to be done from activities that are part of the core framework,
4555 // and then only when they are running as the system.
4556 final ActivityRecord sourceRecord;
4557 final int targetUid;
4558 final String targetPackage;
4559 synchronized (this) {
4560 if (resultTo == null) {
4561 throw new SecurityException("Must be called from an activity");
4563 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4564 if (sourceRecord == null) {
4565 throw new SecurityException("Called with bad activity token: " + resultTo);
4567 if (!sourceRecord.info.packageName.equals("android")) {
4568 throw new SecurityException(
4569 "Must be called from an activity that is declared in the android package");
4571 if (sourceRecord.app == null) {
4572 throw new SecurityException("Called without a process attached to activity");
4574 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4575 // This is still okay, as long as this activity is running under the
4576 // uid of the original calling activity.
4577 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4578 throw new SecurityException(
4579 "Calling activity in uid " + sourceRecord.app.uid
4580 + " must be system uid or original calling uid "
4581 + sourceRecord.launchedFromUid);
4584 if (ignoreTargetSecurity) {
4585 if (intent.getComponent() == null) {
4586 throw new SecurityException(
4587 "Component must be specified with ignoreTargetSecurity");
4589 if (intent.getSelector() != null) {
4590 throw new SecurityException(
4591 "Selector not allowed with ignoreTargetSecurity");
4594 targetUid = sourceRecord.launchedFromUid;
4595 targetPackage = sourceRecord.launchedFromPackage;
4598 if (userId == UserHandle.USER_NULL) {
4599 userId = UserHandle.getUserId(sourceRecord.app.uid);
4602 // TODO: Switch to user app stacks here.
4604 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4605 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4606 null, null, bOptions, ignoreTargetSecurity, userId, null,
4607 "startActivityAsCaller");
4609 } catch (SecurityException e) {
4610 // XXX need to figure out how to propagate to original app.
4611 // A SecurityException here is generally actually a fault of the original
4612 // calling activity (such as a fairly granting permissions), so propagate it
4615 StringBuilder msg = new StringBuilder();
4616 msg.append("While launching");
4617 msg.append(intent.toString());
4619 msg.append(e.getMessage());
4626 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4627 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4628 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4629 enforceNotIsolatedCaller("startActivityAndWait");
4630 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4631 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4632 WaitResult res = new WaitResult();
4633 // TODO: Switch to user app stacks here.
4634 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4635 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4636 bOptions, false, userId, null, "startActivityAndWait");
4641 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4642 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4643 int startFlags, Configuration config, Bundle bOptions, int userId) {
4644 enforceNotIsolatedCaller("startActivityWithConfig");
4645 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4646 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4647 // TODO: Switch to user app stacks here.
4648 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4649 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4650 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4655 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4656 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4657 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4658 throws TransactionTooLargeException {
4659 enforceNotIsolatedCaller("startActivityIntentSender");
4660 // Refuse possible leaked file descriptors
4661 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4662 throw new IllegalArgumentException("File descriptors passed in Intent");
4665 if (!(target instanceof PendingIntentRecord)) {
4666 throw new IllegalArgumentException("Bad PendingIntent object");
4669 PendingIntentRecord pir = (PendingIntentRecord)target;
4671 synchronized (this) {
4672 // If this is coming from the currently resumed activity, it is
4673 // effectively saying that app switches are allowed at this point.
4674 final ActivityStack stack = getFocusedStack();
4675 if (stack.mResumedActivity != null &&
4676 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4677 mAppSwitchesAllowedTime = 0;
4680 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4681 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4686 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4687 Intent intent, String resolvedType, IVoiceInteractionSession session,
4688 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4689 Bundle bOptions, int userId) {
4690 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4691 != PackageManager.PERMISSION_GRANTED) {
4692 String msg = "Permission Denial: startVoiceActivity() from pid="
4693 + Binder.getCallingPid()
4694 + ", uid=" + Binder.getCallingUid()
4695 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4697 throw new SecurityException(msg);
4699 if (session == null || interactor == null) {
4700 throw new NullPointerException("null session or interactor");
4702 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4703 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4704 // TODO: Switch to user app stacks here.
4705 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4706 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4707 null, bOptions, false, userId, null, "startVoiceActivity");
4711 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4712 Intent intent, String resolvedType, Bundle bOptions, int userId) {
4713 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4714 != PackageManager.PERMISSION_GRANTED) {
4715 final String msg = "Permission Denial: startAssistantActivity() from pid="
4716 + Binder.getCallingPid()
4717 + ", uid=" + Binder.getCallingUid()
4718 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4720 throw new SecurityException(msg);
4722 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4723 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4724 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4725 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4726 userId, null, "startAssistantActivity");
4730 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4731 throws RemoteException {
4732 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4733 synchronized (this) {
4734 ActivityRecord activity = getFocusedStack().topActivity();
4735 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4736 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4738 if (mRunningVoice != null || activity.getTask().voiceSession != null
4739 || activity.voiceSession != null) {
4740 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4743 if (activity.pendingVoiceInteractionStart) {
4744 Slog.w(TAG, "Pending start of voice interaction already.");
4747 activity.pendingVoiceInteractionStart = true;
4749 LocalServices.getService(VoiceInteractionManagerInternal.class)
4750 .startLocalVoiceInteraction(callingActivity, options);
4754 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4755 LocalServices.getService(VoiceInteractionManagerInternal.class)
4756 .stopLocalVoiceInteraction(callingActivity);
4760 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4761 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4762 .supportsLocalVoiceInteraction();
4765 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4766 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4767 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4768 if (activityToCallback == null) return;
4769 activityToCallback.setVoiceSessionLocked(voiceSession);
4771 // Inform the activity
4773 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4775 long token = Binder.clearCallingIdentity();
4777 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4779 Binder.restoreCallingIdentity(token);
4781 // TODO: VI Should we cache the activity so that it's easier to find later
4782 // rather than scan through all the stacks and activities?
4783 } catch (RemoteException re) {
4784 activityToCallback.clearVoiceSessionLocked();
4785 // TODO: VI Should this terminate the voice session?
4790 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4791 synchronized (this) {
4792 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4794 mVoiceWakeLock.acquire();
4796 mVoiceWakeLock.release();
4803 public boolean startNextMatchingActivity(IBinder callingActivity,
4804 Intent intent, Bundle bOptions) {
4805 // Refuse possible leaked file descriptors
4806 if (intent != null && intent.hasFileDescriptors() == true) {
4807 throw new IllegalArgumentException("File descriptors passed in Intent");
4809 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4811 synchronized (this) {
4812 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4814 ActivityOptions.abort(options);
4817 if (r.app == null || r.app.thread == null) {
4818 // The caller is not running... d'oh!
4819 ActivityOptions.abort(options);
4822 intent = new Intent(intent);
4823 // The caller is not allowed to change the data.
4824 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4825 // And we are resetting to find the next component...
4826 intent.setComponent(null);
4828 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4830 ActivityInfo aInfo = null;
4832 List<ResolveInfo> resolves =
4833 AppGlobals.getPackageManager().queryIntentActivities(
4834 intent, r.resolvedType,
4835 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4836 UserHandle.getCallingUserId()).getList();
4838 // Look for the original activity in the list...
4839 final int N = resolves != null ? resolves.size() : 0;
4840 for (int i=0; i<N; i++) {
4841 ResolveInfo rInfo = resolves.get(i);
4842 if (rInfo.activityInfo.packageName.equals(r.packageName)
4843 && rInfo.activityInfo.name.equals(r.info.name)) {
4844 // We found the current one... the next matching is
4848 aInfo = resolves.get(i).activityInfo;
4851 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4852 + "/" + r.info.name);
4853 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4854 ? "null" : aInfo.packageName + "/" + aInfo.name));
4859 } catch (RemoteException e) {
4862 if (aInfo == null) {
4863 // Nobody who is next!
4864 ActivityOptions.abort(options);
4865 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4869 intent.setComponent(new ComponentName(
4870 aInfo.applicationInfo.packageName, aInfo.name));
4871 intent.setFlags(intent.getFlags()&~(
4872 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4873 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4874 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4875 Intent.FLAG_ACTIVITY_NEW_TASK));
4877 // Okay now we need to start the new activity, replacing the
4878 // currently running activity. This is a little tricky because
4879 // we want to start the new one as if the current one is finished,
4880 // but not finish the current one first so that there is no flicker.
4882 final boolean wasFinishing = r.finishing;
4885 // Propagate reply information over to the new activity.
4886 final ActivityRecord resultTo = r.resultTo;
4887 final String resultWho = r.resultWho;
4888 final int requestCode = r.requestCode;
4890 if (resultTo != null) {
4891 resultTo.removeResultsLocked(r, resultWho, requestCode);
4894 final long origId = Binder.clearCallingIdentity();
4895 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4896 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4897 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4898 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4899 false, false, null, null, "startNextMatchingActivity");
4900 Binder.restoreCallingIdentity(origId);
4902 r.finishing = wasFinishing;
4903 if (res != ActivityManager.START_SUCCESS) {
4911 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4912 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4913 String msg = "Permission Denial: startActivityFromRecents called without " +
4914 START_TASKS_FROM_RECENTS;
4916 throw new SecurityException(msg);
4918 final long origId = Binder.clearCallingIdentity();
4920 synchronized (this) {
4921 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4924 Binder.restoreCallingIdentity(origId);
4928 final int startActivityInPackage(int uid, String callingPackage,
4929 Intent intent, String resolvedType, IBinder resultTo,
4930 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4931 TaskRecord inTask, String reason) {
4933 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4934 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4936 // TODO: Switch to user app stacks here.
4937 return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4938 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4939 null, null, null, bOptions, false, userId, inTask, reason);
4943 public final int startActivities(IApplicationThread caller, String callingPackage,
4944 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4946 final String reason = "startActivities";
4947 enforceNotIsolatedCaller(reason);
4948 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4949 userId, false, ALLOW_FULL_ONLY, reason, null);
4950 // TODO: Switch to user app stacks here.
4951 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4952 resolvedTypes, resultTo, bOptions, userId, reason);
4956 final int startActivitiesInPackage(int uid, String callingPackage,
4957 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4958 Bundle bOptions, int userId) {
4960 final String reason = "startActivityInPackage";
4961 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4962 userId, false, ALLOW_FULL_ONLY, reason, null);
4963 // TODO: Switch to user app stacks here.
4964 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4965 resultTo, bOptions, userId, reason);
4970 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4971 synchronized (this) {
4972 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4976 r.reportFullyDrawnLocked(restoredFromBundle);
4981 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4982 synchronized (this) {
4983 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4987 final long origId = Binder.clearCallingIdentity();
4989 r.setRequestedOrientation(requestedOrientation);
4991 Binder.restoreCallingIdentity(origId);
4997 public int getRequestedOrientation(IBinder token) {
4998 synchronized (this) {
4999 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5001 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5003 return r.getRequestedOrientation();
5008 public final void requestActivityRelaunch(IBinder token) {
5009 synchronized(this) {
5010 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5014 final long origId = Binder.clearCallingIdentity();
5016 r.forceNewConfig = true;
5017 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5018 true /* preserveWindow */);
5020 Binder.restoreCallingIdentity(origId);
5026 * This is the internal entry point for handling Activity.finish().
5028 * @param token The Binder token referencing the Activity we want to finish.
5029 * @param resultCode Result code, if any, from this Activity.
5030 * @param resultData Result data (Intent), if any, from this Activity.
5031 * @param finishTask Whether to finish the task associated with this Activity.
5033 * @return Returns true if the activity successfully finished, or false if it is still running.
5036 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5038 // Refuse possible leaked file descriptors
5039 if (resultData != null && resultData.hasFileDescriptors() == true) {
5040 throw new IllegalArgumentException("File descriptors passed in Intent");
5043 synchronized(this) {
5044 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5048 // Keep track of the root activity of the task before we finish it
5049 TaskRecord tr = r.getTask();
5050 ActivityRecord rootR = tr.getRootActivity();
5051 if (rootR == null) {
5052 Slog.w(TAG, "Finishing task with all activities already finished");
5054 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5056 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5057 mStackSupervisor.isLastLockedTask(tr)) {
5058 Slog.i(TAG, "Not finishing task in lock task mode");
5059 mStackSupervisor.showLockTaskToast();
5062 if (mController != null) {
5063 // Find the first activity that is not finishing.
5064 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5066 // ask watcher if this is allowed
5067 boolean resumeOK = true;
5069 resumeOK = mController.activityResuming(next.packageName);
5070 } catch (RemoteException e) {
5072 Watchdog.getInstance().setActivityController(null);
5076 Slog.i(TAG, "Not finishing activity because controller resumed");
5081 final long origId = Binder.clearCallingIdentity();
5084 final boolean finishWithRootActivity =
5085 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5086 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5087 || (finishWithRootActivity && r == rootR)) {
5088 // If requested, remove the task that is associated to this activity only if it
5089 // was the root activity in the task. The result code and data is ignored
5090 // because we don't support returning them across task boundaries. Also, to
5091 // keep backwards compatibility we remove the task from recents when finishing
5092 // task with root activity.
5093 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5095 Slog.i(TAG, "Removing task failed to finish activity");
5098 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5099 resultData, "app-request", true);
5101 Slog.i(TAG, "Failed to finish by app-request");
5106 Binder.restoreCallingIdentity(origId);
5112 public final void finishHeavyWeightApp() {
5113 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5114 != PackageManager.PERMISSION_GRANTED) {
5115 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5116 + Binder.getCallingPid()
5117 + ", uid=" + Binder.getCallingUid()
5118 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5120 throw new SecurityException(msg);
5123 synchronized(this) {
5124 if (mHeavyWeightProcess == null) {
5128 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5129 for (int i = 0; i < activities.size(); i++) {
5130 ActivityRecord r = activities.get(i);
5131 if (!r.finishing && r.isInStackLocked()) {
5132 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5133 null, "finish-heavy", true);
5137 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5138 mHeavyWeightProcess.userId, 0));
5139 mHeavyWeightProcess = null;
5144 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5146 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5147 != PackageManager.PERMISSION_GRANTED) {
5148 String msg = "Permission Denial: crashApplication() from pid="
5149 + Binder.getCallingPid()
5150 + ", uid=" + Binder.getCallingUid()
5151 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5153 throw new SecurityException(msg);
5156 synchronized(this) {
5157 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5162 public final void finishSubActivity(IBinder token, String resultWho,
5164 synchronized(this) {
5165 final long origId = Binder.clearCallingIdentity();
5166 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5168 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5170 Binder.restoreCallingIdentity(origId);
5175 public boolean finishActivityAffinity(IBinder token) {
5176 synchronized(this) {
5177 final long origId = Binder.clearCallingIdentity();
5179 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5184 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5186 final TaskRecord task = r.getTask();
5187 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5188 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5189 mStackSupervisor.showLockTaskToast();
5192 return task.getStack().finishActivityAffinityLocked(r);
5194 Binder.restoreCallingIdentity(origId);
5200 public void finishVoiceTask(IVoiceInteractionSession session) {
5201 synchronized (this) {
5202 final long origId = Binder.clearCallingIdentity();
5204 // TODO: VI Consider treating local voice interactions and voice tasks
5206 mStackSupervisor.finishVoiceTask(session);
5208 Binder.restoreCallingIdentity(origId);
5215 public boolean releaseActivityInstance(IBinder token) {
5216 synchronized(this) {
5217 final long origId = Binder.clearCallingIdentity();
5219 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5223 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5225 Binder.restoreCallingIdentity(origId);
5231 public void releaseSomeActivities(IApplicationThread appInt) {
5232 synchronized(this) {
5233 final long origId = Binder.clearCallingIdentity();
5235 ProcessRecord app = getRecordForAppLocked(appInt);
5236 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5238 Binder.restoreCallingIdentity(origId);
5244 public boolean willActivityBeVisible(IBinder token) {
5245 synchronized(this) {
5246 ActivityStack stack = ActivityRecord.getStackLocked(token);
5247 if (stack != null) {
5248 return stack.willActivityBeVisibleLocked(token);
5255 public void overridePendingTransition(IBinder token, String packageName,
5256 int enterAnim, int exitAnim) {
5257 synchronized(this) {
5258 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5263 final long origId = Binder.clearCallingIdentity();
5265 if (self.state == ActivityState.RESUMED
5266 || self.state == ActivityState.PAUSING) {
5267 mWindowManager.overridePendingAppTransition(packageName,
5268 enterAnim, exitAnim, null);
5271 Binder.restoreCallingIdentity(origId);
5276 * Main function for removing an existing process from the activity manager
5277 * as a result of that process going away. Clears out all connections
5280 private final void handleAppDiedLocked(ProcessRecord app,
5281 boolean restarting, boolean allowRestart) {
5283 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5284 false /*replacingPid*/);
5285 if (!kept && !restarting) {
5286 removeLruProcessLocked(app);
5288 ProcessList.remove(pid);
5292 if (mProfileProc == app) {
5293 clearProfilerLocked();
5296 // Remove this application's activities from active lists.
5297 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5299 app.activities.clear();
5301 if (app.instr != null) {
5302 Slog.w(TAG, "Crash of app " + app.processName
5303 + " running instrumentation " + app.instr.mClass);
5304 Bundle info = new Bundle();
5305 info.putString("shortMsg", "Process crashed.");
5306 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5309 mWindowManager.deferSurfaceLayout();
5311 if (!restarting && hasVisibleActivities
5312 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5313 // If there was nothing to resume, and we are not already restarting this process, but
5314 // there is a visible activity that is hosted by the process... then make sure all
5315 // visible activities are running, taking care of restarting this process.
5316 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5319 mWindowManager.continueSurfaceLayout();
5323 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5324 final IBinder threadBinder = thread.asBinder();
5325 // Find the application record.
5326 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5327 final ProcessRecord rec = mLruProcesses.get(i);
5328 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5335 final ProcessRecord getRecordForAppLocked(
5336 IApplicationThread thread) {
5337 if (thread == null) {
5341 int appIndex = getLRURecordIndexForAppLocked(thread);
5342 if (appIndex >= 0) {
5343 return mLruProcesses.get(appIndex);
5346 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5347 // double-check that.
5348 final IBinder threadBinder = thread.asBinder();
5349 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5350 for (int i = pmap.size()-1; i >= 0; i--) {
5351 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5352 for (int j = procs.size()-1; j >= 0; j--) {
5353 final ProcessRecord proc = procs.valueAt(j);
5354 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5355 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5365 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5366 // If there are no longer any background processes running,
5367 // and the app that died was not running instrumentation,
5368 // then tell everyone we are now low on memory.
5369 boolean haveBg = false;
5370 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5371 ProcessRecord rec = mLruProcesses.get(i);
5372 if (rec.thread != null
5373 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5380 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5382 long now = SystemClock.uptimeMillis();
5383 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5386 mLastMemUsageReportTime = now;
5389 final ArrayList<ProcessMemInfo> memInfos
5390 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5391 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5392 long now = SystemClock.uptimeMillis();
5393 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5394 ProcessRecord rec = mLruProcesses.get(i);
5395 if (rec == dyingProc || rec.thread == null) {
5399 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5400 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5402 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5403 // The low memory report is overriding any current
5404 // state for a GC request. Make sure to do
5405 // heavy/important/visible/foreground processes first.
5406 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5407 rec.lastRequestedGc = 0;
5409 rec.lastRequestedGc = rec.lastLowMemory;
5411 rec.reportLowMemory = true;
5412 rec.lastLowMemory = now;
5413 mProcessesToGc.remove(rec);
5414 addProcessToGcListLocked(rec);
5418 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5419 mHandler.sendMessage(msg);
5421 scheduleAppGcsLocked();
5425 final void appDiedLocked(ProcessRecord app) {
5426 appDiedLocked(app, app.pid, app.thread, false);
5429 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5430 boolean fromBinderDied) {
5431 // First check if this ProcessRecord is actually active for the pid.
5432 synchronized (mPidsSelfLocked) {
5433 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5434 if (curProc != app) {
5435 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5440 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5441 synchronized (stats) {
5442 stats.noteProcessDiedLocked(app.info.uid, pid);
5446 if (!fromBinderDied) {
5447 killProcessQuiet(pid);
5449 killProcessGroup(app.uid, pid);
5453 // Clean up already done if the process has been re-started.
5454 if (app.pid == pid && app.thread != null &&
5455 app.thread.asBinder() == thread.asBinder()) {
5456 boolean doLowMem = app.instr == null;
5457 boolean doOomAdj = doLowMem;
5458 if (!app.killedByAm) {
5459 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5460 + ProcessList.makeOomAdjString(app.setAdj)
5461 + ProcessList.makeProcStateString(app.setProcState));
5462 mAllowLowerMemLevel = true;
5464 // Note that we always want to do oom adj to update our state with the
5465 // new number of procs.
5466 mAllowLowerMemLevel = false;
5469 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5470 app.setAdj, app.setProcState);
5471 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5472 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5473 handleAppDiedLocked(app, false, true);
5476 updateOomAdjLocked();
5479 doLowMemReportIfNeededLocked(app);
5481 } else if (app.pid != pid) {
5482 // A new process has already been started.
5483 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5484 + ") has died and restarted (pid " + app.pid + ").");
5485 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5486 } else if (DEBUG_PROCESSES) {
5487 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5488 + thread.asBinder());
5493 * If a stack trace dump file is configured, dump process stack traces.
5494 * @param clearTraces causes the dump file to be erased prior to the new
5495 * traces being written, if true; when false, the new traces will be
5496 * appended to any existing file content.
5497 * @param firstPids of dalvik VM processes to dump stack traces for first
5498 * @param lastPids of dalvik VM processes to dump stack traces for last
5499 * @param nativePids optional list of native pids to dump stack crawls
5501 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5502 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5503 ArrayList<Integer> nativePids) {
5504 ArrayList<Integer> extraPids = null;
5506 // Measure CPU usage as soon as we're called in order to get a realistic sampling
5507 // of the top users at the time of the request.
5508 if (processCpuTracker != null) {
5509 processCpuTracker.init();
5512 } catch (InterruptedException ignored) {
5515 processCpuTracker.update();
5517 // We'll take the stack crawls of just the top apps using CPU.
5518 final int N = processCpuTracker.countWorkingStats();
5519 extraPids = new ArrayList<>();
5520 for (int i = 0; i < N && extraPids.size() < 5; i++) {
5521 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5522 if (lastPids.indexOfKey(stats.pid) >= 0) {
5523 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5525 extraPids.add(stats.pid);
5526 } else if (DEBUG_ANR) {
5527 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5533 boolean useTombstonedForJavaTraces = false;
5536 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5537 if (tracesDirProp.isEmpty()) {
5538 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5539 // dumping scheme. All traces are written to a global trace file (usually
5540 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5541 // the file if requested.
5543 // This mode of operation will be removed in the near future.
5546 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5547 if (globalTracesPath.isEmpty()) {
5548 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5552 tracesFile = new File(globalTracesPath);
5554 if (clearTraces && tracesFile.exists()) {
5555 tracesFile.delete();
5558 tracesFile.createNewFile();
5559 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5560 } catch (IOException e) {
5561 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5565 File tracesDir = new File(tracesDirProp);
5566 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5567 // Each set of ANR traces is written to a separate file and dumpstate will process
5568 // all such files and add them to a captured bug report if they're recent enough.
5569 maybePruneOldTraces(tracesDir);
5571 // NOTE: We should consider creating the file in native code atomically once we've
5572 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5574 tracesFile = createAnrDumpFile(tracesDir);
5575 if (tracesFile == null) {
5579 useTombstonedForJavaTraces = true;
5582 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5583 useTombstonedForJavaTraces);
5587 @GuardedBy("ActivityManagerService.class")
5588 private static SimpleDateFormat sAnrFileDateFormat;
5590 private static synchronized File createAnrDumpFile(File tracesDir) {
5591 if (sAnrFileDateFormat == null) {
5592 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5595 final String formattedDate = sAnrFileDateFormat.format(new Date());
5596 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5599 if (anrFile.createNewFile()) {
5600 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5603 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5605 } catch (IOException ioe) {
5606 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5613 * Prune all trace files that are more than a day old.
5615 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5616 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5617 * since it's the system_server that creates trace files for most ANRs.
5619 private static void maybePruneOldTraces(File tracesDir) {
5620 final long now = System.currentTimeMillis();
5621 final File[] traceFiles = tracesDir.listFiles();
5623 if (traceFiles != null) {
5624 for (File file : traceFiles) {
5625 if ((now - file.lastModified()) > DAY_IN_MILLIS) {
5626 if (!file.delete()) {
5627 Slog.w(TAG, "Unable to prune stale trace file: " + file);
5635 * Legacy code, do not use. Existing users will be deleted.
5640 public static class DumpStackFileObserver extends FileObserver {
5641 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5642 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5644 private final String mTracesPath;
5645 private boolean mClosed;
5647 public DumpStackFileObserver(String tracesPath) {
5648 super(tracesPath, FileObserver.CLOSE_WRITE);
5649 mTracesPath = tracesPath;
5653 public synchronized void onEvent(int event, String path) {
5658 public long dumpWithTimeout(int pid, long timeout) {
5659 sendSignal(pid, SIGNAL_QUIT);
5660 final long start = SystemClock.elapsedRealtime();
5662 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5663 synchronized (this) {
5665 wait(waitTime); // Wait for traces file to be closed.
5666 } catch (InterruptedException e) {
5671 // This avoids a corner case of passing a negative time to the native
5672 // trace in case we've already hit the overall timeout.
5673 final long timeWaited = SystemClock.elapsedRealtime() - start;
5674 if (timeWaited >= timeout) {
5679 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5680 ". Attempting native stack collection.");
5682 final long nativeDumpTimeoutMs = Math.min(
5683 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5685 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5686 (int) (nativeDumpTimeoutMs / 1000));
5689 final long end = SystemClock.elapsedRealtime();
5692 return (end - start);
5697 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5698 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5699 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5700 * attempting to obtain native traces in the case of a failure. Returns the total time spent
5703 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5704 final long timeStart = SystemClock.elapsedRealtime();
5705 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5706 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5707 (NATIVE_DUMP_TIMEOUT_MS / 1000));
5710 return SystemClock.elapsedRealtime() - timeStart;
5713 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5714 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5715 boolean useTombstonedForJavaTraces) {
5717 // We don't need any sort of inotify based monitoring when we're dumping traces via
5718 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5719 // control of all writes to the file in question.
5720 final DumpStackFileObserver observer;
5721 if (useTombstonedForJavaTraces) {
5724 // Use a FileObserver to detect when traces finish writing.
5725 // The order of traces is considered important to maintain for legibility.
5726 observer = new DumpStackFileObserver(tracesFile);
5729 // We must complete all stack dumps within 20 seconds.
5730 long remainingTime = 20 * 1000;
5732 if (observer != null) {
5733 observer.startWatching();
5736 // First collect all of the stacks of the most important pids.
5737 if (firstPids != null) {
5738 int num = firstPids.size();
5739 for (int i = 0; i < num; i++) {
5740 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5741 + firstPids.get(i));
5742 final long timeTaken;
5743 if (useTombstonedForJavaTraces) {
5744 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5746 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5749 remainingTime -= timeTaken;
5750 if (remainingTime <= 0) {
5751 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5752 "); deadline exceeded.");
5757 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5762 // Next collect the stacks of the native pids
5763 if (nativePids != null) {
5764 for (int pid : nativePids) {
5765 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5766 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5768 final long start = SystemClock.elapsedRealtime();
5769 Debug.dumpNativeBacktraceToFileTimeout(
5770 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5771 final long timeTaken = SystemClock.elapsedRealtime() - start;
5773 remainingTime -= timeTaken;
5774 if (remainingTime <= 0) {
5775 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5776 "); deadline exceeded.");
5781 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5786 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5787 if (extraPids != null) {
5788 for (int pid : extraPids) {
5789 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5791 final long timeTaken;
5792 if (useTombstonedForJavaTraces) {
5793 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5795 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5798 remainingTime -= timeTaken;
5799 if (remainingTime <= 0) {
5800 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5801 "); deadline exceeded.");
5806 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5811 if (observer != null) {
5812 observer.stopWatching();
5817 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5818 if (true || Build.IS_USER) {
5821 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5822 if (tracesPath == null || tracesPath.length() == 0) {
5826 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5827 StrictMode.allowThreadDiskWrites();
5829 final File tracesFile = new File(tracesPath);
5830 final File tracesDir = tracesFile.getParentFile();
5831 final File tracesTmp = new File(tracesDir, "__tmp__");
5833 if (tracesFile.exists()) {
5835 tracesFile.renameTo(tracesTmp);
5837 StringBuilder sb = new StringBuilder();
5838 Time tobj = new Time();
5839 tobj.set(System.currentTimeMillis());
5840 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5842 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5843 sb.append(" since ");
5845 FileOutputStream fos = new FileOutputStream(tracesFile);
5846 fos.write(sb.toString().getBytes());
5848 fos.write("\n*** No application process!".getBytes());
5851 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5852 } catch (IOException e) {
5853 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5858 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5859 firstPids.add(app.pid);
5860 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5863 File lastTracesFile = null;
5864 File curTracesFile = null;
5865 for (int i=9; i>=0; i--) {
5866 String name = String.format(Locale.US, "slow%02d.txt", i);
5867 curTracesFile = new File(tracesDir, name);
5868 if (curTracesFile.exists()) {
5869 if (lastTracesFile != null) {
5870 curTracesFile.renameTo(lastTracesFile);
5872 curTracesFile.delete();
5875 lastTracesFile = curTracesFile;
5877 tracesFile.renameTo(curTracesFile);
5878 if (tracesTmp.exists()) {
5879 tracesTmp.renameTo(tracesFile);
5882 StrictMode.setThreadPolicy(oldPolicy);
5886 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5887 if (!mLaunchWarningShown) {
5888 mLaunchWarningShown = true;
5889 mUiHandler.post(new Runnable() {
5892 synchronized (ActivityManagerService.this) {
5893 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5895 mUiHandler.postDelayed(new Runnable() {
5898 synchronized (ActivityManagerService.this) {
5900 mLaunchWarningShown = false;
5911 public boolean clearApplicationUserData(final String packageName,
5912 final IPackageDataObserver observer, int userId) {
5913 enforceNotIsolatedCaller("clearApplicationUserData");
5914 int uid = Binder.getCallingUid();
5915 int pid = Binder.getCallingPid();
5916 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5917 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5919 final ApplicationInfo appInfo;
5920 final boolean isInstantApp;
5922 long callingId = Binder.clearCallingIdentity();
5924 IPackageManager pm = AppGlobals.getPackageManager();
5925 synchronized(this) {
5926 // Instant packages are not protected
5927 if (getPackageManagerInternalLocked().isPackageDataProtected(
5928 resolvedUserId, packageName)) {
5929 throw new SecurityException(
5930 "Cannot clear data for a protected package: " + packageName);
5933 ApplicationInfo applicationInfo = null;
5935 applicationInfo = pm.getApplicationInfo(packageName,
5936 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5937 } catch (RemoteException e) {
5940 appInfo = applicationInfo;
5942 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5944 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5945 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5946 throw new SecurityException("PID " + pid + " does not have permission "
5947 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5948 + " of package " + packageName);
5951 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5952 .hasInstantApplicationMetadata(packageName, resolvedUserId);
5953 final boolean isUninstalledAppWithoutInstantMetadata =
5954 (appInfo == null && !hasInstantMetadata);
5955 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5956 || hasInstantMetadata;
5957 final boolean canAccessInstantApps = checkComponentPermission(
5958 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5959 == PackageManager.PERMISSION_GRANTED;
5961 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5962 && !canAccessInstantApps)) {
5963 Slog.w(TAG, "Invalid packageName: " + packageName);
5964 if (observer != null) {
5966 observer.onRemoveCompleted(packageName, false);
5967 } catch (RemoteException e) {
5968 Slog.i(TAG, "Observer no longer exists.");
5974 if (appInfo != null) {
5975 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5976 // Remove all tasks match the cleared application package and user
5977 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5978 final TaskRecord tr = mRecentTasks.get(i);
5979 final String taskPackageName =
5980 tr.getBaseIntent().getComponent().getPackageName();
5981 if (tr.userId != resolvedUserId) continue;
5982 if (!taskPackageName.equals(packageName)) continue;
5983 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5984 REMOVE_FROM_RECENTS);
5989 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5991 public void onRemoveCompleted(String packageName, boolean succeeded)
5992 throws RemoteException {
5993 if (appInfo != null) {
5994 synchronized (ActivityManagerService.this) {
5995 finishForceStopPackageLocked(packageName, appInfo.uid);
5998 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5999 Uri.fromParts("package", packageName, null));
6000 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6001 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6002 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6004 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6005 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6006 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6009 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6010 null, null, null, null, false, false, resolvedUserId);
6013 if (observer != null) {
6014 observer.onRemoveCompleted(packageName, succeeded);
6020 // Clear application user data
6021 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6023 if (appInfo != null) {
6024 synchronized (this) {
6025 // Remove all permissions granted from/to this package
6026 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6029 // Reset notification settings.
6030 INotificationManager inm = NotificationManager.getService();
6031 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6033 } catch (RemoteException e) {
6036 Binder.restoreCallingIdentity(callingId);
6042 public void killBackgroundProcesses(final String packageName, int userId) {
6043 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6044 != PackageManager.PERMISSION_GRANTED &&
6045 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6046 != PackageManager.PERMISSION_GRANTED) {
6047 String msg = "Permission Denial: killBackgroundProcesses() from pid="
6048 + Binder.getCallingPid()
6049 + ", uid=" + Binder.getCallingUid()
6050 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6052 throw new SecurityException(msg);
6055 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6056 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6057 long callingId = Binder.clearCallingIdentity();
6059 IPackageManager pm = AppGlobals.getPackageManager();
6060 synchronized(this) {
6063 appId = UserHandle.getAppId(
6064 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6065 } catch (RemoteException e) {
6068 Slog.w(TAG, "Invalid packageName: " + packageName);
6071 killPackageProcessesLocked(packageName, appId, userId,
6072 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6075 Binder.restoreCallingIdentity(callingId);
6080 public void killAllBackgroundProcesses() {
6081 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6082 != PackageManager.PERMISSION_GRANTED) {
6083 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6084 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6085 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6087 throw new SecurityException(msg);
6090 final long callingId = Binder.clearCallingIdentity();
6092 synchronized (this) {
6093 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6094 final int NP = mProcessNames.getMap().size();
6095 for (int ip = 0; ip < NP; ip++) {
6096 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6097 final int NA = apps.size();
6098 for (int ia = 0; ia < NA; ia++) {
6099 final ProcessRecord app = apps.valueAt(ia);
6100 if (app.persistent) {
6101 // We don't kill persistent processes.
6106 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6113 final int N = procs.size();
6114 for (int i = 0; i < N; i++) {
6115 removeProcessLocked(procs.get(i), false, true, "kill all background");
6118 mAllowLowerMemLevel = true;
6120 updateOomAdjLocked();
6121 doLowMemReportIfNeededLocked(null);
6124 Binder.restoreCallingIdentity(callingId);
6129 * Kills all background processes, except those matching any of the
6130 * specified properties.
6132 * @param minTargetSdk the target SDK version at or above which to preserve
6133 * processes, or {@code -1} to ignore the target SDK
6134 * @param maxProcState the process state at or below which to preserve
6135 * processes, or {@code -1} to ignore the process state
6137 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6138 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6139 != PackageManager.PERMISSION_GRANTED) {
6140 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6141 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6142 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6144 throw new SecurityException(msg);
6147 final long callingId = Binder.clearCallingIdentity();
6149 synchronized (this) {
6150 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6151 final int NP = mProcessNames.getMap().size();
6152 for (int ip = 0; ip < NP; ip++) {
6153 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6154 final int NA = apps.size();
6155 for (int ia = 0; ia < NA; ia++) {
6156 final ProcessRecord app = apps.valueAt(ia);
6159 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6160 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6167 final int N = procs.size();
6168 for (int i = 0; i < N; i++) {
6169 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6173 Binder.restoreCallingIdentity(callingId);
6178 public void forceStopPackage(final String packageName, int userId) {
6179 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6180 != PackageManager.PERMISSION_GRANTED) {
6181 String msg = "Permission Denial: forceStopPackage() from pid="
6182 + Binder.getCallingPid()
6183 + ", uid=" + Binder.getCallingUid()
6184 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6186 throw new SecurityException(msg);
6188 final int callingPid = Binder.getCallingPid();
6189 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6190 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6191 long callingId = Binder.clearCallingIdentity();
6193 IPackageManager pm = AppGlobals.getPackageManager();
6194 synchronized(this) {
6195 int[] users = userId == UserHandle.USER_ALL
6196 ? mUserController.getUsers() : new int[] { userId };
6197 for (int user : users) {
6200 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6202 } catch (RemoteException e) {
6205 Slog.w(TAG, "Invalid packageName: " + packageName);
6209 pm.setPackageStoppedState(packageName, true, user);
6210 } catch (RemoteException e) {
6211 } catch (IllegalArgumentException e) {
6212 Slog.w(TAG, "Failed trying to unstop package "
6213 + packageName + ": " + e);
6215 if (mUserController.isUserRunningLocked(user, 0)) {
6216 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6217 finishForceStopPackageLocked(packageName, pkgUid);
6222 Binder.restoreCallingIdentity(callingId);
6227 public void addPackageDependency(String packageName) {
6228 synchronized (this) {
6229 int callingPid = Binder.getCallingPid();
6230 if (callingPid == myPid()) {
6235 synchronized (mPidsSelfLocked) {
6236 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6239 if (proc.pkgDeps == null) {
6240 proc.pkgDeps = new ArraySet<String>(1);
6242 proc.pkgDeps.add(packageName);
6248 * The pkg name and app id have to be specified.
6251 public void killApplication(String pkg, int appId, int userId, String reason) {
6255 // Make sure the uid is valid.
6257 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6260 int callerUid = Binder.getCallingUid();
6261 // Only the system server can kill an application
6262 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6263 // Post an aysnc message to kill the application
6264 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6267 Bundle bundle = new Bundle();
6268 bundle.putString("pkg", pkg);
6269 bundle.putString("reason", reason);
6271 mHandler.sendMessage(msg);
6273 throw new SecurityException(callerUid + " cannot kill pkg: " +
6279 public void closeSystemDialogs(String reason) {
6280 enforceNotIsolatedCaller("closeSystemDialogs");
6282 final int pid = Binder.getCallingPid();
6283 final int uid = Binder.getCallingUid();
6284 final long origId = Binder.clearCallingIdentity();
6286 synchronized (this) {
6287 // Only allow this from foreground processes, so that background
6288 // applications can't abuse it to prevent system UI from being shown.
6289 if (uid >= FIRST_APPLICATION_UID) {
6291 synchronized (mPidsSelfLocked) {
6292 proc = mPidsSelfLocked.get(pid);
6294 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6295 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6296 + " from background process " + proc);
6300 closeSystemDialogsLocked(reason);
6303 Binder.restoreCallingIdentity(origId);
6307 void closeSystemDialogsLocked(String reason) {
6308 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6309 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6310 | Intent.FLAG_RECEIVER_FOREGROUND);
6311 if (reason != null) {
6312 intent.putExtra("reason", reason);
6314 mWindowManager.closeSystemDialogs(reason);
6316 mStackSupervisor.closeSystemDialogsLocked();
6318 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6319 AppOpsManager.OP_NONE, null, false, false,
6320 -1, SYSTEM_UID, UserHandle.USER_ALL);
6324 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6325 enforceNotIsolatedCaller("getProcessMemoryInfo");
6326 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6327 for (int i=pids.length-1; i>=0; i--) {
6330 synchronized (this) {
6331 synchronized (mPidsSelfLocked) {
6332 proc = mPidsSelfLocked.get(pids[i]);
6333 oomAdj = proc != null ? proc.setAdj : 0;
6336 infos[i] = new Debug.MemoryInfo();
6337 Debug.getMemoryInfo(pids[i], infos[i]);
6339 synchronized (this) {
6340 if (proc.thread != null && proc.setAdj == oomAdj) {
6341 // Record this for posterity if the process has been stable.
6342 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6343 infos[i].getTotalUss(), false, proc.pkgList);
6352 public long[] getProcessPss(int[] pids) {
6353 enforceNotIsolatedCaller("getProcessPss");
6354 long[] pss = new long[pids.length];
6355 for (int i=pids.length-1; i>=0; i--) {
6358 synchronized (this) {
6359 synchronized (mPidsSelfLocked) {
6360 proc = mPidsSelfLocked.get(pids[i]);
6361 oomAdj = proc != null ? proc.setAdj : 0;
6364 long[] tmpUss = new long[1];
6365 pss[i] = Debug.getPss(pids[i], tmpUss, null);
6367 synchronized (this) {
6368 if (proc.thread != null && proc.setAdj == oomAdj) {
6369 // Record this for posterity if the process has been stable.
6370 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6379 public void killApplicationProcess(String processName, int uid) {
6380 if (processName == null) {
6384 int callerUid = Binder.getCallingUid();
6385 // Only the system server can kill an application
6386 if (callerUid == SYSTEM_UID) {
6387 synchronized (this) {
6388 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6389 if (app != null && app.thread != null) {
6391 app.thread.scheduleSuicide();
6392 } catch (RemoteException e) {
6393 // If the other end already died, then our work here is done.
6396 Slog.w(TAG, "Process/uid not found attempting kill of "
6397 + processName + " / " + uid);
6401 throw new SecurityException(callerUid + " cannot kill app process: " +
6406 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6407 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6408 false, true, false, false, UserHandle.getUserId(uid), reason);
6411 private void finishForceStopPackageLocked(final String packageName, int uid) {
6412 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6413 Uri.fromParts("package", packageName, null));
6414 if (!mProcessesReady) {
6415 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6416 | Intent.FLAG_RECEIVER_FOREGROUND);
6418 intent.putExtra(Intent.EXTRA_UID, uid);
6419 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6420 broadcastIntentLocked(null, null, intent,
6421 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6422 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6426 private final boolean killPackageProcessesLocked(String packageName, int appId,
6427 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6428 boolean doit, boolean evenPersistent, String reason) {
6429 ArrayList<ProcessRecord> procs = new ArrayList<>();
6431 // Remove all processes this package may have touched: all with the
6432 // same UID (except for the system or root user), and all whose name
6433 // matches the package name.
6434 final int NP = mProcessNames.getMap().size();
6435 for (int ip=0; ip<NP; ip++) {
6436 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6437 final int NA = apps.size();
6438 for (int ia=0; ia<NA; ia++) {
6439 ProcessRecord app = apps.valueAt(ia);
6440 if (app.persistent && !evenPersistent) {
6441 // we don't kill persistent processes
6451 // Skip process if it doesn't meet our oom adj requirement.
6452 if (app.setAdj < minOomAdj) {
6456 // If no package is specified, we call all processes under the
6458 if (packageName == null) {
6459 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6462 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6465 // Package has been specified, we want to hit all processes
6466 // that match it. We need to qualify this by the processes
6467 // that are running under the specified app and user ID.
6469 final boolean isDep = app.pkgDeps != null
6470 && app.pkgDeps.contains(packageName);
6471 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6474 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6477 if (!app.pkgList.containsKey(packageName) && !isDep) {
6482 // Process has passed all conditions, kill it!
6491 int N = procs.size();
6492 for (int i=0; i<N; i++) {
6493 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6495 updateOomAdjLocked();
6499 private void cleanupDisabledPackageComponentsLocked(
6500 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6502 Set<String> disabledClasses = null;
6503 boolean packageDisabled = false;
6504 IPackageManager pm = AppGlobals.getPackageManager();
6506 if (changedClasses == null) {
6507 // Nothing changed...
6511 // Determine enable/disable state of the package and its components.
6512 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6513 for (int i = changedClasses.length - 1; i >= 0; i--) {
6514 final String changedClass = changedClasses[i];
6516 if (changedClass.equals(packageName)) {
6518 // Entire package setting changed
6519 enabled = pm.getApplicationEnabledSetting(packageName,
6520 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6521 } catch (Exception e) {
6522 // No such package/component; probably racing with uninstall. In any
6523 // event it means we have nothing further to do here.
6526 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6527 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6528 if (packageDisabled) {
6529 // Entire package is disabled.
6530 // No need to continue to check component states.
6531 disabledClasses = null;
6536 enabled = pm.getComponentEnabledSetting(
6537 new ComponentName(packageName, changedClass),
6538 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6539 } catch (Exception e) {
6540 // As above, probably racing with uninstall.
6543 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6544 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6545 if (disabledClasses == null) {
6546 disabledClasses = new ArraySet<>(changedClasses.length);
6548 disabledClasses.add(changedClass);
6553 if (!packageDisabled && disabledClasses == null) {
6554 // Nothing to do here...
6558 // Clean-up disabled activities.
6559 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6560 packageName, disabledClasses, true, false, userId) && mBooted) {
6561 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6562 mStackSupervisor.scheduleIdleLocked();
6565 // Clean-up disabled tasks
6566 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6568 // Clean-up disabled services.
6569 mServices.bringDownDisabledPackageServicesLocked(
6570 packageName, disabledClasses, userId, false, killProcess, true);
6572 // Clean-up disabled providers.
6573 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6574 mProviderMap.collectPackageProvidersLocked(
6575 packageName, disabledClasses, true, false, userId, providers);
6576 for (int i = providers.size() - 1; i >= 0; i--) {
6577 removeDyingProviderLocked(null, providers.get(i), true);
6580 // Clean-up disabled broadcast receivers.
6581 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6582 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6583 packageName, disabledClasses, userId, true);
6588 final boolean clearBroadcastQueueForUserLocked(int userId) {
6589 boolean didSomething = false;
6590 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6591 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6592 null, null, userId, true);
6594 return didSomething;
6597 final boolean forceStopPackageLocked(String packageName, int appId,
6598 boolean callerWillRestart, boolean purgeCache, boolean doit,
6599 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6602 if (userId == UserHandle.USER_ALL && packageName == null) {
6603 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6606 if (appId < 0 && packageName != null) {
6608 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6609 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6610 } catch (RemoteException e) {
6615 if (packageName != null) {
6616 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6617 + " user=" + userId + ": " + reason);
6619 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6622 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6625 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6626 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6627 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6629 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6631 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6632 packageName, null, doit, evenPersistent, userId)) {
6636 didSomething = true;
6639 if (mServices.bringDownDisabledPackageServicesLocked(
6640 packageName, null, userId, evenPersistent, true, doit)) {
6644 didSomething = true;
6647 if (packageName == null) {
6648 // Remove all sticky broadcasts from this user.
6649 mStickyBroadcasts.remove(userId);
6652 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6653 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6654 userId, providers)) {
6658 didSomething = true;
6660 for (i = providers.size() - 1; i >= 0; i--) {
6661 removeDyingProviderLocked(null, providers.get(i), true);
6664 // Remove transient permissions granted from/to this package/user
6665 removeUriPermissionsForPackageLocked(packageName, userId, false);
6668 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6669 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6670 packageName, null, userId, doit);
6674 if (packageName == null || uninstalling) {
6675 // Remove pending intents. For now we only do this when force
6676 // stopping users, because we have some problems when doing this
6677 // for packages -- app widgets are not currently cleaned up for
6678 // such packages, so they can be left with bad pending intents.
6679 if (mIntentSenderRecords.size() > 0) {
6680 Iterator<WeakReference<PendingIntentRecord>> it
6681 = mIntentSenderRecords.values().iterator();
6682 while (it.hasNext()) {
6683 WeakReference<PendingIntentRecord> wpir = it.next();
6688 PendingIntentRecord pir = wpir.get();
6693 if (packageName == null) {
6694 // Stopping user, remove all objects for the user.
6695 if (pir.key.userId != userId) {
6696 // Not the same user, skip it.
6700 if (UserHandle.getAppId(pir.uid) != appId) {
6701 // Different app id, skip it.
6704 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6705 // Different user, skip it.
6708 if (!pir.key.packageName.equals(packageName)) {
6709 // Different package, skip it.
6716 didSomething = true;
6718 makeIntentSenderCanceledLocked(pir);
6719 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6720 pir.key.activity.pendingResults.remove(pir.ref);
6727 if (purgeCache && packageName != null) {
6728 AttributeCache ac = AttributeCache.instance();
6730 ac.removePackage(packageName);
6734 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6735 mStackSupervisor.scheduleIdleLocked();
6739 return didSomething;
6742 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6743 return removeProcessNameLocked(name, uid, null);
6746 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6747 final ProcessRecord expecting) {
6748 ProcessRecord old = mProcessNames.get(name, uid);
6749 // Only actually remove when the currently recorded value matches the
6750 // record that we expected; if it doesn't match then we raced with a
6751 // newly created process and we don't want to destroy the new one.
6752 if ((expecting == null) || (old == expecting)) {
6753 mProcessNames.remove(name, uid);
6755 if (old != null && old.uidRecord != null) {
6756 old.uidRecord.numProcs--;
6757 if (old.uidRecord.numProcs == 0) {
6758 // No more processes using this uid, tell clients it is gone.
6759 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6760 "No more processes in " + old.uidRecord);
6761 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6762 EventLogTags.writeAmUidStopped(uid);
6763 mActiveUids.remove(uid);
6764 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6766 old.uidRecord = null;
6768 mIsolatedProcesses.remove(uid);
6772 private final void addProcessNameLocked(ProcessRecord proc) {
6773 // We shouldn't already have a process under this name, but just in case we
6774 // need to clean up whatever may be there now.
6775 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6776 if (old == proc && proc.persistent) {
6777 // We are re-adding a persistent process. Whatevs! Just leave it there.
6778 Slog.w(TAG, "Re-adding persistent process " + proc);
6779 } else if (old != null) {
6780 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6782 UidRecord uidRec = mActiveUids.get(proc.uid);
6783 if (uidRec == null) {
6784 uidRec = new UidRecord(proc.uid);
6785 // This is the first appearance of the uid, report it now!
6786 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6787 "Creating new process uid: " + uidRec);
6788 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6789 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6790 uidRec.setWhitelist = uidRec.curWhitelist = true;
6792 uidRec.updateHasInternetPermission();
6793 mActiveUids.put(proc.uid, uidRec);
6794 EventLogTags.writeAmUidRunning(uidRec.uid);
6795 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6797 proc.uidRecord = uidRec;
6799 // Reset render thread tid if it was already set, so new process can set it again.
6800 proc.renderThreadTid = 0;
6802 mProcessNames.put(proc.processName, proc.uid, proc);
6803 if (proc.isolated) {
6804 mIsolatedProcesses.put(proc.uid, proc);
6808 boolean removeProcessLocked(ProcessRecord app,
6809 boolean callerWillRestart, boolean allowRestart, String reason) {
6810 final String name = app.processName;
6811 final int uid = app.uid;
6812 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6813 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6815 ProcessRecord old = mProcessNames.get(name, uid);
6817 // This process is no longer active, so nothing to do.
6818 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6821 removeProcessNameLocked(name, uid);
6822 if (mHeavyWeightProcess == app) {
6823 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6824 mHeavyWeightProcess.userId, 0));
6825 mHeavyWeightProcess = null;
6827 boolean needRestart = false;
6828 if (app.pid > 0 && app.pid != MY_PID) {
6830 synchronized (mPidsSelfLocked) {
6831 mPidsSelfLocked.remove(pid);
6832 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6834 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6835 boolean willRestart = false;
6836 if (app.persistent && !app.isolated) {
6837 if (!callerWillRestart) {
6843 app.kill(reason, true);
6845 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6846 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6848 handleAppDiedLocked(app, willRestart, allowRestart);
6850 removeLruProcessLocked(app);
6851 addAppLocked(app.info, null, false, null /* ABI override */);
6854 mRemovedProcesses.add(app);
6860 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6861 cleanupAppInLaunchingProvidersLocked(app, true);
6862 removeProcessLocked(app, false, true, "timeout publishing content providers");
6865 private final void processStartTimedOutLocked(ProcessRecord app) {
6866 final int pid = app.pid;
6867 boolean gone = false;
6868 synchronized (mPidsSelfLocked) {
6869 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6870 if (knownApp != null && knownApp.thread == null) {
6871 mPidsSelfLocked.remove(pid);
6877 Slog.w(TAG, "Process " + app + " failed to attach");
6878 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6879 pid, app.uid, app.processName);
6880 removeProcessNameLocked(app.processName, app.uid);
6881 if (mHeavyWeightProcess == app) {
6882 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6883 mHeavyWeightProcess.userId, 0));
6884 mHeavyWeightProcess = null;
6886 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6887 // Take care of any launching providers waiting for this process.
6888 cleanupAppInLaunchingProvidersLocked(app, true);
6889 // Take care of any services that are waiting for the process.
6890 mServices.processStartTimedOutLocked(app);
6891 app.kill("start timeout", true);
6893 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6895 removeLruProcessLocked(app);
6896 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6897 Slog.w(TAG, "Unattached app died before backup, skipping");
6898 mHandler.post(new Runnable() {
6902 IBackupManager bm = IBackupManager.Stub.asInterface(
6903 ServiceManager.getService(Context.BACKUP_SERVICE));
6904 bm.agentDisconnected(app.info.packageName);
6905 } catch (RemoteException e) {
6906 // Can't happen; the backup manager is local
6911 if (isPendingBroadcastProcessLocked(pid)) {
6912 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6913 skipPendingBroadcastLocked(pid);
6916 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6920 private final boolean attachApplicationLocked(IApplicationThread thread,
6923 // Find the application record that is being attached... either via
6924 // the pid if we are running in multiple processes, or just pull the
6925 // next app record if we are emulating process with anonymous threads.
6927 long startTime = SystemClock.uptimeMillis();
6928 if (pid != MY_PID && pid >= 0) {
6929 synchronized (mPidsSelfLocked) {
6930 app = mPidsSelfLocked.get(pid);
6937 Slog.w(TAG, "No pending application record for pid " + pid
6938 + " (IApplicationThread " + thread + "); dropping process");
6939 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6940 if (pid > 0 && pid != MY_PID) {
6941 killProcessQuiet(pid);
6942 //TODO: killProcessGroup(app.info.uid, pid);
6945 thread.scheduleExit();
6946 } catch (Exception e) {
6947 // Ignore exceptions.
6953 // If this application record is still attached to a previous
6954 // process, clean it up now.
6955 if (app.thread != null) {
6956 handleAppDiedLocked(app, true, true);
6959 // Tell the process all about itself.
6961 if (DEBUG_ALL) Slog.v(
6962 TAG, "Binding process pid " + pid + " to record " + app);
6964 final String processName = app.processName;
6966 AppDeathRecipient adr = new AppDeathRecipient(
6968 thread.asBinder().linkToDeath(adr, 0);
6969 app.deathRecipient = adr;
6970 } catch (RemoteException e) {
6971 app.resetPackageList(mProcessStats);
6972 startProcessLocked(app, "link fail", processName);
6976 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6978 app.makeActive(thread, mProcessStats);
6979 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6980 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6981 app.forcingToImportant = null;
6982 updateProcessForegroundLocked(app, false, false);
6983 app.hasShownUi = false;
6984 app.debugging = false;
6986 app.killedByAm = false;
6990 // We carefully use the same state that PackageManager uses for
6991 // filtering, since we use this flag to decide if we need to install
6992 // providers when user is unlocked later
6993 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6995 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6997 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6998 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7000 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7001 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7003 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7006 checkTime(startTime, "attachApplicationLocked: before bindApplication");
7009 Slog.i(TAG, "Launching preboot mode app: " + app);
7012 if (DEBUG_ALL) Slog.v(
7013 TAG, "New app record " + app
7014 + " thread=" + thread.asBinder() + " pid=" + pid);
7016 int testMode = ApplicationThreadConstants.DEBUG_OFF;
7017 if (mDebugApp != null && mDebugApp.equals(processName)) {
7018 testMode = mWaitForDebugger
7019 ? ApplicationThreadConstants.DEBUG_WAIT
7020 : ApplicationThreadConstants.DEBUG_ON;
7021 app.debugging = true;
7022 if (mDebugTransient) {
7023 mDebugApp = mOrigDebugApp;
7024 mWaitForDebugger = mOrigWaitForDebugger;
7028 boolean enableTrackAllocation = false;
7029 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7030 enableTrackAllocation = true;
7031 mTrackAllocationApp = null;
7034 // If the app is being launched for restore or full backup, set it up specially
7035 boolean isRestrictedBackupMode = false;
7036 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7037 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7038 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7039 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7040 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7043 if (app.instr != null) {
7044 notifyPackageUse(app.instr.mClass.getPackageName(),
7045 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7047 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7048 + processName + " with config " + getGlobalConfiguration());
7049 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7050 app.compat = compatibilityInfoForPackageLocked(appInfo);
7052 ProfilerInfo profilerInfo = null;
7053 String preBindAgent = null;
7054 if (mProfileApp != null && mProfileApp.equals(processName)) {
7056 if (mProfilerInfo != null) {
7057 // Send a profiler info object to the app if either a file is given, or
7058 // an agent should be loaded at bind-time.
7059 boolean needsInfo = mProfilerInfo.profileFile != null
7060 || mProfilerInfo.attachAgentDuringBind;
7061 profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7062 if (mProfilerInfo.agent != null) {
7063 preBindAgent = mProfilerInfo.agent;
7066 } else if (app.instr != null && app.instr.mProfileFile != null) {
7067 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7070 if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7071 // We need to do a debuggable check here. See setAgentApp for why the check is
7072 // postponed to here.
7073 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7074 String agent = mAppAgentMap.get(processName);
7075 // Do not overwrite already requested agent.
7076 if (profilerInfo == null) {
7077 profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7078 mAppAgentMap.get(processName), true);
7079 } else if (profilerInfo.agent == null) {
7080 profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7085 if (profilerInfo != null && profilerInfo.profileFd != null) {
7086 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7089 // We deprecated Build.SERIAL and it is not accessible to
7090 // apps that target the v2 security sandbox. Since access to
7091 // the serial is now behind a permission we push down the value.
7092 String buildSerial = appInfo.targetSandboxVersion < 2
7093 ? sTheRealBuildSerial : Build.UNKNOWN;
7095 // Check if this is a secondary process that should be incorporated into some
7096 // currently active instrumentation. (Note we do this AFTER all of the profiling
7097 // stuff above because profiling can currently happen only in the primary
7098 // instrumentation process.)
7099 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7100 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7101 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7102 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7103 if (aInstr.mTargetProcesses.length == 0) {
7104 // This is the wildcard mode, where every process brought up for
7105 // the target instrumentation should be included.
7106 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7108 aInstr.mRunningProcesses.add(app);
7111 for (String proc : aInstr.mTargetProcesses) {
7112 if (proc.equals(app.processName)) {
7114 aInstr.mRunningProcesses.add(app);
7123 // If we were asked to attach an agent on startup, do so now, before we're binding
7124 // application code.
7125 if (preBindAgent != null) {
7126 thread.attachAgent(preBindAgent);
7129 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7130 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7131 if (app.instr != null) {
7132 thread.bindApplication(processName, appInfo, providers,
7134 profilerInfo, app.instr.mArguments,
7136 app.instr.mUiAutomationConnection, testMode,
7137 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7138 isRestrictedBackupMode || !normalMode, app.persistent,
7139 new Configuration(getGlobalConfiguration()), app.compat,
7140 getCommonServicesLocked(app.isolated),
7141 mCoreSettingsObserver.getCoreSettingsLocked(),
7144 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7145 null, null, null, testMode,
7146 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7147 isRestrictedBackupMode || !normalMode, app.persistent,
7148 new Configuration(getGlobalConfiguration()), app.compat,
7149 getCommonServicesLocked(app.isolated),
7150 mCoreSettingsObserver.getCoreSettingsLocked(),
7154 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7155 updateLruProcessLocked(app, false, null);
7156 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7157 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7158 } catch (Exception e) {
7159 // todo: Yikes! What should we do? For now we will try to
7160 // start another process, but that could easily get us in
7161 // an infinite loop of restarting processes...
7162 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7164 app.resetPackageList(mProcessStats);
7165 app.unlinkDeathRecipient();
7166 startProcessLocked(app, "bind fail", processName);
7170 // Remove this record from the list of starting applications.
7171 mPersistentStartingProcesses.remove(app);
7172 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7173 "Attach application locked removing on hold: " + app);
7174 mProcessesOnHold.remove(app);
7176 boolean badApp = false;
7177 boolean didSomething = false;
7179 // See if the top visible activity is waiting to run in this process...
7182 if (mStackSupervisor.attachApplicationLocked(app)) {
7183 didSomething = true;
7185 } catch (Exception e) {
7186 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7191 // Find any services that should be running in this process...
7194 didSomething |= mServices.attachApplicationLocked(app, processName);
7195 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7196 } catch (Exception e) {
7197 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7202 // Check if a next-broadcast receiver is in this process...
7203 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7205 didSomething |= sendPendingBroadcastsLocked(app);
7206 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7207 } catch (Exception e) {
7208 // If the app died trying to launch the receiver we declare it 'bad'
7209 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7214 // Check whether the next backup agent is in this process...
7215 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7216 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7217 "New app is backup target, launching agent for " + app);
7218 notifyPackageUse(mBackupTarget.appInfo.packageName,
7219 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7221 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7222 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7223 mBackupTarget.backupMode);
7224 } catch (Exception e) {
7225 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7231 app.kill("error during init", true);
7232 handleAppDiedLocked(app, false, true);
7236 if (!didSomething) {
7237 updateOomAdjLocked();
7238 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7245 public final void attachApplication(IApplicationThread thread) {
7246 synchronized (this) {
7247 int callingPid = Binder.getCallingPid();
7248 final long origId = Binder.clearCallingIdentity();
7249 attachApplicationLocked(thread, callingPid);
7250 Binder.restoreCallingIdentity(origId);
7255 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7256 final long origId = Binder.clearCallingIdentity();
7257 synchronized (this) {
7258 ActivityStack stack = ActivityRecord.getStackLocked(token);
7259 if (stack != null) {
7261 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7262 false /* processPausingActivities */, config);
7263 if (stopProfiling) {
7264 if ((mProfileProc == r.app) && mProfilerInfo != null) {
7265 clearProfilerLocked();
7270 Binder.restoreCallingIdentity(origId);
7273 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7274 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7275 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7278 void enableScreenAfterBoot() {
7279 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7280 SystemClock.uptimeMillis());
7281 mWindowManager.enableScreenAfterBoot();
7283 synchronized (this) {
7284 updateEventDispatchingLocked();
7289 public void showBootMessage(final CharSequence msg, final boolean always) {
7290 if (Binder.getCallingUid() != myUid()) {
7291 throw new SecurityException();
7293 mWindowManager.showBootMessage(msg, always);
7297 public void keyguardGoingAway(int flags) {
7298 enforceNotIsolatedCaller("keyguardGoingAway");
7299 final long token = Binder.clearCallingIdentity();
7301 synchronized (this) {
7302 mKeyguardController.keyguardGoingAway(flags);
7305 Binder.restoreCallingIdentity(token);
7310 * @return whther the keyguard is currently locked.
7312 boolean isKeyguardLocked() {
7313 return mKeyguardController.isKeyguardLocked();
7316 final void finishBooting() {
7317 synchronized (this) {
7318 if (!mBootAnimationComplete) {
7319 mCallFinishBooting = true;
7322 mCallFinishBooting = false;
7325 ArraySet<String> completedIsas = new ArraySet<String>();
7326 for (String abi : Build.SUPPORTED_ABIS) {
7327 zygoteProcess.establishZygoteConnectionForAbi(abi);
7328 final String instructionSet = VMRuntime.getInstructionSet(abi);
7329 if (!completedIsas.contains(instructionSet)) {
7331 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7332 } catch (InstallerException e) {
7333 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7334 e.getMessage() +")");
7336 completedIsas.add(instructionSet);
7340 IntentFilter pkgFilter = new IntentFilter();
7341 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7342 pkgFilter.addDataScheme("package");
7343 mContext.registerReceiver(new BroadcastReceiver() {
7345 public void onReceive(Context context, Intent intent) {
7346 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7348 for (String pkg : pkgs) {
7349 synchronized (ActivityManagerService.this) {
7350 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7351 0, "query restart")) {
7352 setResultCode(Activity.RESULT_OK);
7361 IntentFilter dumpheapFilter = new IntentFilter();
7362 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7363 mContext.registerReceiver(new BroadcastReceiver() {
7365 public void onReceive(Context context, Intent intent) {
7366 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7367 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7369 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7374 // Let system services know.
7375 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7377 synchronized (this) {
7378 // Ensure that any processes we had put on hold are now started
7380 final int NP = mProcessesOnHold.size();
7382 ArrayList<ProcessRecord> procs =
7383 new ArrayList<ProcessRecord>(mProcessesOnHold);
7384 for (int ip=0; ip<NP; ip++) {
7385 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7387 startProcessLocked(procs.get(ip), "on-hold", null);
7391 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7392 // Start looking for apps that are abusing wake locks.
7393 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7394 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7395 // Tell anyone interested that we are done booting!
7396 SystemProperties.set("sys.boot_completed", "1");
7398 // And trigger dev.bootcomplete if we are not showing encryption progress
7399 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7400 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7401 SystemProperties.set("dev.bootcomplete", "1");
7403 mUserController.sendBootCompletedLocked(
7404 new IIntentReceiver.Stub() {
7406 public void performReceive(Intent intent, int resultCode,
7407 String data, Bundle extras, boolean ordered,
7408 boolean sticky, int sendingUser) {
7409 synchronized (ActivityManagerService.this) {
7410 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7415 scheduleStartProfilesLocked();
7421 public void bootAnimationComplete() {
7422 final boolean callFinishBooting;
7423 synchronized (this) {
7424 callFinishBooting = mCallFinishBooting;
7425 mBootAnimationComplete = true;
7427 if (callFinishBooting) {
7428 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7430 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7434 final void ensureBootCompleted() {
7436 boolean enableScreen;
7437 synchronized (this) {
7440 enableScreen = !mBooted;
7445 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7447 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7451 enableScreenAfterBoot();
7456 public final void activityResumed(IBinder token) {
7457 final long origId = Binder.clearCallingIdentity();
7458 synchronized(this) {
7459 ActivityRecord.activityResumedLocked(token);
7460 mWindowManager.notifyAppResumedFinished(token);
7462 Binder.restoreCallingIdentity(origId);
7466 public final void activityPaused(IBinder token) {
7467 final long origId = Binder.clearCallingIdentity();
7468 synchronized(this) {
7469 ActivityStack stack = ActivityRecord.getStackLocked(token);
7470 if (stack != null) {
7471 stack.activityPausedLocked(token, false);
7474 Binder.restoreCallingIdentity(origId);
7478 public final void activityStopped(IBinder token, Bundle icicle,
7479 PersistableBundle persistentState, CharSequence description) {
7480 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7482 // Refuse possible leaked file descriptors
7483 if (icicle != null && icicle.hasFileDescriptors()) {
7484 throw new IllegalArgumentException("File descriptors passed in Bundle");
7487 final long origId = Binder.clearCallingIdentity();
7489 synchronized (this) {
7490 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7492 r.activityStoppedLocked(icicle, persistentState, description);
7498 Binder.restoreCallingIdentity(origId);
7502 public final void activityDestroyed(IBinder token) {
7503 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7504 synchronized (this) {
7505 ActivityStack stack = ActivityRecord.getStackLocked(token);
7506 if (stack != null) {
7507 stack.activityDestroyedLocked(token, "activityDestroyed");
7513 public final void activityRelaunched(IBinder token) {
7514 final long origId = Binder.clearCallingIdentity();
7515 synchronized (this) {
7516 mStackSupervisor.activityRelaunchedLocked(token);
7518 Binder.restoreCallingIdentity(origId);
7522 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7523 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7524 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7525 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7526 synchronized (this) {
7527 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7528 if (record == null) {
7529 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7530 + "found for: " + token);
7532 record.setSizeConfigurations(horizontalSizeConfiguration,
7533 verticalSizeConfigurations, smallestSizeConfigurations);
7538 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7539 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7543 public final void notifyEnterAnimationComplete(IBinder token) {
7544 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7548 public String getCallingPackage(IBinder token) {
7549 synchronized (this) {
7550 ActivityRecord r = getCallingRecordLocked(token);
7551 return r != null ? r.info.packageName : null;
7556 public ComponentName getCallingActivity(IBinder token) {
7557 synchronized (this) {
7558 ActivityRecord r = getCallingRecordLocked(token);
7559 return r != null ? r.intent.getComponent() : null;
7563 private ActivityRecord getCallingRecordLocked(IBinder token) {
7564 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7572 public ComponentName getActivityClassForToken(IBinder token) {
7573 synchronized(this) {
7574 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7578 return r.intent.getComponent();
7583 public String getPackageForToken(IBinder token) {
7584 synchronized(this) {
7585 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7589 return r.packageName;
7594 public boolean isRootVoiceInteraction(IBinder token) {
7595 synchronized(this) {
7596 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7600 return r.rootVoiceInteraction;
7605 public IIntentSender getIntentSender(int type,
7606 String packageName, IBinder token, String resultWho,
7607 int requestCode, Intent[] intents, String[] resolvedTypes,
7608 int flags, Bundle bOptions, int userId) {
7609 enforceNotIsolatedCaller("getIntentSender");
7610 // Refuse possible leaked file descriptors
7611 if (intents != null) {
7612 if (intents.length < 1) {
7613 throw new IllegalArgumentException("Intents array length must be >= 1");
7615 for (int i=0; i<intents.length; i++) {
7616 Intent intent = intents[i];
7617 if (intent != null) {
7618 if (intent.hasFileDescriptors()) {
7619 throw new IllegalArgumentException("File descriptors passed in Intent");
7621 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7622 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7623 throw new IllegalArgumentException(
7624 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7626 intents[i] = new Intent(intent);
7629 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7630 throw new IllegalArgumentException(
7631 "Intent array length does not match resolvedTypes length");
7634 if (bOptions != null) {
7635 if (bOptions.hasFileDescriptors()) {
7636 throw new IllegalArgumentException("File descriptors passed in options");
7640 synchronized(this) {
7641 int callingUid = Binder.getCallingUid();
7642 int origUserId = userId;
7643 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7644 type == ActivityManager.INTENT_SENDER_BROADCAST,
7645 ALLOW_NON_FULL, "getIntentSender", null);
7646 if (origUserId == UserHandle.USER_CURRENT) {
7647 // We don't want to evaluate this until the pending intent is
7648 // actually executed. However, we do want to always do the
7649 // security checking for it above.
7650 userId = UserHandle.USER_CURRENT;
7653 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7654 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7655 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7656 if (!UserHandle.isSameApp(callingUid, uid)) {
7657 String msg = "Permission Denial: getIntentSender() from pid="
7658 + Binder.getCallingPid()
7659 + ", uid=" + Binder.getCallingUid()
7660 + ", (need uid=" + uid + ")"
7661 + " is not allowed to send as package " + packageName;
7663 throw new SecurityException(msg);
7667 return getIntentSenderLocked(type, packageName, callingUid, userId,
7668 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7670 } catch (RemoteException e) {
7671 throw new SecurityException(e);
7676 IIntentSender getIntentSenderLocked(int type, String packageName,
7677 int callingUid, int userId, IBinder token, String resultWho,
7678 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7680 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7681 ActivityRecord activity = null;
7682 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7683 activity = ActivityRecord.isInStackLocked(token);
7684 if (activity == null) {
7685 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7688 if (activity.finishing) {
7689 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7694 // We're going to be splicing together extras before sending, so we're
7695 // okay poking into any contained extras.
7696 if (intents != null) {
7697 for (int i = 0; i < intents.length; i++) {
7698 intents[i].setDefusable(true);
7701 Bundle.setDefusable(bOptions, true);
7703 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7704 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7705 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7706 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7707 |PendingIntent.FLAG_UPDATE_CURRENT);
7709 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7710 type, packageName, activity, resultWho,
7711 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7712 WeakReference<PendingIntentRecord> ref;
7713 ref = mIntentSenderRecords.get(key);
7714 PendingIntentRecord rec = ref != null ? ref.get() : null;
7716 if (!cancelCurrent) {
7717 if (updateCurrent) {
7718 if (rec.key.requestIntent != null) {
7719 rec.key.requestIntent.replaceExtras(intents != null ?
7720 intents[intents.length - 1] : null);
7722 if (intents != null) {
7723 intents[intents.length-1] = rec.key.requestIntent;
7724 rec.key.allIntents = intents;
7725 rec.key.allResolvedTypes = resolvedTypes;
7727 rec.key.allIntents = null;
7728 rec.key.allResolvedTypes = null;
7733 makeIntentSenderCanceledLocked(rec);
7734 mIntentSenderRecords.remove(key);
7739 rec = new PendingIntentRecord(this, key, callingUid);
7740 mIntentSenderRecords.put(key, rec.ref);
7741 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7742 if (activity.pendingResults == null) {
7743 activity.pendingResults
7744 = new HashSet<WeakReference<PendingIntentRecord>>();
7746 activity.pendingResults.add(rec.ref);
7752 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7753 Intent intent, String resolvedType,
7754 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7755 if (target instanceof PendingIntentRecord) {
7756 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7757 whitelistToken, finishedReceiver, requiredPermission, options);
7759 if (intent == null) {
7760 // Weird case: someone has given us their own custom IIntentSender, and now
7761 // they have someone else trying to send to it but of course this isn't
7762 // really a PendingIntent, so there is no base Intent, and the caller isn't
7763 // supplying an Intent... but we never want to dispatch a null Intent to
7764 // a receiver, so um... let's make something up.
7765 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7766 intent = new Intent(Intent.ACTION_MAIN);
7769 target.send(code, intent, resolvedType, whitelistToken, null,
7770 requiredPermission, options);
7771 } catch (RemoteException e) {
7773 // Platform code can rely on getting a result back when the send is done, but if
7774 // this intent sender is from outside of the system we can't rely on it doing that.
7775 // So instead we don't give it the result receiver, and instead just directly
7776 // report the finish immediately.
7777 if (finishedReceiver != null) {
7779 finishedReceiver.performReceive(intent, 0,
7780 null, null, false, false, UserHandle.getCallingUserId());
7781 } catch (RemoteException e) {
7789 public void cancelIntentSender(IIntentSender sender) {
7790 if (!(sender instanceof PendingIntentRecord)) {
7793 synchronized(this) {
7794 PendingIntentRecord rec = (PendingIntentRecord)sender;
7796 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7797 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7798 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7799 String msg = "Permission Denial: cancelIntentSender() from pid="
7800 + Binder.getCallingPid()
7801 + ", uid=" + Binder.getCallingUid()
7802 + " is not allowed to cancel package "
7803 + rec.key.packageName;
7805 throw new SecurityException(msg);
7807 } catch (RemoteException e) {
7808 throw new SecurityException(e);
7810 cancelIntentSenderLocked(rec, true);
7814 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7815 makeIntentSenderCanceledLocked(rec);
7816 mIntentSenderRecords.remove(rec.key);
7817 if (cleanActivity && rec.key.activity != null) {
7818 rec.key.activity.pendingResults.remove(rec.ref);
7822 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7823 rec.canceled = true;
7824 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7825 if (callbacks != null) {
7826 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7831 public String getPackageForIntentSender(IIntentSender pendingResult) {
7832 if (!(pendingResult instanceof PendingIntentRecord)) {
7836 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7837 return res.key.packageName;
7838 } catch (ClassCastException e) {
7844 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7845 if (!(sender instanceof PendingIntentRecord)) {
7848 synchronized(this) {
7849 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7854 public void unregisterIntentSenderCancelListener(IIntentSender sender,
7855 IResultReceiver receiver) {
7856 if (!(sender instanceof PendingIntentRecord)) {
7859 synchronized(this) {
7860 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7865 public int getUidForIntentSender(IIntentSender sender) {
7866 if (sender instanceof PendingIntentRecord) {
7868 PendingIntentRecord res = (PendingIntentRecord)sender;
7870 } catch (ClassCastException e) {
7877 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7878 if (!(pendingResult instanceof PendingIntentRecord)) {
7882 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7883 if (res.key.allIntents == null) {
7886 for (int i=0; i<res.key.allIntents.length; i++) {
7887 Intent intent = res.key.allIntents[i];
7888 if (intent.getPackage() != null && intent.getComponent() != null) {
7893 } catch (ClassCastException e) {
7899 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7900 if (!(pendingResult instanceof PendingIntentRecord)) {
7904 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7905 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7909 } catch (ClassCastException e) {
7915 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7916 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7917 "getIntentForIntentSender()");
7918 if (!(pendingResult instanceof PendingIntentRecord)) {
7922 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7923 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7924 } catch (ClassCastException e) {
7930 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7931 if (!(pendingResult instanceof PendingIntentRecord)) {
7935 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7936 synchronized (this) {
7937 return getTagForIntentSenderLocked(res, prefix);
7939 } catch (ClassCastException e) {
7944 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7945 final Intent intent = res.key.requestIntent;
7946 if (intent != null) {
7947 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7948 || res.lastTagPrefix.equals(prefix))) {
7951 res.lastTagPrefix = prefix;
7952 final StringBuilder sb = new StringBuilder(128);
7953 if (prefix != null) {
7956 if (intent.getAction() != null) {
7957 sb.append(intent.getAction());
7958 } else if (intent.getComponent() != null) {
7959 intent.getComponent().appendShortString(sb);
7963 return res.lastTag = sb.toString();
7969 public void setProcessLimit(int max) {
7970 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7971 "setProcessLimit()");
7972 synchronized (this) {
7973 mConstants.setOverrideMaxCachedProcesses(max);
7979 public int getProcessLimit() {
7980 synchronized (this) {
7981 return mConstants.getOverrideMaxCachedProcesses();
7985 void importanceTokenDied(ImportanceToken token) {
7986 synchronized (ActivityManagerService.this) {
7987 synchronized (mPidsSelfLocked) {
7989 = mImportantProcesses.get(token.pid);
7993 mImportantProcesses.remove(token.pid);
7994 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7998 pr.forcingToImportant = null;
7999 updateProcessForegroundLocked(pr, false, false);
8001 updateOomAdjLocked();
8006 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8007 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8008 "setProcessImportant()");
8009 synchronized(this) {
8010 boolean changed = false;
8012 synchronized (mPidsSelfLocked) {
8013 ProcessRecord pr = mPidsSelfLocked.get(pid);
8014 if (pr == null && isForeground) {
8015 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8018 ImportanceToken oldToken = mImportantProcesses.get(pid);
8019 if (oldToken != null) {
8020 oldToken.token.unlinkToDeath(oldToken, 0);
8021 mImportantProcesses.remove(pid);
8023 pr.forcingToImportant = null;
8027 if (isForeground && token != null) {
8028 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8030 public void binderDied() {
8031 importanceTokenDied(this);
8035 token.linkToDeath(newToken, 0);
8036 mImportantProcesses.put(pid, newToken);
8037 pr.forcingToImportant = newToken;
8039 } catch (RemoteException e) {
8040 // If the process died while doing this, we will later
8041 // do the cleanup with the process death link.
8047 updateOomAdjLocked();
8053 public boolean isAppForeground(int uid) throws RemoteException {
8054 synchronized (this) {
8055 UidRecord uidRec = mActiveUids.get(uid);
8056 if (uidRec == null || uidRec.idle) {
8059 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8063 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8064 // be guarded by permission checking.
8065 int getUidState(int uid) {
8066 synchronized (this) {
8067 return getUidStateLocked(uid);
8071 int getUidStateLocked(int uid) {
8072 UidRecord uidRec = mActiveUids.get(uid);
8073 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8077 public boolean isInMultiWindowMode(IBinder token) {
8078 final long origId = Binder.clearCallingIdentity();
8080 synchronized(this) {
8081 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8085 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8086 return !r.getTask().mFullscreen;
8089 Binder.restoreCallingIdentity(origId);
8094 public boolean isInPictureInPictureMode(IBinder token) {
8095 final long origId = Binder.clearCallingIdentity();
8097 synchronized(this) {
8098 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8101 Binder.restoreCallingIdentity(origId);
8105 private boolean isInPictureInPictureMode(ActivityRecord r) {
8106 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8107 r.getStack().isInStackLocked(r) == null) {
8111 // If we are animating to fullscreen then we have already dispatched the PIP mode
8112 // changed, so we should reflect that check here as well.
8113 final PinnedActivityStack stack = r.getStack();
8114 final PinnedStackWindowController windowController = stack.getWindowContainerController();
8115 return !windowController.isAnimatingBoundsToFullscreen();
8119 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8120 final long origId = Binder.clearCallingIdentity();
8122 synchronized(this) {
8123 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8124 "enterPictureInPictureMode", token, params);
8126 // If the activity is already in picture in picture mode, then just return early
8127 if (isInPictureInPictureMode(r)) {
8131 // Activity supports picture-in-picture, now check that we can enter PiP at this
8133 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8134 false /* beforeStopping */)) {
8138 final Runnable enterPipRunnable = () -> {
8139 // Only update the saved args from the args that are set
8140 r.pictureInPictureArgs.copyOnlySet(params);
8141 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8142 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8143 // Adjust the source bounds by the insets for the transition down
8144 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8145 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8146 true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8147 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8148 stack.setPictureInPictureAspectRatio(aspectRatio);
8149 stack.setPictureInPictureActions(actions);
8151 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8152 r.supportsEnterPipOnTaskSwitch);
8153 logPictureInPictureArgs(params);
8156 if (isKeyguardLocked()) {
8157 // If the keyguard is showing or occluded, then try and dismiss it before
8158 // entering picture-in-picture (this will prompt the user to authenticate if the
8159 // device is currently locked).
8161 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8163 public void onDismissError() throws RemoteException {
8168 public void onDismissSucceeded() throws RemoteException {
8169 mHandler.post(enterPipRunnable);
8173 public void onDismissCancelled() throws RemoteException {
8177 } catch (RemoteException e) {
8181 // Enter picture in picture immediately otherwise
8182 enterPipRunnable.run();
8187 Binder.restoreCallingIdentity(origId);
8192 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8193 final long origId = Binder.clearCallingIdentity();
8195 synchronized(this) {
8196 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8197 "setPictureInPictureParams", token, params);
8199 // Only update the saved args from the args that are set
8200 r.pictureInPictureArgs.copyOnlySet(params);
8201 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8202 // If the activity is already in picture-in-picture, update the pinned stack now
8203 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8204 // be used the next time the activity enters PiP
8205 final PinnedActivityStack stack = r.getStack();
8206 if (!stack.isAnimatingBoundsToFullscreen()) {
8207 stack.setPictureInPictureAspectRatio(
8208 r.pictureInPictureArgs.getAspectRatio());
8209 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8212 logPictureInPictureArgs(params);
8215 Binder.restoreCallingIdentity(origId);
8220 public int getMaxNumPictureInPictureActions(IBinder token) {
8221 // Currently, this is a static constant, but later, we may change this to be dependent on
8222 // the context of the activity
8226 private void logPictureInPictureArgs(PictureInPictureParams params) {
8227 if (params.hasSetActions()) {
8228 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8229 params.getActions().size());
8231 if (params.hasSetAspectRatio()) {
8232 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8233 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8234 MetricsLogger.action(lm);
8239 * Checks the state of the system and the activity associated with the given {@param token} to
8240 * verify that picture-in-picture is supported for that activity.
8242 * @return the activity record for the given {@param token} if all the checks pass.
8244 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8245 IBinder token, PictureInPictureParams params) {
8246 if (!mSupportsPictureInPicture) {
8247 throw new IllegalStateException(caller
8248 + ": Device doesn't support picture-in-picture mode.");
8251 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8253 throw new IllegalStateException(caller
8254 + ": Can't find activity for token=" + token);
8257 if (!r.supportsPictureInPicture()) {
8258 throw new IllegalStateException(caller
8259 + ": Current activity does not support picture-in-picture.");
8262 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8263 throw new IllegalStateException(caller
8264 + ": Activities on the home, assistant, or recents stack not supported");
8267 if (params.hasSetAspectRatio()
8268 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8269 params.getAspectRatio())) {
8270 final float minAspectRatio = mContext.getResources().getFloat(
8271 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8272 final float maxAspectRatio = mContext.getResources().getFloat(
8273 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8274 throw new IllegalArgumentException(String.format(caller
8275 + ": Aspect ratio is too extreme (must be between %f and %f).",
8276 minAspectRatio, maxAspectRatio));
8279 // Truncate the number of actions if necessary
8280 params.truncateActions(getMaxNumPictureInPictureActions(token));
8285 // =========================================================
8287 // =========================================================
8289 static class ProcessInfoService extends IProcessInfoService.Stub {
8290 final ActivityManagerService mActivityManagerService;
8291 ProcessInfoService(ActivityManagerService activityManagerService) {
8292 mActivityManagerService = activityManagerService;
8296 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8297 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8298 /*in*/ pids, /*out*/ states, null);
8302 public void getProcessStatesAndOomScoresFromPids(
8303 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8304 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8305 /*in*/ pids, /*out*/ states, /*out*/ scores);
8310 * For each PID in the given input array, write the current process state
8311 * for that process into the states array, or -1 to indicate that no
8312 * process with the given PID exists. If scores array is provided, write
8313 * the oom score for the process into the scores array, with INVALID_ADJ
8314 * indicating the PID doesn't exist.
8316 public void getProcessStatesAndOomScoresForPIDs(
8317 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8318 if (scores != null) {
8319 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8320 "getProcessStatesAndOomScoresForPIDs()");
8324 throw new NullPointerException("pids");
8325 } else if (states == null) {
8326 throw new NullPointerException("states");
8327 } else if (pids.length != states.length) {
8328 throw new IllegalArgumentException("pids and states arrays have different lengths!");
8329 } else if (scores != null && pids.length != scores.length) {
8330 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8333 synchronized (mPidsSelfLocked) {
8334 for (int i = 0; i < pids.length; i++) {
8335 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8336 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8338 if (scores != null) {
8339 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8345 // =========================================================
8347 // =========================================================
8349 static class PermissionController extends IPermissionController.Stub {
8350 ActivityManagerService mActivityManagerService;
8351 PermissionController(ActivityManagerService activityManagerService) {
8352 mActivityManagerService = activityManagerService;
8356 public boolean checkPermission(String permission, int pid, int uid) {
8357 return mActivityManagerService.checkPermission(permission, pid,
8358 uid) == PackageManager.PERMISSION_GRANTED;
8362 public String[] getPackagesForUid(int uid) {
8363 return mActivityManagerService.mContext.getPackageManager()
8364 .getPackagesForUid(uid);
8368 public boolean isRuntimePermission(String permission) {
8370 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8371 .getPermissionInfo(permission, 0);
8372 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8373 == PermissionInfo.PROTECTION_DANGEROUS;
8374 } catch (NameNotFoundException nnfe) {
8375 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8381 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8383 public int checkComponentPermission(String permission, int pid, int uid,
8384 int owningUid, boolean exported) {
8385 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8386 owningUid, exported);
8390 public Object getAMSLock() {
8391 return ActivityManagerService.this;
8396 * This can be called with or without the global lock held.
8398 int checkComponentPermission(String permission, int pid, int uid,
8399 int owningUid, boolean exported) {
8400 if (pid == MY_PID) {
8401 return PackageManager.PERMISSION_GRANTED;
8403 return ActivityManager.checkComponentPermission(permission, uid,
8404 owningUid, exported);
8408 * As the only public entry point for permissions checking, this method
8409 * can enforce the semantic that requesting a check on a null global
8410 * permission is automatically denied. (Internally a null permission
8411 * string is used when calling {@link #checkComponentPermission} in cases
8412 * when only uid-based security is needed.)
8414 * This can be called with or without the global lock held.
8417 public int checkPermission(String permission, int pid, int uid) {
8418 if (permission == null) {
8419 return PackageManager.PERMISSION_DENIED;
8421 return checkComponentPermission(permission, pid, uid, -1, true);
8425 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8426 if (permission == null) {
8427 return PackageManager.PERMISSION_DENIED;
8430 // We might be performing an operation on behalf of an indirect binder
8431 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
8432 // client identity accordingly before proceeding.
8433 Identity tlsIdentity = sCallerIdentity.get();
8434 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8435 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8436 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8437 uid = tlsIdentity.uid;
8438 pid = tlsIdentity.pid;
8441 return checkComponentPermission(permission, pid, uid, -1, true);
8445 * Binder IPC calls go through the public entry point.
8446 * This can be called with or without the global lock held.
8448 int checkCallingPermission(String permission) {
8449 return checkPermission(permission,
8450 Binder.getCallingPid(),
8451 UserHandle.getAppId(Binder.getCallingUid()));
8455 * This can be called with or without the global lock held.
8457 void enforceCallingPermission(String permission, String func) {
8458 if (checkCallingPermission(permission)
8459 == PackageManager.PERMISSION_GRANTED) {
8463 String msg = "Permission Denial: " + func + " from pid="
8464 + Binder.getCallingPid()
8465 + ", uid=" + Binder.getCallingUid()
8466 + " requires " + permission;
8468 throw new SecurityException(msg);
8472 * Determine if UID is holding permissions required to access {@link Uri} in
8473 * the given {@link ProviderInfo}. Final permission checking is always done
8474 * in {@link ContentProvider}.
8476 private final boolean checkHoldingPermissionsLocked(
8477 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8478 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8479 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8480 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8481 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8482 != PERMISSION_GRANTED) {
8486 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8489 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8490 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8491 if (pi.applicationInfo.uid == uid) {
8493 } else if (!pi.exported) {
8497 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8498 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8500 // check if target holds top-level <provider> permissions
8501 if (!readMet && pi.readPermission != null && considerUidPermissions
8502 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8505 if (!writeMet && pi.writePermission != null && considerUidPermissions
8506 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8510 // track if unprotected read/write is allowed; any denied
8511 // <path-permission> below removes this ability
8512 boolean allowDefaultRead = pi.readPermission == null;
8513 boolean allowDefaultWrite = pi.writePermission == null;
8515 // check if target holds any <path-permission> that match uri
8516 final PathPermission[] pps = pi.pathPermissions;
8518 final String path = grantUri.uri.getPath();
8520 while (i > 0 && (!readMet || !writeMet)) {
8522 PathPermission pp = pps[i];
8523 if (pp.match(path)) {
8525 final String pprperm = pp.getReadPermission();
8526 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8527 "Checking read perm for " + pprperm + " for " + pp.getPath()
8528 + ": match=" + pp.match(path)
8529 + " check=" + pm.checkUidPermission(pprperm, uid));
8530 if (pprperm != null) {
8531 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8532 == PERMISSION_GRANTED) {
8535 allowDefaultRead = false;
8540 final String ppwperm = pp.getWritePermission();
8541 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8542 "Checking write perm " + ppwperm + " for " + pp.getPath()
8543 + ": match=" + pp.match(path)
8544 + " check=" + pm.checkUidPermission(ppwperm, uid));
8545 if (ppwperm != null) {
8546 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8547 == PERMISSION_GRANTED) {
8550 allowDefaultWrite = false;
8558 // grant unprotected <provider> read/write, if not blocked by
8559 // <path-permission> above
8560 if (allowDefaultRead) readMet = true;
8561 if (allowDefaultWrite) writeMet = true;
8563 } catch (RemoteException e) {
8567 return readMet && writeMet;
8570 public boolean isAppStartModeDisabled(int uid, String packageName) {
8571 synchronized (this) {
8572 return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8573 == ActivityManager.APP_START_MODE_DISABLED;
8577 // Unified app-op and target sdk check
8578 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8579 // Apps that target O+ are always subject to background check
8580 if (packageTargetSdk >= Build.VERSION_CODES.O) {
8581 if (DEBUG_BACKGROUND_CHECK) {
8582 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8584 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8586 // ...and legacy apps get an AppOp check
8587 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8589 if (DEBUG_BACKGROUND_CHECK) {
8590 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8593 case AppOpsManager.MODE_ALLOWED:
8594 return ActivityManager.APP_START_MODE_NORMAL;
8595 case AppOpsManager.MODE_IGNORED:
8596 return ActivityManager.APP_START_MODE_DELAYED;
8598 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8602 // Service launch is available to apps with run-in-background exemptions but
8603 // some other background operations are not. If we're doing a check
8604 // of service-launch policy, allow those callers to proceed unrestricted.
8605 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8607 if (mPackageManagerInt.isPackagePersistent(packageName)) {
8608 if (DEBUG_BACKGROUND_CHECK) {
8609 Slog.i(TAG, "App " + uid + "/" + packageName
8610 + " is persistent; not restricted in background");
8612 return ActivityManager.APP_START_MODE_NORMAL;
8615 // Non-persistent but background whitelisted?
8616 if (uidOnBackgroundWhitelist(uid)) {
8617 if (DEBUG_BACKGROUND_CHECK) {
8618 Slog.i(TAG, "App " + uid + "/" + packageName
8619 + " on background whitelist; not restricted in background");
8621 return ActivityManager.APP_START_MODE_NORMAL;
8624 // Is this app on the battery whitelist?
8625 if (isOnDeviceIdleWhitelistLocked(uid)) {
8626 if (DEBUG_BACKGROUND_CHECK) {
8627 Slog.i(TAG, "App " + uid + "/" + packageName
8628 + " on idle whitelist; not restricted in background");
8630 return ActivityManager.APP_START_MODE_NORMAL;
8633 // None of the service-policy criteria apply, so we apply the common criteria
8634 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8637 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8638 int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8639 UidRecord uidRec = mActiveUids.get(uid);
8640 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8641 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8642 + (uidRec != null ? uidRec.idle : false));
8643 if (uidRec == null || alwaysRestrict || uidRec.idle) {
8645 if (uidRec == null) {
8646 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8647 UserHandle.getUserId(uid), packageName);
8649 ephemeral = uidRec.ephemeral;
8653 // We are hard-core about ephemeral apps not running in the background.
8654 return ActivityManager.APP_START_MODE_DISABLED;
8657 // The caller is only interested in whether app starts are completely
8658 // disabled for the given package (that is, it is an instant app). So
8659 // we don't need to go further, which is all just seeing if we should
8660 // apply a "delayed" mode for a regular app.
8661 return ActivityManager.APP_START_MODE_NORMAL;
8663 final int startMode = (alwaysRestrict)
8664 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8665 : appServicesRestrictedInBackgroundLocked(uid, packageName,
8667 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8668 + " pkg=" + packageName + " startMode=" + startMode
8669 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8670 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8671 // This is an old app that has been forced into a "compatible as possible"
8672 // mode of background check. To increase compatibility, we will allow other
8673 // foreground apps to cause its services to start.
8674 if (callingPid >= 0) {
8676 synchronized (mPidsSelfLocked) {
8677 proc = mPidsSelfLocked.get(callingPid);
8680 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8681 // Whoever is instigating this is in the foreground, so we will allow it
8683 return ActivityManager.APP_START_MODE_NORMAL;
8690 return ActivityManager.APP_START_MODE_NORMAL;
8693 boolean isOnDeviceIdleWhitelistLocked(int uid) {
8694 final int appId = UserHandle.getAppId(uid);
8695 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8696 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8697 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8700 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8701 ProviderInfo pi = null;
8702 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8707 pi = AppGlobals.getPackageManager().resolveContentProvider(
8708 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8710 } catch (RemoteException ex) {
8716 void grantEphemeralAccessLocked(int userId, Intent intent,
8717 int targetAppId, int ephemeralAppId) {
8718 getPackageManagerInternalLocked().
8719 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8722 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8723 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8724 if (targetUris != null) {
8725 return targetUris.get(grantUri);
8730 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8731 String targetPkg, int targetUid, GrantUri grantUri) {
8732 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8733 if (targetUris == null) {
8734 targetUris = Maps.newArrayMap();
8735 mGrantedUriPermissions.put(targetUid, targetUris);
8738 UriPermission perm = targetUris.get(grantUri);
8740 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8741 targetUris.put(grantUri, perm);
8747 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8748 final int modeFlags) {
8749 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8750 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8751 : UriPermission.STRENGTH_OWNED;
8753 // Root gets to do everything.
8758 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8759 if (perms == null) return false;
8761 // First look for exact match
8762 final UriPermission exactPerm = perms.get(grantUri);
8763 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8767 // No exact match, look for prefixes
8768 final int N = perms.size();
8769 for (int i = 0; i < N; i++) {
8770 final UriPermission perm = perms.valueAt(i);
8771 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8772 && perm.getStrength(modeFlags) >= minStrength) {
8781 * @param uri This uri must NOT contain an embedded userId.
8782 * @param userId The userId in which the uri is to be resolved.
8785 public int checkUriPermission(Uri uri, int pid, int uid,
8786 final int modeFlags, int userId, IBinder callerToken) {
8787 enforceNotIsolatedCaller("checkUriPermission");
8789 // Another redirected-binder-call permissions check as in
8790 // {@link checkPermissionWithToken}.
8791 Identity tlsIdentity = sCallerIdentity.get();
8792 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8793 uid = tlsIdentity.uid;
8794 pid = tlsIdentity.pid;
8797 // Our own process gets to do everything.
8798 if (pid == MY_PID) {
8799 return PackageManager.PERMISSION_GRANTED;
8801 synchronized (this) {
8802 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8803 ? PackageManager.PERMISSION_GRANTED
8804 : PackageManager.PERMISSION_DENIED;
8809 * Check if the targetPkg can be granted permission to access uri by
8810 * the callingUid using the given modeFlags. Throws a security exception
8811 * if callingUid is not allowed to do this. Returns the uid of the target
8812 * if the URI permission grant should be performed; returns -1 if it is not
8813 * needed (for example targetPkg already has permission to access the URI).
8814 * If you already know the uid of the target, you can supply it in
8815 * lastTargetUid else set that to -1.
8817 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8818 final int modeFlags, int lastTargetUid) {
8819 if (!Intent.isAccessUriMode(modeFlags)) {
8823 if (targetPkg != null) {
8824 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8825 "Checking grant " + targetPkg + " permission to " + grantUri);
8828 final IPackageManager pm = AppGlobals.getPackageManager();
8830 // If this is not a content: uri, we can't do anything with it.
8831 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8832 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8833 "Can't grant URI permission for non-content URI: " + grantUri);
8837 // Bail early if system is trying to hand out permissions directly; it
8838 // must always grant permissions on behalf of someone explicit.
8839 final int callingAppId = UserHandle.getAppId(callingUid);
8840 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8841 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8842 // Exempted authority for cropping user photos in Settings app
8844 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8845 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8850 final String authority = grantUri.uri.getAuthority();
8851 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8852 MATCH_DEBUG_TRIAGED_MISSING);
8854 Slog.w(TAG, "No content provider found for permission check: " +
8855 grantUri.uri.toSafeString());
8859 int targetUid = lastTargetUid;
8860 if (targetUid < 0 && targetPkg != null) {
8862 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8863 UserHandle.getUserId(callingUid));
8864 if (targetUid < 0) {
8865 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8866 "Can't grant URI permission no uid for: " + targetPkg);
8869 } catch (RemoteException ex) {
8874 // If we're extending a persistable grant, then we always need to create
8875 // the grant data structure so that take/release APIs work
8876 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8880 if (targetUid >= 0) {
8881 // First... does the target actually need this permission?
8882 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8883 // No need to grant the target this permission.
8884 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8885 "Target " + targetPkg + " already has full permission to " + grantUri);
8889 // First... there is no target package, so can anyone access it?
8890 boolean allowed = pi.exported;
8891 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8892 if (pi.readPermission != null) {
8896 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8897 if (pi.writePermission != null) {
8906 /* There is a special cross user grant if:
8907 * - The target is on another user.
8908 * - Apps on the current user can access the uri without any uid permissions.
8909 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8910 * grant uri permissions.
8912 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8913 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8914 modeFlags, false /*without considering the uid permissions*/);
8916 // Second... is the provider allowing granting of URI permissions?
8917 if (!specialCrossUserGrant) {
8918 if (!pi.grantUriPermissions) {
8919 throw new SecurityException("Provider " + pi.packageName
8921 + " does not allow granting of Uri permissions (uri "
8924 if (pi.uriPermissionPatterns != null) {
8925 final int N = pi.uriPermissionPatterns.length;
8926 boolean allowed = false;
8927 for (int i=0; i<N; i++) {
8928 if (pi.uriPermissionPatterns[i] != null
8929 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8935 throw new SecurityException("Provider " + pi.packageName
8937 + " does not allow granting of permission to path of Uri "
8943 // Third... does the caller itself have permission to access
8945 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8946 // Require they hold a strong enough Uri permission
8947 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8948 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8949 throw new SecurityException(
8950 "UID " + callingUid + " does not have permission to " + grantUri
8951 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8952 + "or related APIs");
8954 throw new SecurityException(
8955 "UID " + callingUid + " does not have permission to " + grantUri);
8963 * @param uri This uri must NOT contain an embedded userId.
8964 * @param userId The userId in which the uri is to be resolved.
8967 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8968 final int modeFlags, int userId) {
8969 enforceNotIsolatedCaller("checkGrantUriPermission");
8970 synchronized(this) {
8971 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8972 new GrantUri(userId, uri, false), modeFlags, -1);
8976 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8977 final int modeFlags, UriPermissionOwner owner) {
8978 if (!Intent.isAccessUriMode(modeFlags)) {
8982 // So here we are: the caller has the assumed permission
8983 // to the uri, and the target doesn't. Let's now give this to
8986 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8987 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8989 final String authority = grantUri.uri.getAuthority();
8990 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8991 MATCH_DEBUG_TRIAGED_MISSING);
8993 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8997 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8998 grantUri.prefix = true;
9000 final UriPermission perm = findOrCreateUriPermissionLocked(
9001 pi.packageName, targetPkg, targetUid, grantUri);
9002 perm.grantModes(modeFlags, owner);
9005 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9006 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9007 if (targetPkg == null) {
9008 throw new NullPointerException("targetPkg");
9011 final IPackageManager pm = AppGlobals.getPackageManager();
9013 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9014 } catch (RemoteException ex) {
9018 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9020 if (targetUid < 0) {
9024 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9028 static class NeededUriGrants extends ArrayList<GrantUri> {
9029 final String targetPkg;
9030 final int targetUid;
9033 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9034 this.targetPkg = targetPkg;
9035 this.targetUid = targetUid;
9041 * Like checkGrantUriPermissionLocked, but takes an Intent.
9043 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9044 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9045 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9046 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9047 + " clip=" + (intent != null ? intent.getClipData() : null)
9048 + " from " + intent + "; flags=0x"
9049 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9051 if (targetPkg == null) {
9052 throw new NullPointerException("targetPkg");
9055 if (intent == null) {
9058 Uri data = intent.getData();
9059 ClipData clip = intent.getClipData();
9060 if (data == null && clip == null) {
9063 // Default userId for uris in the intent (if they don't specify it themselves)
9064 int contentUserHint = intent.getContentUserHint();
9065 if (contentUserHint == UserHandle.USER_CURRENT) {
9066 contentUserHint = UserHandle.getUserId(callingUid);
9068 final IPackageManager pm = AppGlobals.getPackageManager();
9070 if (needed != null) {
9071 targetUid = needed.targetUid;
9074 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9076 } catch (RemoteException ex) {
9079 if (targetUid < 0) {
9080 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9081 "Can't grant URI permission no uid for: " + targetPkg
9082 + " on user " + targetUserId);
9087 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9088 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9090 if (targetUid > 0) {
9091 if (needed == null) {
9092 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9094 needed.add(grantUri);
9098 for (int i=0; i<clip.getItemCount(); i++) {
9099 Uri uri = clip.getItemAt(i).getUri();
9101 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9102 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9104 if (targetUid > 0) {
9105 if (needed == null) {
9106 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9108 needed.add(grantUri);
9111 Intent clipIntent = clip.getItemAt(i).getIntent();
9112 if (clipIntent != null) {
9113 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9114 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9115 if (newNeeded != null) {
9127 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9129 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9130 UriPermissionOwner owner) {
9131 if (needed != null) {
9132 for (int i=0; i<needed.size(); i++) {
9133 GrantUri grantUri = needed.get(i);
9134 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9135 grantUri, needed.flags, owner);
9140 void grantUriPermissionFromIntentLocked(int callingUid,
9141 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9142 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9143 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9144 if (needed == null) {
9148 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9152 * @param uri This uri must NOT contain an embedded userId.
9153 * @param userId The userId in which the uri is to be resolved.
9156 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9157 final int modeFlags, int userId) {
9158 enforceNotIsolatedCaller("grantUriPermission");
9159 GrantUri grantUri = new GrantUri(userId, uri, false);
9160 synchronized(this) {
9161 final ProcessRecord r = getRecordForAppLocked(caller);
9163 throw new SecurityException("Unable to find app for caller "
9165 + " when granting permission to uri " + grantUri);
9167 if (targetPkg == null) {
9168 throw new IllegalArgumentException("null target");
9170 if (grantUri == null) {
9171 throw new IllegalArgumentException("null uri");
9174 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9175 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9176 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9177 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9179 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9180 UserHandle.getUserId(r.uid));
9184 void removeUriPermissionIfNeededLocked(UriPermission perm) {
9185 if (perm.modeFlags == 0) {
9186 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9188 if (perms != null) {
9189 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9190 "Removing " + perm.targetUid + " permission to " + perm.uri);
9192 perms.remove(perm.uri);
9193 if (perms.isEmpty()) {
9194 mGrantedUriPermissions.remove(perm.targetUid);
9200 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9201 final int modeFlags) {
9202 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9203 "Revoking all granted permissions to " + grantUri);
9205 final IPackageManager pm = AppGlobals.getPackageManager();
9206 final String authority = grantUri.uri.getAuthority();
9207 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9208 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9210 Slog.w(TAG, "No content provider found for permission revoke: "
9211 + grantUri.toSafeString());
9215 // Does the caller have this permission on the URI?
9216 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9217 // If they don't have direct access to the URI, then revoke any
9218 // ownerless URI permissions that have been granted to them.
9219 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9220 if (perms != null) {
9221 boolean persistChanged = false;
9222 for (int i = perms.size()-1; i >= 0; i--) {
9223 final UriPermission perm = perms.valueAt(i);
9224 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9227 if (perm.uri.sourceUserId == grantUri.sourceUserId
9228 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9229 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9230 "Revoking non-owned " + perm.targetUid
9231 + " permission to " + perm.uri);
9232 persistChanged |= perm.revokeModes(
9233 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9234 if (perm.modeFlags == 0) {
9239 if (perms.isEmpty()) {
9240 mGrantedUriPermissions.remove(callingUid);
9242 if (persistChanged) {
9243 schedulePersistUriGrants();
9249 boolean persistChanged = false;
9251 // Go through all of the permissions and remove any that match.
9252 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9253 final int targetUid = mGrantedUriPermissions.keyAt(i);
9254 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9256 for (int j = perms.size()-1; j >= 0; j--) {
9257 final UriPermission perm = perms.valueAt(j);
9258 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9261 if (perm.uri.sourceUserId == grantUri.sourceUserId
9262 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9263 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9264 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9265 persistChanged |= perm.revokeModes(
9266 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9267 targetPackage == null);
9268 if (perm.modeFlags == 0) {
9274 if (perms.isEmpty()) {
9275 mGrantedUriPermissions.removeAt(i);
9279 if (persistChanged) {
9280 schedulePersistUriGrants();
9285 * @param uri This uri must NOT contain an embedded userId.
9286 * @param userId The userId in which the uri is to be resolved.
9289 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9290 final int modeFlags, int userId) {
9291 enforceNotIsolatedCaller("revokeUriPermission");
9292 synchronized(this) {
9293 final ProcessRecord r = getRecordForAppLocked(caller);
9295 throw new SecurityException("Unable to find app for caller "
9297 + " when revoking permission to uri " + uri);
9300 Slog.w(TAG, "revokeUriPermission: null uri");
9304 if (!Intent.isAccessUriMode(modeFlags)) {
9308 final String authority = uri.getAuthority();
9309 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9310 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9312 Slog.w(TAG, "No content provider found for permission revoke: "
9313 + uri.toSafeString());
9317 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9323 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9326 * @param packageName Package name to match, or {@code null} to apply to all
9328 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9330 * @param persistable If persistable grants should be removed.
9332 private void removeUriPermissionsForPackageLocked(
9333 String packageName, int userHandle, boolean persistable) {
9334 if (userHandle == UserHandle.USER_ALL && packageName == null) {
9335 throw new IllegalArgumentException("Must narrow by either package or user");
9338 boolean persistChanged = false;
9340 int N = mGrantedUriPermissions.size();
9341 for (int i = 0; i < N; i++) {
9342 final int targetUid = mGrantedUriPermissions.keyAt(i);
9343 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9345 // Only inspect grants matching user
9346 if (userHandle == UserHandle.USER_ALL
9347 || userHandle == UserHandle.getUserId(targetUid)) {
9348 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9349 final UriPermission perm = it.next();
9351 // Only inspect grants matching package
9352 if (packageName == null || perm.sourcePkg.equals(packageName)
9353 || perm.targetPkg.equals(packageName)) {
9354 // Hacky solution as part of fixing a security bug; ignore
9355 // grants associated with DownloadManager so we don't have
9356 // to immediately launch it to regrant the permissions
9357 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9358 && !persistable) continue;
9360 persistChanged |= perm.revokeModes(persistable
9361 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9363 // Only remove when no modes remain; any persisted grants
9364 // will keep this alive.
9365 if (perm.modeFlags == 0) {
9371 if (perms.isEmpty()) {
9372 mGrantedUriPermissions.remove(targetUid);
9379 if (persistChanged) {
9380 schedulePersistUriGrants();
9385 public IBinder newUriPermissionOwner(String name) {
9386 enforceNotIsolatedCaller("newUriPermissionOwner");
9387 synchronized(this) {
9388 UriPermissionOwner owner = new UriPermissionOwner(this, name);
9389 return owner.getExternalTokenLocked();
9394 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9395 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9396 synchronized(this) {
9397 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9399 throw new IllegalArgumentException("Activity does not exist; token="
9402 return r.getUriPermissionsLocked().getExternalTokenLocked();
9406 * @param uri This uri must NOT contain an embedded userId.
9407 * @param sourceUserId The userId in which the uri is to be resolved.
9408 * @param targetUserId The userId of the app that receives the grant.
9411 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9412 final int modeFlags, int sourceUserId, int targetUserId) {
9413 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9414 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9415 "grantUriPermissionFromOwner", null);
9416 synchronized(this) {
9417 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9418 if (owner == null) {
9419 throw new IllegalArgumentException("Unknown owner: " + token);
9421 if (fromUid != Binder.getCallingUid()) {
9422 if (Binder.getCallingUid() != myUid()) {
9423 // Only system code can grant URI permissions on behalf
9425 throw new SecurityException("nice try");
9428 if (targetPkg == null) {
9429 throw new IllegalArgumentException("null target");
9432 throw new IllegalArgumentException("null uri");
9435 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9436 modeFlags, owner, targetUserId);
9441 * @param uri This uri must NOT contain an embedded userId.
9442 * @param userId The userId in which the uri is to be resolved.
9445 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9446 synchronized(this) {
9447 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9448 if (owner == null) {
9449 throw new IllegalArgumentException("Unknown owner: " + token);
9453 owner.removeUriPermissionsLocked(mode);
9455 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9456 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9461 private void schedulePersistUriGrants() {
9462 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9463 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9464 10 * DateUtils.SECOND_IN_MILLIS);
9468 private void writeGrantedUriPermissions() {
9469 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9471 // Snapshot permissions so we can persist without lock
9472 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9473 synchronized (this) {
9474 final int size = mGrantedUriPermissions.size();
9475 for (int i = 0; i < size; i++) {
9476 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9477 for (UriPermission perm : perms.values()) {
9478 if (perm.persistedModeFlags != 0) {
9479 persist.add(perm.snapshot());
9485 FileOutputStream fos = null;
9487 fos = mGrantFile.startWrite();
9489 XmlSerializer out = new FastXmlSerializer();
9490 out.setOutput(fos, StandardCharsets.UTF_8.name());
9491 out.startDocument(null, true);
9492 out.startTag(null, TAG_URI_GRANTS);
9493 for (UriPermission.Snapshot perm : persist) {
9494 out.startTag(null, TAG_URI_GRANT);
9495 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9496 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9497 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9498 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9499 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9500 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9501 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9502 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9503 out.endTag(null, TAG_URI_GRANT);
9505 out.endTag(null, TAG_URI_GRANTS);
9508 mGrantFile.finishWrite(fos);
9509 } catch (IOException e) {
9511 mGrantFile.failWrite(fos);
9516 private void readGrantedUriPermissionsLocked() {
9517 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9519 final long now = System.currentTimeMillis();
9521 FileInputStream fis = null;
9523 fis = mGrantFile.openRead();
9524 final XmlPullParser in = Xml.newPullParser();
9525 in.setInput(fis, StandardCharsets.UTF_8.name());
9528 while ((type = in.next()) != END_DOCUMENT) {
9529 final String tag = in.getName();
9530 if (type == START_TAG) {
9531 if (TAG_URI_GRANT.equals(tag)) {
9532 final int sourceUserId;
9533 final int targetUserId;
9534 final int userHandle = readIntAttribute(in,
9535 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9536 if (userHandle != UserHandle.USER_NULL) {
9537 // For backwards compatibility.
9538 sourceUserId = userHandle;
9539 targetUserId = userHandle;
9541 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9542 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9544 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9545 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9546 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9547 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9548 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9549 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9551 // Sanity check that provider still belongs to source package
9552 // Both direct boot aware and unaware packages are fine as we
9553 // will do filtering at query time to avoid multiple parsing.
9554 final ProviderInfo pi = getProviderInfoLocked(
9555 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9556 | MATCH_DIRECT_BOOT_UNAWARE);
9557 if (pi != null && sourcePkg.equals(pi.packageName)) {
9560 targetUid = AppGlobals.getPackageManager().getPackageUid(
9561 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9562 } catch (RemoteException e) {
9564 if (targetUid != -1) {
9565 final UriPermission perm = findOrCreateUriPermissionLocked(
9566 sourcePkg, targetPkg, targetUid,
9567 new GrantUri(sourceUserId, uri, prefix));
9568 perm.initPersistedModes(modeFlags, createdTime);
9571 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9572 + " but instead found " + pi);
9577 } catch (FileNotFoundException e) {
9578 // Missing grants is okay
9579 } catch (IOException e) {
9580 Slog.wtf(TAG, "Failed reading Uri grants", e);
9581 } catch (XmlPullParserException e) {
9582 Slog.wtf(TAG, "Failed reading Uri grants", e);
9584 IoUtils.closeQuietly(fis);
9589 * @param uri This uri must NOT contain an embedded userId.
9590 * @param userId The userId in which the uri is to be resolved.
9593 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9594 enforceNotIsolatedCaller("takePersistableUriPermission");
9596 Preconditions.checkFlagsArgument(modeFlags,
9597 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9599 synchronized (this) {
9600 final int callingUid = Binder.getCallingUid();
9601 boolean persistChanged = false;
9602 GrantUri grantUri = new GrantUri(userId, uri, false);
9604 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9605 new GrantUri(userId, uri, false));
9606 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9607 new GrantUri(userId, uri, true));
9609 final boolean exactValid = (exactPerm != null)
9610 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9611 final boolean prefixValid = (prefixPerm != null)
9612 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9614 if (!(exactValid || prefixValid)) {
9615 throw new SecurityException("No persistable permission grants found for UID "
9616 + callingUid + " and Uri " + grantUri.toSafeString());
9620 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9623 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9626 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9628 if (persistChanged) {
9629 schedulePersistUriGrants();
9635 * @param uri This uri must NOT contain an embedded userId.
9636 * @param userId The userId in which the uri is to be resolved.
9639 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9640 enforceNotIsolatedCaller("releasePersistableUriPermission");
9642 Preconditions.checkFlagsArgument(modeFlags,
9643 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9645 synchronized (this) {
9646 final int callingUid = Binder.getCallingUid();
9647 boolean persistChanged = false;
9649 UriPermission exactPerm = findUriPermissionLocked(callingUid,
9650 new GrantUri(userId, uri, false));
9651 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9652 new GrantUri(userId, uri, true));
9653 if (exactPerm == null && prefixPerm == null) {
9654 throw new SecurityException("No permission grants found for UID " + callingUid
9655 + " and Uri " + uri.toSafeString());
9658 if (exactPerm != null) {
9659 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9660 removeUriPermissionIfNeededLocked(exactPerm);
9662 if (prefixPerm != null) {
9663 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9664 removeUriPermissionIfNeededLocked(prefixPerm);
9667 if (persistChanged) {
9668 schedulePersistUriGrants();
9674 * Prune any older {@link UriPermission} for the given UID until outstanding
9675 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9677 * @return if any mutations occured that require persisting.
9679 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9680 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9681 if (perms == null) return false;
9682 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9684 final ArrayList<UriPermission> persisted = Lists.newArrayList();
9685 for (UriPermission perm : perms.values()) {
9686 if (perm.persistedModeFlags != 0) {
9687 persisted.add(perm);
9691 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9692 if (trimCount <= 0) return false;
9694 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9695 for (int i = 0; i < trimCount; i++) {
9696 final UriPermission perm = persisted.get(i);
9698 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9699 "Trimming grant created at " + perm.persistedCreateTime);
9701 perm.releasePersistableModes(~0);
9702 removeUriPermissionIfNeededLocked(perm);
9709 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9710 String packageName, boolean incoming) {
9711 enforceNotIsolatedCaller("getPersistedUriPermissions");
9712 Preconditions.checkNotNull(packageName, "packageName");
9714 final int callingUid = Binder.getCallingUid();
9715 final int callingUserId = UserHandle.getUserId(callingUid);
9716 final IPackageManager pm = AppGlobals.getPackageManager();
9718 final int packageUid = pm.getPackageUid(packageName,
9719 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9720 if (packageUid != callingUid) {
9721 throw new SecurityException(
9722 "Package " + packageName + " does not belong to calling UID " + callingUid);
9724 } catch (RemoteException e) {
9725 throw new SecurityException("Failed to verify package name ownership");
9728 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9729 synchronized (this) {
9731 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9733 if (perms == null) {
9734 Slog.w(TAG, "No permission grants found for " + packageName);
9736 for (UriPermission perm : perms.values()) {
9737 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9738 result.add(perm.buildPersistedPublicApiObject());
9743 final int size = mGrantedUriPermissions.size();
9744 for (int i = 0; i < size; i++) {
9745 final ArrayMap<GrantUri, UriPermission> perms =
9746 mGrantedUriPermissions.valueAt(i);
9747 for (UriPermission perm : perms.values()) {
9748 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9749 result.add(perm.buildPersistedPublicApiObject());
9755 return new ParceledListSlice<android.content.UriPermission>(result);
9759 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9760 String packageName, int userId) {
9761 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9762 "getGrantedUriPermissions");
9764 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9765 synchronized (this) {
9766 final int size = mGrantedUriPermissions.size();
9767 for (int i = 0; i < size; i++) {
9768 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9769 for (UriPermission perm : perms.values()) {
9770 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9771 && perm.persistedModeFlags != 0) {
9772 result.add(perm.buildPersistedPublicApiObject());
9777 return new ParceledListSlice<android.content.UriPermission>(result);
9781 public void clearGrantedUriPermissions(String packageName, int userId) {
9782 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9783 "clearGrantedUriPermissions");
9784 removeUriPermissionsForPackageLocked(packageName, userId, true);
9788 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9789 synchronized (this) {
9791 who != null ? getRecordForAppLocked(who) : null;
9792 if (app == null) return;
9794 Message msg = Message.obtain();
9795 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9797 msg.arg1 = waiting ? 1 : 0;
9798 mUiHandler.sendMessage(msg);
9803 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9804 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9805 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9806 outInfo.availMem = getFreeMemory();
9807 outInfo.totalMem = getTotalMemory();
9808 outInfo.threshold = homeAppMem;
9809 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9810 outInfo.hiddenAppThreshold = cachedAppMem;
9811 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9812 ProcessList.SERVICE_ADJ);
9813 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9814 ProcessList.VISIBLE_APP_ADJ);
9815 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9816 ProcessList.FOREGROUND_APP_ADJ);
9819 // =========================================================
9821 // =========================================================
9824 public List<IBinder> getAppTasks(String callingPackage) {
9825 int callingUid = Binder.getCallingUid();
9826 long ident = Binder.clearCallingIdentity();
9828 synchronized(this) {
9829 ArrayList<IBinder> list = new ArrayList<IBinder>();
9831 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9833 final int N = mRecentTasks.size();
9834 for (int i = 0; i < N; i++) {
9835 TaskRecord tr = mRecentTasks.get(i);
9836 // Skip tasks that do not match the caller. We don't need to verify
9837 // callingPackage, because we are also limiting to callingUid and know
9838 // that will limit to the correct security sandbox.
9839 if (tr.effectiveUid != callingUid) {
9842 Intent intent = tr.getBaseIntent();
9843 if (intent == null ||
9844 !callingPackage.equals(intent.getComponent().getPackageName())) {
9847 ActivityManager.RecentTaskInfo taskInfo =
9848 createRecentTaskInfoFromTaskRecord(tr);
9849 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9850 list.add(taskImpl.asBinder());
9853 Binder.restoreCallingIdentity(ident);
9860 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9861 final int callingUid = Binder.getCallingUid();
9862 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9864 synchronized(this) {
9865 if (DEBUG_ALL) Slog.v(
9866 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9868 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9871 // TODO: Improve with MRU list from all ActivityStacks.
9872 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9879 * Creates a new RecentTaskInfo from a TaskRecord.
9881 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9882 // Update the task description to reflect any changes in the task stack
9883 tr.updateTaskDescription();
9885 // Compose the recent task info
9886 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9887 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9888 rti.persistentId = tr.taskId;
9889 rti.baseIntent = new Intent(tr.getBaseIntent());
9890 rti.origActivity = tr.origActivity;
9891 rti.realActivity = tr.realActivity;
9892 rti.description = tr.lastDescription;
9893 rti.stackId = tr.getStackId();
9894 rti.userId = tr.userId;
9895 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9896 rti.firstActiveTime = tr.firstActiveTime;
9897 rti.lastActiveTime = tr.lastActiveTime;
9898 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9899 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9900 rti.numActivities = 0;
9901 if (tr.mBounds != null) {
9902 rti.bounds = new Rect(tr.mBounds);
9904 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9905 rti.resizeMode = tr.mResizeMode;
9907 ActivityRecord base = null;
9908 ActivityRecord top = null;
9911 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9912 tmp = tr.mActivities.get(i);
9913 if (tmp.finishing) {
9917 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9920 rti.numActivities++;
9923 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9924 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9929 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9930 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9931 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9933 if (checkPermission(android.Manifest.permission.GET_TASKS,
9934 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9935 // Temporary compatibility: some existing apps on the system image may
9936 // still be requesting the old permission and not switched to the new
9937 // one; if so, we'll still allow them full access. This means we need
9938 // to see if they are holding the old permission and are a system app.
9940 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9942 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9943 + " is using old GET_TASKS but privileged; allowing");
9945 } catch (RemoteException e) {
9950 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9951 + " does not hold REAL_GET_TASKS; limiting output");
9957 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9959 final int callingUid = Binder.getCallingUid();
9960 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9961 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9963 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9964 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9965 synchronized (this) {
9966 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9968 final boolean detailed = checkCallingPermission(
9969 android.Manifest.permission.GET_DETAILED_TASKS)
9970 == PackageManager.PERMISSION_GRANTED;
9972 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9973 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9974 return ParceledListSlice.emptyList();
9976 mRecentTasks.loadUserRecentsLocked(userId);
9978 final int recentsCount = mRecentTasks.size();
9979 ArrayList<ActivityManager.RecentTaskInfo> res =
9980 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9982 final Set<Integer> includedUsers;
9983 if (includeProfiles) {
9984 includedUsers = mUserController.getProfileIds(userId);
9986 includedUsers = new HashSet<>();
9988 includedUsers.add(Integer.valueOf(userId));
9990 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9991 TaskRecord tr = mRecentTasks.get(i);
9992 // Only add calling user or related users recent tasks
9993 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9994 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9998 if (tr.realActivitySuspended) {
9999 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
10003 // Return the entry if desired by the caller. We always return
10004 // the first entry, because callers always expect this to be the
10005 // foreground app. We may filter others if the caller has
10006 // not supplied RECENT_WITH_EXCLUDED and there is some reason
10007 // we should exclude the entry.
10011 || (tr.intent == null)
10012 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
10015 // If the caller doesn't have the GET_TASKS permission, then only
10016 // allow them to see a small subset of tasks -- their own and home.
10017 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
10018 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
10022 final ActivityStack stack = tr.getStack();
10023 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
10024 if (stack != null && stack.isHomeOrRecentsStack()) {
10025 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10026 "Skipping, home or recents stack task: " + tr);
10030 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10031 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10032 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10033 "Skipping, top task in docked stack: " + tr);
10037 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10038 if (stack != null && stack.isPinnedStack()) {
10039 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10040 "Skipping, pinned stack task: " + tr);
10044 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10045 // Don't include auto remove tasks that are finished or finishing.
10046 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10047 "Skipping, auto-remove without activity: " + tr);
10050 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10051 && !tr.isAvailable) {
10052 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10053 "Skipping, unavail real act: " + tr);
10057 if (!tr.mUserSetupComplete) {
10058 // Don't include task launched while user is not done setting-up.
10059 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10060 "Skipping, user setup not complete: " + tr);
10064 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10066 rti.baseIntent.replaceExtras((Bundle)null);
10073 return new ParceledListSlice<>(res);
10078 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10079 synchronized (this) {
10080 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10081 "getTaskThumbnail()");
10082 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10083 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10085 return tr.getTaskThumbnailLocked();
10092 public ActivityManager.TaskDescription getTaskDescription(int id) {
10093 synchronized (this) {
10094 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10095 "getTaskDescription()");
10096 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10097 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10099 return tr.lastTaskDescription;
10106 public int addAppTask(IBinder activityToken, Intent intent,
10107 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10108 final int callingUid = Binder.getCallingUid();
10109 final long callingIdent = Binder.clearCallingIdentity();
10112 synchronized (this) {
10113 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10115 throw new IllegalArgumentException("Activity does not exist; token="
10118 ComponentName comp = intent.getComponent();
10119 if (comp == null) {
10120 throw new IllegalArgumentException("Intent " + intent
10121 + " must specify explicit component");
10123 if (thumbnail.getWidth() != mThumbnailWidth
10124 || thumbnail.getHeight() != mThumbnailHeight) {
10125 throw new IllegalArgumentException("Bad thumbnail size: got "
10126 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10127 + mThumbnailWidth + "x" + mThumbnailHeight);
10129 if (intent.getSelector() != null) {
10130 intent.setSelector(null);
10132 if (intent.getSourceBounds() != null) {
10133 intent.setSourceBounds(null);
10135 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10136 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10137 // The caller has added this as an auto-remove task... that makes no
10138 // sense, so turn off auto-remove.
10139 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10142 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10143 mLastAddedTaskActivity = null;
10145 ActivityInfo ainfo = mLastAddedTaskActivity;
10146 if (ainfo == null) {
10147 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10148 comp, 0, UserHandle.getUserId(callingUid));
10149 if (ainfo.applicationInfo.uid != callingUid) {
10150 throw new SecurityException(
10151 "Can't add task for another application: target uid="
10152 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10156 TaskRecord task = new TaskRecord(this,
10157 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10158 ainfo, intent, description, new TaskThumbnailInfo());
10160 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10161 if (trimIdx >= 0) {
10162 // If this would have caused a trim, then we'll abort because that
10163 // means it would be added at the end of the list but then just removed.
10164 return INVALID_TASK_ID;
10167 final int N = mRecentTasks.size();
10168 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10169 final TaskRecord tr = mRecentTasks.remove(N - 1);
10170 tr.removedFromRecents();
10173 task.inRecents = true;
10174 mRecentTasks.add(task);
10175 r.getStack().addTask(task, false, "addAppTask");
10177 task.setLastThumbnailLocked(thumbnail);
10178 task.freeLastThumbnail();
10179 return task.taskId;
10182 Binder.restoreCallingIdentity(callingIdent);
10187 public Point getAppTaskThumbnailSize() {
10188 synchronized (this) {
10189 return new Point(mThumbnailWidth, mThumbnailHeight);
10194 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10195 synchronized (this) {
10196 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10198 r.setTaskDescription(td);
10199 final TaskRecord task = r.getTask();
10200 task.updateTaskDescription();
10201 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10207 public void setTaskResizeable(int taskId, int resizeableMode) {
10208 synchronized (this) {
10209 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10210 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10211 if (task == null) {
10212 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10215 task.setResizeMode(resizeableMode);
10220 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10221 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10222 long ident = Binder.clearCallingIdentity();
10224 synchronized (this) {
10225 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10226 if (task == null) {
10227 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10230 // Place the task in the right stack if it isn't there already based on
10231 // the requested bounds.
10232 // The stack transition logic is:
10233 // - a null bounds on a freeform task moves that task to fullscreen
10234 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10235 // that task to freeform
10236 // - otherwise the task is not moved
10237 int stackId = task.getStackId();
10238 if (!StackId.isTaskResizeAllowed(stackId)) {
10239 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10241 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10242 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10243 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10244 stackId = FREEFORM_WORKSPACE_STACK_ID;
10247 // Reparent the task to the right stack if necessary
10248 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10249 if (stackId != task.getStackId()) {
10250 // Defer resume until the task is resized below
10251 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10252 DEFER_RESUME, "resizeTask");
10253 preserveWindow = false;
10256 // After reparenting (which only resizes the task to the stack bounds), resize the
10257 // task to the actual bounds provided
10258 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10261 Binder.restoreCallingIdentity(ident);
10266 public Rect getTaskBounds(int taskId) {
10267 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10268 long ident = Binder.clearCallingIdentity();
10269 Rect rect = new Rect();
10271 synchronized (this) {
10272 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10273 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10274 if (task == null) {
10275 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10278 if (task.getStack() != null) {
10279 // Return the bounds from window manager since it will be adjusted for various
10280 // things like the presense of a docked stack for tasks that aren't resizeable.
10281 task.getWindowContainerBounds(rect);
10283 // Task isn't in window manager yet since it isn't associated with a stack.
10284 // Return the persist value from activity manager
10285 if (task.mBounds != null) {
10286 rect.set(task.mBounds);
10287 } else if (task.mLastNonFullscreenBounds != null) {
10288 rect.set(task.mLastNonFullscreenBounds);
10293 Binder.restoreCallingIdentity(ident);
10299 public void cancelTaskWindowTransition(int taskId) {
10300 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10301 final long ident = Binder.clearCallingIdentity();
10303 synchronized (this) {
10304 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10305 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10306 if (task == null) {
10307 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10310 task.cancelWindowTransition();
10313 Binder.restoreCallingIdentity(ident);
10318 public void cancelTaskThumbnailTransition(int taskId) {
10319 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10320 final long ident = Binder.clearCallingIdentity();
10322 synchronized (this) {
10323 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10324 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10325 if (task == null) {
10326 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10329 task.cancelThumbnailTransition();
10332 Binder.restoreCallingIdentity(ident);
10337 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10338 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10339 final long ident = Binder.clearCallingIdentity();
10341 final TaskRecord task;
10342 synchronized (this) {
10343 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10344 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10345 if (task == null) {
10346 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10350 // Don't call this while holding the lock as this operation might hit the disk.
10351 return task.getSnapshot(reducedResolution);
10353 Binder.restoreCallingIdentity(ident);
10358 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10359 if (userId != UserHandle.getCallingUserId()) {
10360 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10361 "getTaskDescriptionIcon");
10363 final File passedIconFile = new File(filePath);
10364 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10365 passedIconFile.getName());
10366 if (!legitIconFile.getPath().equals(filePath)
10367 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10368 throw new IllegalArgumentException("Bad file path: " + filePath
10369 + " passed for userId " + userId);
10371 return mRecentTasks.getTaskDescriptionIcon(filePath);
10375 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10376 throws RemoteException {
10377 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10378 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10379 activityOptions.getCustomInPlaceResId() == 0) {
10380 throw new IllegalArgumentException("Expected in-place ActivityOption " +
10381 "with valid animation");
10383 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10384 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10385 activityOptions.getCustomInPlaceResId());
10386 mWindowManager.executeAppTransition();
10389 private void removeTasksByPackageNameLocked(String packageName, int userId) {
10390 // Remove all tasks with activities in the specified package from the list of recent tasks
10391 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10392 TaskRecord tr = mRecentTasks.get(i);
10393 if (tr.userId != userId) continue;
10395 ComponentName cn = tr.intent.getComponent();
10396 if (cn != null && cn.getPackageName().equals(packageName)) {
10397 // If the package name matches, remove the task.
10398 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10403 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10406 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10407 TaskRecord tr = mRecentTasks.get(i);
10408 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10412 ComponentName cn = tr.intent.getComponent();
10413 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10414 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10415 if (sameComponent) {
10416 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10422 public void removeStack(int stackId) {
10423 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10424 if (StackId.isHomeOrRecentsStack(stackId)) {
10425 throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10428 synchronized (this) {
10429 final long ident = Binder.clearCallingIdentity();
10431 mStackSupervisor.removeStackLocked(stackId);
10433 Binder.restoreCallingIdentity(ident);
10439 public void moveStackToDisplay(int stackId, int displayId) {
10440 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10442 synchronized (this) {
10443 final long ident = Binder.clearCallingIdentity();
10445 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10446 + " to displayId=" + displayId);
10447 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10449 Binder.restoreCallingIdentity(ident);
10455 public boolean removeTask(int taskId) {
10456 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10457 synchronized (this) {
10458 final long ident = Binder.clearCallingIdentity();
10460 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10462 Binder.restoreCallingIdentity(ident);
10468 * TODO: Add mController hook
10471 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10472 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10474 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10475 synchronized(this) {
10476 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10480 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10481 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10483 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10484 Binder.getCallingUid(), -1, -1, "Task to front")) {
10485 ActivityOptions.abort(options);
10488 final long origId = Binder.clearCallingIdentity();
10490 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10491 if (task == null) {
10492 Slog.d(TAG, "Could not find task for id: "+ taskId);
10495 if (mStackSupervisor.isLockTaskModeViolation(task)) {
10496 mStackSupervisor.showLockTaskToast();
10497 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10500 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10501 if (prev != null) {
10502 task.setTaskToReturnTo(prev);
10504 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10505 false /* forceNonResizable */);
10507 final ActivityRecord topActivity = task.getTopActivity();
10508 if (topActivity != null) {
10510 // We are reshowing a task, use a starting window to hide the initial draw delay
10511 // so the transition can start earlier.
10512 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10513 true /* taskSwitch */, fromRecents);
10516 Binder.restoreCallingIdentity(origId);
10518 ActivityOptions.abort(options);
10522 * Attempts to move a task backwards in z-order (the order of activities within the task is
10525 * There are several possible results of this call:
10526 * - if the task is locked, then we will show the lock toast
10527 * - if there is a task behind the provided task, then that task is made visible and resumed as
10528 * this task is moved to the back
10529 * - otherwise, if there are no other tasks in the stack:
10530 * - if this task is in the pinned stack, then we remove the stack completely, which will
10531 * have the effect of moving the task to the top or bottom of the fullscreen stack
10532 * (depending on whether it is visible)
10533 * - otherwise, we simply return home and hide this task
10535 * @param token A reference to the activity we wish to move
10536 * @param nonRoot If false then this only works if the activity is the root
10537 * of a task; if true it will work for any activity in a task.
10538 * @return Returns true if the move completed, false if not.
10541 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10542 enforceNotIsolatedCaller("moveActivityTaskToBack");
10543 synchronized(this) {
10544 final long origId = Binder.clearCallingIdentity();
10546 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10547 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10548 if (task != null) {
10549 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10552 Binder.restoreCallingIdentity(origId);
10559 public void moveTaskBackwards(int task) {
10560 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10561 "moveTaskBackwards()");
10563 synchronized(this) {
10564 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10565 Binder.getCallingUid(), -1, -1, "Task backwards")) {
10568 final long origId = Binder.clearCallingIdentity();
10569 moveTaskBackwardsLocked(task);
10570 Binder.restoreCallingIdentity(origId);
10574 private final void moveTaskBackwardsLocked(int task) {
10575 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10579 public int createStackOnDisplay(int displayId) throws RemoteException {
10580 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10581 synchronized (this) {
10582 final int stackId = mStackSupervisor.getNextStackId();
10583 final ActivityStack stack =
10584 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10585 if (stack == null) {
10586 return INVALID_STACK_ID;
10588 return stack.mStackId;
10593 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10594 synchronized (this) {
10595 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10596 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10597 return stack.mDisplayId;
10599 return DEFAULT_DISPLAY;
10604 public int getActivityStackId(IBinder token) throws RemoteException {
10605 synchronized (this) {
10606 ActivityStack stack = ActivityRecord.getStackLocked(token);
10607 if (stack == null) {
10608 return INVALID_STACK_ID;
10610 return stack.mStackId;
10615 public void exitFreeformMode(IBinder token) throws RemoteException {
10616 synchronized (this) {
10617 long ident = Binder.clearCallingIdentity();
10619 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10621 throw new IllegalArgumentException(
10622 "exitFreeformMode: No activity record matching token=" + token);
10625 final ActivityStack stack = r.getStack();
10626 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10627 throw new IllegalStateException(
10628 "exitFreeformMode: You can only go fullscreen from freeform.");
10631 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10632 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10633 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10635 Binder.restoreCallingIdentity(ident);
10641 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10642 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10643 if (StackId.isHomeOrRecentsStack(stackId)) {
10644 throw new IllegalArgumentException(
10645 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10647 synchronized (this) {
10648 long ident = Binder.clearCallingIdentity();
10650 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10651 if (task == null) {
10652 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10656 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10657 + " to stackId=" + stackId + " toTop=" + toTop);
10658 if (stackId == DOCKED_STACK_ID) {
10659 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10660 null /* initialBounds */);
10662 task.reparent(stackId, toTop,
10663 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10665 Binder.restoreCallingIdentity(ident);
10671 public void swapDockedAndFullscreenStack() throws RemoteException {
10672 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10673 synchronized (this) {
10674 long ident = Binder.clearCallingIdentity();
10676 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10677 FULLSCREEN_WORKSPACE_STACK_ID);
10678 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10680 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10681 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10683 if (topTask == null || tasks == null || tasks.size() == 0) {
10685 "Unable to swap tasks, either docked or fullscreen stack is empty.");
10689 // TODO: App transition
10690 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10692 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10693 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10694 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10695 final int size = tasks.size();
10696 for (int i = 0; i < size; i++) {
10697 final int id = tasks.get(i).taskId;
10698 if (id == topTask.taskId) {
10702 // Defer the resume until after all the tasks have been moved
10703 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10704 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10705 "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10708 // Because we deferred the resume to avoid conflicts with stack switches while
10709 // resuming, we need to do it after all the tasks are moved.
10710 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10711 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10713 mWindowManager.executeAppTransition();
10715 Binder.restoreCallingIdentity(ident);
10721 * Moves the input task to the docked stack.
10723 * @param taskId Id of task to move.
10724 * @param createMode The mode the docked stack should be created in if it doesn't exist
10726 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10728 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10729 * @param toTop If the task and stack should be moved to the top.
10730 * @param animate Whether we should play an animation for the moving the task
10731 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10732 * docked stack. Pass {@code null} to use default bounds.
10735 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10736 Rect initialBounds) {
10737 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10738 synchronized (this) {
10739 long ident = Binder.clearCallingIdentity();
10741 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10742 if (task == null) {
10743 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10747 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10748 + " to createMode=" + createMode + " toTop=" + toTop);
10749 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10751 // Defer resuming until we move the home stack to the front below
10752 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10753 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10754 "moveTaskToDockedStack");
10756 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10760 Binder.restoreCallingIdentity(ident);
10766 * Moves the top activity in the input stackId to the pinned stack.
10768 * @param stackId Id of stack to move the top activity to pinned stack.
10769 * @param bounds Bounds to use for pinned stack.
10771 * @return True if the top activity of the input stack was successfully moved to the pinned
10775 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10776 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10777 synchronized (this) {
10778 if (!mSupportsPictureInPicture) {
10779 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10780 + "Device doesn't support picture-in-picture mode");
10783 long ident = Binder.clearCallingIdentity();
10785 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10787 Binder.restoreCallingIdentity(ident);
10793 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10794 boolean preserveWindows, boolean animate, int animationDuration) {
10795 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10796 long ident = Binder.clearCallingIdentity();
10798 synchronized (this) {
10800 if (stackId == PINNED_STACK_ID) {
10801 final PinnedActivityStack pinnedStack =
10802 mStackSupervisor.getStack(PINNED_STACK_ID);
10803 if (pinnedStack != null) {
10804 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10805 destBounds, animationDuration, false /* fromFullscreen */);
10808 throw new IllegalArgumentException("Stack: " + stackId
10809 + " doesn't support animated resize.");
10812 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10813 null /* tempTaskInsetBounds */, preserveWindows,
10814 allowResizeInDockedMode, !DEFER_RESUME);
10818 Binder.restoreCallingIdentity(ident);
10823 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10824 Rect tempDockedTaskInsetBounds,
10825 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10826 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10827 "resizeDockedStack()");
10828 long ident = Binder.clearCallingIdentity();
10830 synchronized (this) {
10831 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10832 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10836 Binder.restoreCallingIdentity(ident);
10841 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10842 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10843 "resizePinnedStack()");
10844 final long ident = Binder.clearCallingIdentity();
10846 synchronized (this) {
10847 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10850 Binder.restoreCallingIdentity(ident);
10855 * Try to place task to provided position. The final position might be different depending on
10856 * current user and stacks state. The task will be moved to target stack if it's currently in
10860 public void positionTaskInStack(int taskId, int stackId, int position) {
10861 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10862 if (StackId.isHomeOrRecentsStack(stackId)) {
10863 throw new IllegalArgumentException(
10864 "positionTaskInStack: Attempt to change the position of task "
10865 + taskId + " in/to home/recents stack");
10867 synchronized (this) {
10868 long ident = Binder.clearCallingIdentity();
10870 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10871 + taskId + " in stackId=" + stackId + " at position=" + position);
10872 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10873 if (task == null) {
10874 throw new IllegalArgumentException("positionTaskInStack: no task for id="
10878 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10881 // TODO: Have the callers of this API call a separate reparent method if that is
10882 // what they intended to do vs. having this method also do reparenting.
10883 if (task.getStack() == stack) {
10884 // Change position in current stack.
10885 stack.positionChildAt(task, position);
10887 // Reparent to new stack.
10888 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10889 !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10892 Binder.restoreCallingIdentity(ident);
10898 public List<StackInfo> getAllStackInfos() {
10899 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10900 long ident = Binder.clearCallingIdentity();
10902 synchronized (this) {
10903 return mStackSupervisor.getAllStackInfosLocked();
10906 Binder.restoreCallingIdentity(ident);
10911 public StackInfo getStackInfo(int stackId) {
10912 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10913 long ident = Binder.clearCallingIdentity();
10915 synchronized (this) {
10916 return mStackSupervisor.getStackInfoLocked(stackId);
10919 Binder.restoreCallingIdentity(ident);
10924 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10925 synchronized(this) {
10926 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10931 public void updateDeviceOwner(String packageName) {
10932 final int callingUid = Binder.getCallingUid();
10933 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10934 throw new SecurityException("updateDeviceOwner called from non-system process");
10936 synchronized (this) {
10937 mDeviceOwnerName = packageName;
10942 public void updateLockTaskPackages(int userId, String[] packages) {
10943 final int callingUid = Binder.getCallingUid();
10944 if (callingUid != 0 && callingUid != SYSTEM_UID) {
10945 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10946 "updateLockTaskPackages()");
10948 synchronized (this) {
10949 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10950 Arrays.toString(packages));
10951 mLockTaskPackages.put(userId, packages);
10952 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10957 void startLockTaskModeLocked(TaskRecord task) {
10958 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10959 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10963 // When a task is locked, dismiss the pinned stack if it exists
10964 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10966 if (pinnedStack != null) {
10967 mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10970 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10971 // is initiated by system after the pinning request was shown and locked mode is initiated
10972 // by an authorized app directly
10973 final int callingUid = Binder.getCallingUid();
10974 boolean isSystemInitiated = callingUid == SYSTEM_UID;
10975 long ident = Binder.clearCallingIdentity();
10977 if (!isSystemInitiated) {
10978 task.mLockTaskUid = callingUid;
10979 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10980 // startLockTask() called by app and task mode is lockTaskModeDefault.
10981 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10982 StatusBarManagerInternal statusBarManager =
10983 LocalServices.getService(StatusBarManagerInternal.class);
10984 if (statusBarManager != null) {
10985 statusBarManager.showScreenPinningRequest(task.taskId);
10990 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10991 if (stack == null || task != stack.topTask()) {
10992 throw new IllegalArgumentException("Invalid task, not in foreground");
10995 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10997 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10998 ActivityManager.LOCK_TASK_MODE_PINNED :
10999 ActivityManager.LOCK_TASK_MODE_LOCKED,
11000 "startLockTask", true);
11002 Binder.restoreCallingIdentity(ident);
11007 public void startLockTaskModeById(int taskId) {
11008 synchronized (this) {
11009 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11010 if (task != null) {
11011 startLockTaskModeLocked(task);
11017 public void startLockTaskModeByToken(IBinder token) {
11018 synchronized (this) {
11019 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11023 final TaskRecord task = r.getTask();
11024 if (task != null) {
11025 startLockTaskModeLocked(task);
11031 public void startSystemLockTaskMode(int taskId) throws RemoteException {
11032 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11033 // This makes inner call to look as if it was initiated by system.
11034 long ident = Binder.clearCallingIdentity();
11036 synchronized (this) {
11037 startLockTaskModeById(taskId);
11040 Binder.restoreCallingIdentity(ident);
11045 public void stopLockTaskMode() {
11046 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11047 if (lockTask == null) {
11048 // Our work here is done.
11052 final int callingUid = Binder.getCallingUid();
11053 final int lockTaskUid = lockTask.mLockTaskUid;
11054 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11055 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11059 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11060 // It is possible lockTaskMode was started by the system process because
11061 // android:lockTaskMode is set to a locking value in the application manifest
11062 // instead of the app calling startLockTaskMode. In this case
11063 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11064 // {@link TaskRecord.effectiveUid} instead. Also caller with
11065 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11066 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11067 && callingUid != lockTaskUid
11068 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11069 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11070 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11073 long ident = Binder.clearCallingIdentity();
11075 Log.d(TAG, "stopLockTaskMode");
11077 synchronized (this) {
11078 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11079 "stopLockTask", true);
11081 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11083 tm.showInCallScreen(false);
11086 Binder.restoreCallingIdentity(ident);
11091 * This API should be called by SystemUI only when user perform certain action to dismiss
11092 * lock task mode. We should only dismiss pinned lock task mode in this case.
11095 public void stopSystemLockTaskMode() throws RemoteException {
11096 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11097 stopLockTaskMode();
11099 mStackSupervisor.showLockTaskToast();
11104 public boolean isInLockTaskMode() {
11105 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11109 public int getLockTaskModeState() {
11110 synchronized (this) {
11111 return mStackSupervisor.getLockTaskModeState();
11116 public void showLockTaskEscapeMessage(IBinder token) {
11117 synchronized (this) {
11118 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11122 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11127 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11128 throws RemoteException {
11129 synchronized (this) {
11130 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11132 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11136 final long origId = Binder.clearCallingIdentity();
11138 r.setDisablePreviewScreenshots(disable);
11140 Binder.restoreCallingIdentity(origId);
11145 // =========================================================
11146 // CONTENT PROVIDERS
11147 // =========================================================
11149 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11150 List<ProviderInfo> providers = null;
11152 providers = AppGlobals.getPackageManager()
11153 .queryContentProviders(app.processName, app.uid,
11154 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11155 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11157 } catch (RemoteException ex) {
11159 if (DEBUG_MU) Slog.v(TAG_MU,
11160 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11161 int userId = app.userId;
11162 if (providers != null) {
11163 int N = providers.size();
11164 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11165 for (int i=0; i<N; i++) {
11166 // TODO: keep logic in sync with installEncryptionUnawareProviders
11168 (ProviderInfo)providers.get(i);
11169 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11170 cpi.name, cpi.flags);
11171 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11172 // This is a singleton provider, but a user besides the
11173 // default user is asking to initialize a process it runs
11174 // in... well, no, it doesn't actually run in this process,
11175 // it runs in the process of the default user. Get rid of it.
11176 providers.remove(i);
11182 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11183 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11185 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11186 mProviderMap.putProviderByClass(comp, cpr);
11188 if (DEBUG_MU) Slog.v(TAG_MU,
11189 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11190 app.pubProviders.put(cpi.name, cpr);
11191 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11192 // Don't add this if it is a platform component that is marked
11193 // to run in multiple processes, because this is actually
11194 // part of the framework so doesn't make sense to track as a
11195 // separate apk in the process.
11196 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11199 notifyPackageUse(cpi.applicationInfo.packageName,
11200 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11207 * Check if the calling UID has a possible chance at accessing the provider
11208 * at the given authority and user.
11210 public String checkContentProviderAccess(String authority, int userId) {
11211 if (userId == UserHandle.USER_ALL) {
11212 mContext.enforceCallingOrSelfPermission(
11213 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11214 userId = UserHandle.getCallingUserId();
11217 ProviderInfo cpi = null;
11219 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11220 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11221 | PackageManager.MATCH_DISABLED_COMPONENTS
11222 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11223 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11225 } catch (RemoteException ignored) {
11228 return "Failed to find provider " + authority + " for user " + userId
11229 + "; expected to find a valid ContentProvider for this authority";
11232 ProcessRecord r = null;
11233 synchronized (mPidsSelfLocked) {
11234 r = mPidsSelfLocked.get(Binder.getCallingPid());
11237 return "Failed to find PID " + Binder.getCallingPid();
11240 synchronized (this) {
11241 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11246 * Check if {@link ProcessRecord} has a possible chance at accessing the
11247 * given {@link ProviderInfo}. Final permission checking is always done
11248 * in {@link ContentProvider}.
11250 private final String checkContentProviderPermissionLocked(
11251 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11252 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11253 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11254 boolean checkedGrants = false;
11256 // Looking for cross-user grants before enforcing the typical cross-users permissions
11257 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11258 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11259 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11262 checkedGrants = true;
11264 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11265 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11266 if (userId != tmpTargetUserId) {
11267 // When we actually went to determine the final targer user ID, this ended
11268 // up different than our initial check for the authority. This is because
11269 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11270 // SELF. So we need to re-check the grants again.
11271 checkedGrants = false;
11274 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11275 cpi.applicationInfo.uid, cpi.exported)
11276 == PackageManager.PERMISSION_GRANTED) {
11279 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11280 cpi.applicationInfo.uid, cpi.exported)
11281 == PackageManager.PERMISSION_GRANTED) {
11285 PathPermission[] pps = cpi.pathPermissions;
11287 int i = pps.length;
11290 PathPermission pp = pps[i];
11291 String pprperm = pp.getReadPermission();
11292 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11293 cpi.applicationInfo.uid, cpi.exported)
11294 == PackageManager.PERMISSION_GRANTED) {
11297 String ppwperm = pp.getWritePermission();
11298 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11299 cpi.applicationInfo.uid, cpi.exported)
11300 == PackageManager.PERMISSION_GRANTED) {
11305 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11309 final String suffix;
11310 if (!cpi.exported) {
11311 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11312 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11313 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11315 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11317 final String msg = "Permission Denial: opening provider " + cpi.name
11318 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11319 + ", uid=" + callingUid + ")" + suffix;
11325 * Returns if the ContentProvider has granted a uri to callingUid
11327 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11328 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11329 if (perms != null) {
11330 for (int i=perms.size()-1; i>=0; i--) {
11331 GrantUri grantUri = perms.keyAt(i);
11332 if (grantUri.sourceUserId == userId || !checkUser) {
11333 if (matchesProvider(grantUri.uri, cpi)) {
11343 * Returns true if the uri authority is one of the authorities specified in the provider.
11345 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11346 String uriAuth = uri.getAuthority();
11347 String cpiAuth = cpi.authority;
11348 if (cpiAuth.indexOf(';') == -1) {
11349 return cpiAuth.equals(uriAuth);
11351 String[] cpiAuths = cpiAuth.split(";");
11352 int length = cpiAuths.length;
11353 for (int i = 0; i < length; i++) {
11354 if (cpiAuths[i].equals(uriAuth)) return true;
11359 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11360 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11362 for (int i=0; i<r.conProviders.size(); i++) {
11363 ContentProviderConnection conn = r.conProviders.get(i);
11364 if (conn.provider == cpr) {
11365 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11366 "Adding provider requested by "
11367 + r.processName + " from process "
11368 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11369 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11371 conn.stableCount++;
11372 conn.numStableIncs++;
11374 conn.unstableCount++;
11375 conn.numUnstableIncs++;
11380 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11382 conn.stableCount = 1;
11383 conn.numStableIncs = 1;
11385 conn.unstableCount = 1;
11386 conn.numUnstableIncs = 1;
11388 cpr.connections.add(conn);
11389 r.conProviders.add(conn);
11390 startAssociationLocked(r.uid, r.processName, r.curProcState,
11391 cpr.uid, cpr.name, cpr.info.processName);
11394 cpr.addExternalProcessHandleLocked(externalProcessToken);
11398 boolean decProviderCountLocked(ContentProviderConnection conn,
11399 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11400 if (conn != null) {
11401 cpr = conn.provider;
11402 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11403 "Removing provider requested by "
11404 + conn.client.processName + " from process "
11405 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11406 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11408 conn.stableCount--;
11410 conn.unstableCount--;
11412 if (conn.stableCount == 0 && conn.unstableCount == 0) {
11413 cpr.connections.remove(conn);
11414 conn.client.conProviders.remove(conn);
11415 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11416 // The client is more important than last activity -- note the time this
11417 // is happening, so we keep the old provider process around a bit as last
11418 // activity to avoid thrashing it.
11419 if (cpr.proc != null) {
11420 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11423 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11428 cpr.removeExternalProcessHandleLocked(externalProcessToken);
11432 private void checkTime(long startTime, String where) {
11433 long now = SystemClock.uptimeMillis();
11434 if ((now-startTime) > 50) {
11435 // If we are taking more than 50ms, log about it.
11436 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11440 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11442 PROC_SPACE_TERM|PROC_PARENS,
11443 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
11446 private final long[] mProcessStateStatsLongs = new long[1];
11448 boolean isProcessAliveLocked(ProcessRecord proc) {
11449 if (proc.procStatFile == null) {
11450 proc.procStatFile = "/proc/" + proc.pid + "/stat";
11452 mProcessStateStatsLongs[0] = 0;
11453 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11454 mProcessStateStatsLongs, null)) {
11455 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11458 final long state = mProcessStateStatsLongs[0];
11459 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11461 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11464 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11465 String name, IBinder token, boolean stable, int userId) {
11466 ContentProviderRecord cpr;
11467 ContentProviderConnection conn = null;
11468 ProviderInfo cpi = null;
11470 synchronized(this) {
11471 long startTime = SystemClock.uptimeMillis();
11473 ProcessRecord r = null;
11474 if (caller != null) {
11475 r = getRecordForAppLocked(caller);
11477 throw new SecurityException(
11478 "Unable to find app for caller " + caller
11479 + " (pid=" + Binder.getCallingPid()
11480 + ") when getting content provider " + name);
11484 boolean checkCrossUser = true;
11486 checkTime(startTime, "getContentProviderImpl: getProviderByName");
11488 // First check if this content provider has been published...
11489 cpr = mProviderMap.getProviderByName(name, userId);
11490 // If that didn't work, check if it exists for user 0 and then
11491 // verify that it's a singleton provider before using it.
11492 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11493 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11496 if (isSingleton(cpi.processName, cpi.applicationInfo,
11497 cpi.name, cpi.flags)
11498 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11499 userId = UserHandle.USER_SYSTEM;
11500 checkCrossUser = false;
11508 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11509 if (providerRunning) {
11512 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11513 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11515 throw new SecurityException(msg);
11517 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11519 if (r != null && cpr.canRunHere(r)) {
11520 // This provider has been published or is in the process
11521 // of being published... but it is also allowed to run
11522 // in the caller's process, so don't make a connection
11523 // and just let the caller instantiate its own instance.
11524 ContentProviderHolder holder = cpr.newHolder(null);
11525 // don't give caller the provider object, it needs
11526 // to make its own.
11527 holder.provider = null;
11530 // Don't expose providers between normal apps and instant apps
11532 if (AppGlobals.getPackageManager()
11533 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11536 } catch (RemoteException e) {
11539 final long origId = Binder.clearCallingIdentity();
11541 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11543 // In this case the provider instance already exists, so we can
11544 // return it right away.
11545 conn = incProviderCountLocked(r, cpr, token, stable);
11546 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11547 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11548 // If this is a perceptible app accessing the provider,
11549 // make sure to count it as being accessed and thus
11550 // back up on the LRU list. This is good because
11551 // content providers are often expensive to start.
11552 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11553 updateLruProcessLocked(cpr.proc, false, null);
11554 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11558 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11559 final int verifiedAdj = cpr.proc.verifiedAdj;
11560 boolean success = updateOomAdjLocked(cpr.proc, true);
11561 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11562 // if the process has been successfully adjusted. So to reduce races with
11563 // it, we will check whether the process still exists. Note that this doesn't
11564 // completely get rid of races with LMK killing the process, but should make
11565 // them much smaller.
11566 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11569 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11570 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11571 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11572 // NOTE: there is still a race here where a signal could be
11573 // pending on the process even though we managed to update its
11574 // adj level. Not sure what to do about this, but at least
11575 // the race is now smaller.
11577 // Uh oh... it looks like the provider's process
11578 // has been killed on us. We need to wait for a new
11579 // process to be started, and make sure its death
11580 // doesn't kill our process.
11581 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11582 + " is crashing; detaching " + r);
11583 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11584 checkTime(startTime, "getContentProviderImpl: before appDied");
11585 appDiedLocked(cpr.proc);
11586 checkTime(startTime, "getContentProviderImpl: after appDied");
11588 // This wasn't the last ref our process had on
11589 // the provider... we have now been killed, bail.
11592 providerRunning = false;
11595 cpr.proc.verifiedAdj = cpr.proc.setAdj;
11598 Binder.restoreCallingIdentity(origId);
11601 if (!providerRunning) {
11603 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11604 cpi = AppGlobals.getPackageManager().
11605 resolveContentProvider(name,
11606 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11607 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11608 } catch (RemoteException ex) {
11613 // If the provider is a singleton AND
11614 // (it's a call within the same user || the provider is a
11616 // Then allow connecting to the singleton provider
11617 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11618 cpi.name, cpi.flags)
11619 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11621 userId = UserHandle.USER_SYSTEM;
11623 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11624 checkTime(startTime, "getContentProviderImpl: got app info for user");
11627 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11628 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11630 throw new SecurityException(msg);
11632 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11634 if (!mProcessesReady
11635 && !cpi.processName.equals("system")) {
11636 // If this content provider does not run in the system
11637 // process, and the system is not yet ready to run other
11638 // processes, then fail fast instead of hanging.
11639 throw new IllegalArgumentException(
11640 "Attempt to launch content provider before system ready");
11643 // Make sure that the user who owns this provider is running. If not,
11644 // we don't want to allow it to run.
11645 if (!mUserController.isUserRunningLocked(userId, 0)) {
11646 Slog.w(TAG, "Unable to launch app "
11647 + cpi.applicationInfo.packageName + "/"
11648 + cpi.applicationInfo.uid + " for provider "
11649 + name + ": user " + userId + " is stopped");
11653 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11654 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11655 cpr = mProviderMap.getProviderByClass(comp, userId);
11656 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11657 final boolean firstClass = cpr == null;
11659 final long ident = Binder.clearCallingIdentity();
11661 // If permissions need a review before any of the app components can run,
11662 // we return no provider and launch a review activity if the calling app
11663 // is in the foreground.
11664 if (mPermissionReviewRequired) {
11665 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11671 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11672 ApplicationInfo ai =
11673 AppGlobals.getPackageManager().
11674 getApplicationInfo(
11675 cpi.applicationInfo.packageName,
11676 STOCK_PM_FLAGS, userId);
11677 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11679 Slog.w(TAG, "No package info for content provider "
11683 ai = getAppInfoForUser(ai, userId);
11684 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11685 } catch (RemoteException ex) {
11686 // pm is in same process, this will never happen.
11688 Binder.restoreCallingIdentity(ident);
11692 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11694 if (r != null && cpr.canRunHere(r)) {
11695 // If this is a multiprocess provider, then just return its
11696 // info and allow the caller to instantiate it. Only do
11697 // this if the provider is the same user as the caller's
11698 // process, or can run as root (so can be in any process).
11699 return cpr.newHolder(null);
11702 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11703 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11704 + cpr.info.name + " callers=" + Debug.getCallers(6));
11706 // This is single process, and our app is now connecting to it.
11707 // See if we are already in the process of launching this
11709 final int N = mLaunchingProviders.size();
11711 for (i = 0; i < N; i++) {
11712 if (mLaunchingProviders.get(i) == cpr) {
11717 // If the provider is not already being launched, then get it
11720 final long origId = Binder.clearCallingIdentity();
11723 // Content provider is now in use, its package can't be stopped.
11725 checkTime(startTime, "getContentProviderImpl: before set stopped state");
11726 AppGlobals.getPackageManager().setPackageStoppedState(
11727 cpr.appInfo.packageName, false, userId);
11728 checkTime(startTime, "getContentProviderImpl: after set stopped state");
11729 } catch (RemoteException e) {
11730 } catch (IllegalArgumentException e) {
11731 Slog.w(TAG, "Failed trying to unstop package "
11732 + cpr.appInfo.packageName + ": " + e);
11735 // Use existing process if already started
11736 checkTime(startTime, "getContentProviderImpl: looking for process record");
11737 ProcessRecord proc = getProcessRecordLocked(
11738 cpi.processName, cpr.appInfo.uid, false);
11739 if (proc != null && proc.thread != null && !proc.killed) {
11740 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11741 "Installing in existing process " + proc);
11742 if (!proc.pubProviders.containsKey(cpi.name)) {
11743 checkTime(startTime, "getContentProviderImpl: scheduling install");
11744 proc.pubProviders.put(cpi.name, cpr);
11746 proc.thread.scheduleInstallProvider(cpi);
11747 } catch (RemoteException e) {
11751 checkTime(startTime, "getContentProviderImpl: before start process");
11752 proc = startProcessLocked(cpi.processName,
11753 cpr.appInfo, false, 0, "content provider",
11754 new ComponentName(cpi.applicationInfo.packageName,
11755 cpi.name), false, false, false);
11756 checkTime(startTime, "getContentProviderImpl: after start process");
11757 if (proc == null) {
11758 Slog.w(TAG, "Unable to launch app "
11759 + cpi.applicationInfo.packageName + "/"
11760 + cpi.applicationInfo.uid + " for provider "
11761 + name + ": process is bad");
11765 cpr.launchingApp = proc;
11766 mLaunchingProviders.add(cpr);
11768 Binder.restoreCallingIdentity(origId);
11772 checkTime(startTime, "getContentProviderImpl: updating data structures");
11774 // Make sure the provider is published (the same provider class
11775 // may be published under multiple names).
11777 mProviderMap.putProviderByClass(comp, cpr);
11780 mProviderMap.putProviderByName(name, cpr);
11781 conn = incProviderCountLocked(r, cpr, token, stable);
11782 if (conn != null) {
11783 conn.waiting = true;
11786 checkTime(startTime, "getContentProviderImpl: done!");
11788 grantEphemeralAccessLocked(userId, null /*intent*/,
11789 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11792 // Wait for the provider to be published...
11793 synchronized (cpr) {
11794 while (cpr.provider == null) {
11795 if (cpr.launchingApp == null) {
11796 Slog.w(TAG, "Unable to launch app "
11797 + cpi.applicationInfo.packageName + "/"
11798 + cpi.applicationInfo.uid + " for provider "
11799 + name + ": launching app became null");
11800 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11801 UserHandle.getUserId(cpi.applicationInfo.uid),
11802 cpi.applicationInfo.packageName,
11803 cpi.applicationInfo.uid, name);
11807 if (DEBUG_MU) Slog.v(TAG_MU,
11808 "Waiting to start provider " + cpr
11809 + " launchingApp=" + cpr.launchingApp);
11810 if (conn != null) {
11811 conn.waiting = true;
11814 } catch (InterruptedException ex) {
11816 if (conn != null) {
11817 conn.waiting = false;
11822 return cpr != null ? cpr.newHolder(conn) : null;
11825 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11826 ProcessRecord r, final int userId) {
11827 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11828 cpi.packageName, userId)) {
11830 final boolean callerForeground = r == null || r.setSchedGroup
11831 != ProcessList.SCHED_GROUP_BACKGROUND;
11833 // Show a permission review UI only for starting from a foreground app
11834 if (!callerForeground) {
11835 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11836 + cpi.packageName + " requires a permissions review");
11840 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11841 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11842 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11843 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11845 if (DEBUG_PERMISSIONS_REVIEW) {
11846 Slog.i(TAG, "u" + userId + " Launching permission review "
11847 + "for package " + cpi.packageName);
11850 final UserHandle userHandle = new UserHandle(userId);
11851 mHandler.post(new Runnable() {
11853 public void run() {
11854 mContext.startActivityAsUser(intent, userHandle);
11864 PackageManagerInternal getPackageManagerInternalLocked() {
11865 if (mPackageManagerInt == null) {
11866 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11868 return mPackageManagerInt;
11872 public final ContentProviderHolder getContentProvider(
11873 IApplicationThread caller, String name, int userId, boolean stable) {
11874 enforceNotIsolatedCaller("getContentProvider");
11875 if (caller == null) {
11876 String msg = "null IApplicationThread when getting content provider "
11879 throw new SecurityException(msg);
11881 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11882 // with cross-user grant.
11883 return getContentProviderImpl(caller, name, null, stable, userId);
11886 public ContentProviderHolder getContentProviderExternal(
11887 String name, int userId, IBinder token) {
11888 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11889 "Do not have permission in call getContentProviderExternal()");
11890 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11891 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11892 return getContentProviderExternalUnchecked(name, token, userId);
11895 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11896 IBinder token, int userId) {
11897 return getContentProviderImpl(null, name, token, true, userId);
11901 * Drop a content provider from a ProcessRecord's bookkeeping
11903 public void removeContentProvider(IBinder connection, boolean stable) {
11904 enforceNotIsolatedCaller("removeContentProvider");
11905 long ident = Binder.clearCallingIdentity();
11907 synchronized (this) {
11908 ContentProviderConnection conn;
11910 conn = (ContentProviderConnection)connection;
11911 } catch (ClassCastException e) {
11912 String msg ="removeContentProvider: " + connection
11913 + " not a ContentProviderConnection";
11915 throw new IllegalArgumentException(msg);
11917 if (conn == null) {
11918 throw new NullPointerException("connection is null");
11920 if (decProviderCountLocked(conn, null, null, stable)) {
11921 updateOomAdjLocked();
11925 Binder.restoreCallingIdentity(ident);
11929 public void removeContentProviderExternal(String name, IBinder token) {
11930 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11931 "Do not have permission in call removeContentProviderExternal()");
11932 int userId = UserHandle.getCallingUserId();
11933 long ident = Binder.clearCallingIdentity();
11935 removeContentProviderExternalUnchecked(name, token, userId);
11937 Binder.restoreCallingIdentity(ident);
11941 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11942 synchronized (this) {
11943 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11945 //remove from mProvidersByClass
11946 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11950 //update content provider record entry info
11951 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11952 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11953 if (localCpr.hasExternalProcessHandles()) {
11954 if (localCpr.removeExternalProcessHandleLocked(token)) {
11955 updateOomAdjLocked();
11957 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11958 + " with no external reference for token: "
11962 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11963 + " with no external references.");
11968 public final void publishContentProviders(IApplicationThread caller,
11969 List<ContentProviderHolder> providers) {
11970 if (providers == null) {
11974 enforceNotIsolatedCaller("publishContentProviders");
11975 synchronized (this) {
11976 final ProcessRecord r = getRecordForAppLocked(caller);
11977 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11979 throw new SecurityException(
11980 "Unable to find app for caller " + caller
11981 + " (pid=" + Binder.getCallingPid()
11982 + ") when publishing content providers");
11985 final long origId = Binder.clearCallingIdentity();
11987 final int N = providers.size();
11988 for (int i = 0; i < N; i++) {
11989 ContentProviderHolder src = providers.get(i);
11990 if (src == null || src.info == null || src.provider == null) {
11993 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11994 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11996 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11997 mProviderMap.putProviderByClass(comp, dst);
11998 String names[] = dst.info.authority.split(";");
11999 for (int j = 0; j < names.length; j++) {
12000 mProviderMap.putProviderByName(names[j], dst);
12003 int launchingCount = mLaunchingProviders.size();
12005 boolean wasInLaunchingProviders = false;
12006 for (j = 0; j < launchingCount; j++) {
12007 if (mLaunchingProviders.get(j) == dst) {
12008 mLaunchingProviders.remove(j);
12009 wasInLaunchingProviders = true;
12014 if (wasInLaunchingProviders) {
12015 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12017 synchronized (dst) {
12018 dst.provider = src.provider;
12022 updateOomAdjLocked(r, true);
12023 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12024 src.info.authority);
12028 Binder.restoreCallingIdentity(origId);
12032 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12033 ContentProviderConnection conn;
12035 conn = (ContentProviderConnection)connection;
12036 } catch (ClassCastException e) {
12037 String msg ="refContentProvider: " + connection
12038 + " not a ContentProviderConnection";
12040 throw new IllegalArgumentException(msg);
12042 if (conn == null) {
12043 throw new NullPointerException("connection is null");
12046 synchronized (this) {
12048 conn.numStableIncs += stable;
12050 stable = conn.stableCount + stable;
12052 throw new IllegalStateException("stableCount < 0: " + stable);
12055 if (unstable > 0) {
12056 conn.numUnstableIncs += unstable;
12058 unstable = conn.unstableCount + unstable;
12059 if (unstable < 0) {
12060 throw new IllegalStateException("unstableCount < 0: " + unstable);
12063 if ((stable+unstable) <= 0) {
12064 throw new IllegalStateException("ref counts can't go to zero here: stable="
12065 + stable + " unstable=" + unstable);
12067 conn.stableCount = stable;
12068 conn.unstableCount = unstable;
12073 public void unstableProviderDied(IBinder connection) {
12074 ContentProviderConnection conn;
12076 conn = (ContentProviderConnection)connection;
12077 } catch (ClassCastException e) {
12078 String msg ="refContentProvider: " + connection
12079 + " not a ContentProviderConnection";
12081 throw new IllegalArgumentException(msg);
12083 if (conn == null) {
12084 throw new NullPointerException("connection is null");
12087 // Safely retrieve the content provider associated with the connection.
12088 IContentProvider provider;
12089 synchronized (this) {
12090 provider = conn.provider.provider;
12093 if (provider == null) {
12094 // Um, yeah, we're way ahead of you.
12098 // Make sure the caller is being honest with us.
12099 if (provider.asBinder().pingBinder()) {
12100 // Er, no, still looks good to us.
12101 synchronized (this) {
12102 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12103 + " says " + conn + " died, but we don't agree");
12108 // Well look at that! It's dead!
12109 synchronized (this) {
12110 if (conn.provider.provider != provider) {
12111 // But something changed... good enough.
12115 ProcessRecord proc = conn.provider.proc;
12116 if (proc == null || proc.thread == null) {
12117 // Seems like the process is already cleaned up.
12121 // As far as we're concerned, this is just like receiving a
12122 // death notification... just a bit prematurely.
12123 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12124 + ") early provider death");
12125 final long ident = Binder.clearCallingIdentity();
12127 appDiedLocked(proc);
12129 Binder.restoreCallingIdentity(ident);
12135 public void appNotRespondingViaProvider(IBinder connection) {
12136 enforceCallingPermission(
12137 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12139 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12140 if (conn == null) {
12141 Slog.w(TAG, "ContentProviderConnection is null");
12145 final ProcessRecord host = conn.provider.proc;
12146 if (host == null) {
12147 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12151 mHandler.post(new Runnable() {
12153 public void run() {
12154 mAppErrors.appNotResponding(host, null, null, false,
12155 "ContentProvider not responding");
12160 public final void installSystemProviders() {
12161 List<ProviderInfo> providers;
12162 synchronized (this) {
12163 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12164 providers = generateApplicationProvidersLocked(app);
12165 if (providers != null) {
12166 for (int i=providers.size()-1; i>=0; i--) {
12167 ProviderInfo pi = (ProviderInfo)providers.get(i);
12168 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12169 Slog.w(TAG, "Not installing system proc provider " + pi.name
12170 + ": not system .apk");
12171 providers.remove(i);
12176 if (providers != null) {
12177 mSystemThread.installSystemProviders(providers);
12180 mConstants.start(mContext.getContentResolver());
12181 mCoreSettingsObserver = new CoreSettingsObserver(this);
12182 mFontScaleSettingObserver = new FontScaleSettingObserver();
12184 // Now that the settings provider is published we can consider sending
12185 // in a rescue party.
12186 RescueParty.onSettingsProviderPublished(mContext);
12188 //mUsageStatsService.monitorPackages();
12191 private void startPersistentApps(int matchFlags) {
12192 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12194 synchronized (this) {
12196 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12197 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12198 for (ApplicationInfo app : apps) {
12199 if (!"android".equals(app.packageName)) {
12200 addAppLocked(app, null, false, null /* ABI override */);
12203 } catch (RemoteException ex) {
12209 * When a user is unlocked, we need to install encryption-unaware providers
12210 * belonging to any running apps.
12212 private void installEncryptionUnawareProviders(int userId) {
12213 // We're only interested in providers that are encryption unaware, and
12214 // we don't care about uninstalled apps, since there's no way they're
12215 // running at this point.
12216 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12218 synchronized (this) {
12219 final int NP = mProcessNames.getMap().size();
12220 for (int ip = 0; ip < NP; ip++) {
12221 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12222 final int NA = apps.size();
12223 for (int ia = 0; ia < NA; ia++) {
12224 final ProcessRecord app = apps.valueAt(ia);
12225 if (app.userId != userId || app.thread == null || app.unlocked) continue;
12227 final int NG = app.pkgList.size();
12228 for (int ig = 0; ig < NG; ig++) {
12230 final String pkgName = app.pkgList.keyAt(ig);
12231 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12232 .getPackageInfo(pkgName, matchFlags, userId);
12233 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12234 for (ProviderInfo pi : pkgInfo.providers) {
12235 // TODO: keep in sync with generateApplicationProvidersLocked
12236 final boolean processMatch = Objects.equals(pi.processName,
12237 app.processName) || pi.multiprocess;
12238 final boolean userMatch = isSingleton(pi.processName,
12239 pi.applicationInfo, pi.name, pi.flags)
12240 ? (app.userId == UserHandle.USER_SYSTEM) : true;
12241 if (processMatch && userMatch) {
12242 Log.v(TAG, "Installing " + pi);
12243 app.thread.scheduleInstallProvider(pi);
12245 Log.v(TAG, "Skipping " + pi);
12249 } catch (RemoteException ignored) {
12258 * Allows apps to retrieve the MIME type of a URI.
12259 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12260 * users, then it does not need permission to access the ContentProvider.
12261 * Either, it needs cross-user uri grants.
12263 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12265 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12266 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12268 public String getProviderMimeType(Uri uri, int userId) {
12269 enforceNotIsolatedCaller("getProviderMimeType");
12270 final String name = uri.getAuthority();
12271 int callingUid = Binder.getCallingUid();
12272 int callingPid = Binder.getCallingPid();
12274 boolean clearedIdentity = false;
12275 synchronized (this) {
12276 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12278 if (canClearIdentity(callingPid, callingUid, userId)) {
12279 clearedIdentity = true;
12280 ident = Binder.clearCallingIdentity();
12282 ContentProviderHolder holder = null;
12284 holder = getContentProviderExternalUnchecked(name, null, userId);
12285 if (holder != null) {
12286 return holder.provider.getType(uri);
12288 } catch (RemoteException e) {
12289 Log.w(TAG, "Content provider dead retrieving " + uri, e);
12291 } catch (Exception e) {
12292 Log.w(TAG, "Exception while determining type of " + uri, e);
12295 // We need to clear the identity to call removeContentProviderExternalUnchecked
12296 if (!clearedIdentity) {
12297 ident = Binder.clearCallingIdentity();
12300 if (holder != null) {
12301 removeContentProviderExternalUnchecked(name, null, userId);
12304 Binder.restoreCallingIdentity(ident);
12311 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12312 if (UserHandle.getUserId(callingUid) == userId) {
12315 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12316 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12317 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12318 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12324 // =========================================================
12325 // GLOBAL MANAGEMENT
12326 // =========================================================
12328 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12329 boolean isolated, int isolatedUid) {
12330 String proc = customProcess != null ? customProcess : info.processName;
12331 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12332 final int userId = UserHandle.getUserId(info.uid);
12333 int uid = info.uid;
12335 if (isolatedUid == 0) {
12336 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12338 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12339 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12340 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12342 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12343 mNextIsolatedProcessUid++;
12344 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12345 // No process for this uid, use it.
12349 if (stepsLeft <= 0) {
12354 // Special case for startIsolatedProcess (internal only), where
12355 // the uid of the isolated process is specified by the caller.
12358 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12360 // Register the isolated UID with this application so BatteryStats knows to
12361 // attribute resource usage to the application.
12363 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12364 // about the process state of the isolated UID *before* it is registered with the
12365 // owning application.
12366 mBatteryStatsService.addIsolatedUid(uid, info.uid);
12368 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12369 if (!mBooted && !mBooting
12370 && userId == UserHandle.USER_SYSTEM
12371 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12372 r.persistent = true;
12373 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12375 addProcessNameLocked(r);
12379 private boolean uidOnBackgroundWhitelist(final int uid) {
12380 final int appId = UserHandle.getAppId(uid);
12381 final int[] whitelist = mBackgroundAppIdWhitelist;
12382 final int N = whitelist.length;
12383 for (int i = 0; i < N; i++) {
12384 if (appId == whitelist[i]) {
12392 public void backgroundWhitelistUid(final int uid) {
12393 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12394 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12397 if (DEBUG_BACKGROUND_CHECK) {
12398 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12400 synchronized (this) {
12401 final int N = mBackgroundAppIdWhitelist.length;
12402 int[] newList = new int[N+1];
12403 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12404 newList[N] = UserHandle.getAppId(uid);
12405 mBackgroundAppIdWhitelist = newList;
12409 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12410 String abiOverride) {
12413 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12420 app = newProcessRecordLocked(info, customProcess, isolated, 0);
12421 updateLruProcessLocked(app, false, null);
12422 updateOomAdjLocked();
12425 // This package really, really can not be stopped.
12427 AppGlobals.getPackageManager().setPackageStoppedState(
12428 info.packageName, false, UserHandle.getUserId(app.uid));
12429 } catch (RemoteException e) {
12430 } catch (IllegalArgumentException e) {
12431 Slog.w(TAG, "Failed trying to unstop package "
12432 + info.packageName + ": " + e);
12435 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12436 app.persistent = true;
12437 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12439 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12440 mPersistentStartingProcesses.add(app);
12441 startProcessLocked(app, "added application",
12442 customProcess != null ? customProcess : app.processName, abiOverride,
12443 null /* entryPoint */, null /* entryPointArgs */);
12449 public void unhandledBack() {
12450 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12451 "unhandledBack()");
12453 synchronized(this) {
12454 final long origId = Binder.clearCallingIdentity();
12456 getFocusedStack().unhandledBackLocked();
12458 Binder.restoreCallingIdentity(origId);
12463 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12464 enforceNotIsolatedCaller("openContentUri");
12465 final int userId = UserHandle.getCallingUserId();
12466 final Uri uri = Uri.parse(uriString);
12467 String name = uri.getAuthority();
12468 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12469 ParcelFileDescriptor pfd = null;
12471 // We record the binder invoker's uid in thread-local storage before
12472 // going to the content provider to open the file. Later, in the code
12473 // that handles all permissions checks, we look for this uid and use
12474 // that rather than the Activity Manager's own uid. The effect is that
12475 // we do the check against the caller's permissions even though it looks
12476 // to the content provider like the Activity Manager itself is making
12478 Binder token = new Binder();
12479 sCallerIdentity.set(new Identity(
12480 token, Binder.getCallingPid(), Binder.getCallingUid()));
12482 pfd = cph.provider.openFile(null, uri, "r", null, token);
12483 } catch (FileNotFoundException e) {
12484 // do nothing; pfd will be returned null
12486 // Ensure that whatever happens, we clean up the identity state
12487 sCallerIdentity.remove();
12488 // Ensure we're done with the provider.
12489 removeContentProviderExternalUnchecked(name, null, userId);
12492 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12497 // Actually is sleeping or shutting down or whatever else in the future
12498 // is an inactive state.
12499 boolean isSleepingOrShuttingDownLocked() {
12500 return isSleepingLocked() || mShuttingDown;
12503 boolean isShuttingDownLocked() {
12504 return mShuttingDown;
12507 boolean isSleepingLocked() {
12511 void onWakefulnessChanged(int wakefulness) {
12512 synchronized(this) {
12513 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12514 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12515 mWakefulness = wakefulness;
12517 if (wasAwake != isAwake) {
12518 // Also update state in a special way for running foreground services UI.
12519 mServices.updateScreenStateLocked(isAwake);
12520 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12526 void finishRunningVoiceLocked() {
12527 if (mRunningVoice != null) {
12528 mRunningVoice = null;
12529 mVoiceWakeLock.release();
12530 updateSleepIfNeededLocked();
12534 void startTimeTrackingFocusedActivityLocked() {
12535 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12536 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12537 mCurAppTimeTracker.start(resumedActivity.packageName);
12541 void updateSleepIfNeededLocked() {
12542 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12543 final boolean wasSleeping = mSleeping;
12545 if (!shouldSleep) {
12546 // If wasSleeping is true, we need to wake up activity manager state from when
12547 // we started sleeping. In either case, we need to apply the sleep tokens, which
12548 // will wake up stacks or put them to sleep as appropriate.
12551 startTimeTrackingFocusedActivityLocked();
12552 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12553 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12555 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12557 updateOomAdjLocked();
12559 } else if (!mSleeping && shouldSleep) {
12561 if (mCurAppTimeTracker != null) {
12562 mCurAppTimeTracker.stop();
12564 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12565 mStackSupervisor.goingToSleepLocked();
12566 updateOomAdjLocked();
12570 /** Pokes the task persister. */
12571 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12572 mRecentTasks.notifyTaskPersisterLocked(task, flush);
12576 * Notifies all listeners when the pinned stack animation starts.
12579 public void notifyPinnedStackAnimationStarted() {
12580 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12584 * Notifies all listeners when the pinned stack animation ends.
12587 public void notifyPinnedStackAnimationEnded() {
12588 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12592 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12593 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12597 public boolean shutdown(int timeout) {
12598 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12599 != PackageManager.PERMISSION_GRANTED) {
12600 throw new SecurityException("Requires permission "
12601 + android.Manifest.permission.SHUTDOWN);
12604 boolean timedout = false;
12606 synchronized(this) {
12607 mShuttingDown = true;
12608 mStackSupervisor.prepareForShutdownLocked();
12609 updateEventDispatchingLocked();
12610 timedout = mStackSupervisor.shutdownLocked(timeout);
12613 mAppOpsService.shutdown();
12614 if (mUsageStatsService != null) {
12615 mUsageStatsService.prepareShutdown();
12617 mBatteryStatsService.shutdown();
12618 synchronized (this) {
12619 mProcessStats.shutdownLocked();
12620 notifyTaskPersisterLocked(null, true);
12626 public final void activitySlept(IBinder token) {
12627 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12629 final long origId = Binder.clearCallingIdentity();
12631 synchronized (this) {
12632 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12634 mStackSupervisor.activitySleptLocked(r);
12638 Binder.restoreCallingIdentity(origId);
12641 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12642 Slog.d(TAG, "<<< startRunningVoiceLocked()");
12643 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12644 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12645 boolean wasRunningVoice = mRunningVoice != null;
12646 mRunningVoice = session;
12647 if (!wasRunningVoice) {
12648 mVoiceWakeLock.acquire();
12649 updateSleepIfNeededLocked();
12654 private void updateEventDispatchingLocked() {
12655 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12659 public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12660 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12661 != PackageManager.PERMISSION_GRANTED) {
12662 throw new SecurityException("Requires permission "
12663 + android.Manifest.permission.DEVICE_POWER);
12666 synchronized(this) {
12667 long ident = Binder.clearCallingIdentity();
12669 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12671 Binder.restoreCallingIdentity(ident);
12675 mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12680 public void notifyLockedProfile(@UserIdInt int userId) {
12682 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12683 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12685 } catch (RemoteException ex) {
12686 throw new SecurityException("Fail to check is caller a privileged app", ex);
12689 synchronized (this) {
12690 final long ident = Binder.clearCallingIdentity();
12692 if (mUserController.shouldConfirmCredentials(userId)) {
12693 if (mKeyguardController.isKeyguardLocked()) {
12694 // Showing launcher to avoid user entering credential twice.
12695 final int currentUserId = mUserController.getCurrentUserIdLocked();
12696 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12698 mStackSupervisor.lockAllProfileTasks(userId);
12701 Binder.restoreCallingIdentity(ident);
12707 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12708 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12709 synchronized (this) {
12710 final long ident = Binder.clearCallingIdentity();
12712 mActivityStarter.startConfirmCredentialIntent(intent, options);
12714 Binder.restoreCallingIdentity(ident);
12720 public void stopAppSwitches() {
12721 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12722 != PackageManager.PERMISSION_GRANTED) {
12723 throw new SecurityException("viewquires permission "
12724 + android.Manifest.permission.STOP_APP_SWITCHES);
12727 synchronized(this) {
12728 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12729 + APP_SWITCH_DELAY_TIME;
12730 mDidAppSwitch = false;
12731 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12732 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12733 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12737 public void resumeAppSwitches() {
12738 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12739 != PackageManager.PERMISSION_GRANTED) {
12740 throw new SecurityException("Requires permission "
12741 + android.Manifest.permission.STOP_APP_SWITCHES);
12744 synchronized(this) {
12745 // Note that we don't execute any pending app switches... we will
12746 // let those wait until either the timeout, or the next start
12747 // activity request.
12748 mAppSwitchesAllowedTime = 0;
12752 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12753 int callingPid, int callingUid, String name) {
12754 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12758 int perm = checkComponentPermission(
12759 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12760 sourceUid, -1, true);
12761 if (perm == PackageManager.PERMISSION_GRANTED) {
12765 // If the actual IPC caller is different from the logical source, then
12766 // also see if they are allowed to control app switches.
12767 if (callingUid != -1 && callingUid != sourceUid) {
12768 perm = checkComponentPermission(
12769 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12770 callingUid, -1, true);
12771 if (perm == PackageManager.PERMISSION_GRANTED) {
12776 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12780 public void setDebugApp(String packageName, boolean waitForDebugger,
12781 boolean persistent) {
12782 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12785 long ident = Binder.clearCallingIdentity();
12787 // Note that this is not really thread safe if there are multiple
12788 // callers into it at the same time, but that's not a situation we
12791 final ContentResolver resolver = mContext.getContentResolver();
12792 Settings.Global.putString(
12793 resolver, Settings.Global.DEBUG_APP,
12795 Settings.Global.putInt(
12796 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12797 waitForDebugger ? 1 : 0);
12800 synchronized (this) {
12802 mOrigDebugApp = mDebugApp;
12803 mOrigWaitForDebugger = mWaitForDebugger;
12805 mDebugApp = packageName;
12806 mWaitForDebugger = waitForDebugger;
12807 mDebugTransient = !persistent;
12808 if (packageName != null) {
12809 forceStopPackageLocked(packageName, -1, false, false, true, true,
12810 false, UserHandle.USER_ALL, "set debug app");
12814 Binder.restoreCallingIdentity(ident);
12819 * Set or remove an agent to be run whenever an app with the given process name starts.
12821 * This method will not check whether the given process name matches a debuggable app. That
12822 * would require scanning all current packages, and a rescan when new packages are installed
12825 * Instead, do the check when an application is started and matched to a stored agent.
12827 * @param packageName the process name of the app.
12828 * @param agent the agent string to be used, or null to remove any previously set agent.
12831 public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
12832 synchronized (this) {
12833 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
12834 // its own permission.
12835 if (checkCallingPermission(
12836 android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
12837 PackageManager.PERMISSION_GRANTED) {
12838 throw new SecurityException(
12839 "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12842 if (agent == null) {
12843 if (mAppAgentMap != null) {
12844 mAppAgentMap.remove(packageName);
12845 if (mAppAgentMap.isEmpty()) {
12846 mAppAgentMap = null;
12850 if (mAppAgentMap == null) {
12851 mAppAgentMap = new HashMap<>();
12853 if (mAppAgentMap.size() >= 100) {
12854 // Limit the size of the map, to avoid OOMEs.
12855 Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
12859 mAppAgentMap.put(packageName, agent);
12864 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12865 synchronized (this) {
12866 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12867 if (!isDebuggable) {
12868 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12869 throw new SecurityException("Process not debuggable: " + app.packageName);
12873 mTrackAllocationApp = processName;
12877 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12878 synchronized (this) {
12879 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12880 if (!isDebuggable) {
12881 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12882 throw new SecurityException("Process not debuggable: " + app.packageName);
12885 mProfileApp = processName;
12887 if (mProfilerInfo != null) {
12888 if (mProfilerInfo.profileFd != null) {
12890 mProfilerInfo.profileFd.close();
12891 } catch (IOException e) {
12895 mProfilerInfo = new ProfilerInfo(profilerInfo);
12900 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12901 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12902 if (!isDebuggable) {
12903 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12904 throw new SecurityException("Process not debuggable: " + app.packageName);
12907 mNativeDebuggingApp = processName;
12911 public void setAlwaysFinish(boolean enabled) {
12912 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12913 "setAlwaysFinish()");
12915 long ident = Binder.clearCallingIdentity();
12917 Settings.Global.putInt(
12918 mContext.getContentResolver(),
12919 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12921 synchronized (this) {
12922 mAlwaysFinishActivities = enabled;
12925 Binder.restoreCallingIdentity(ident);
12930 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12931 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12932 "setActivityController()");
12933 synchronized (this) {
12934 mController = controller;
12935 mControllerIsAMonkey = imAMonkey;
12936 Watchdog.getInstance().setActivityController(controller);
12941 public void setUserIsMonkey(boolean userIsMonkey) {
12942 synchronized (this) {
12943 synchronized (mPidsSelfLocked) {
12944 final int callingPid = Binder.getCallingPid();
12945 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12946 if (proc == null) {
12947 throw new SecurityException("Unknown process: " + callingPid);
12949 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12950 throw new SecurityException("Only an instrumentation process "
12951 + "with a UiAutomation can call setUserIsMonkey");
12954 mUserIsMonkey = userIsMonkey;
12959 public boolean isUserAMonkey() {
12960 synchronized (this) {
12961 // If there is a controller also implies the user is a monkey.
12962 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12967 * @deprecated This method is only used by a few internal components and it will soon be
12968 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12969 * No new code should be calling it.
12973 public void requestBugReport(int bugreportType) {
12974 String extraOptions = null;
12975 switch (bugreportType) {
12976 case ActivityManager.BUGREPORT_OPTION_FULL:
12977 // Default options.
12979 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12980 extraOptions = "bugreportplus";
12982 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12983 extraOptions = "bugreportremote";
12985 case ActivityManager.BUGREPORT_OPTION_WEAR:
12986 extraOptions = "bugreportwear";
12988 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12989 extraOptions = "bugreporttelephony";
12992 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12995 // Always log caller, even if it does not have permission to dump.
12996 String type = extraOptions == null ? "bugreport" : extraOptions;
12997 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12999 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13000 if (extraOptions != null) {
13001 SystemProperties.set("dumpstate.options", extraOptions);
13003 SystemProperties.set("ctl.start", "bugreport");
13007 * @deprecated This method is only used by a few internal components and it will soon be
13008 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13009 * No new code should be calling it.
13013 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13015 if (!TextUtils.isEmpty(shareTitle)) {
13016 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13017 String errorStr = "shareTitle should be less than " +
13018 MAX_BUGREPORT_TITLE_SIZE + " characters";
13019 throw new IllegalArgumentException(errorStr);
13021 if (!TextUtils.isEmpty(shareDescription)) {
13024 length = shareDescription.getBytes("UTF-8").length;
13025 } catch (UnsupportedEncodingException e) {
13026 String errorStr = "shareDescription: UnsupportedEncodingException";
13027 throw new IllegalArgumentException(errorStr);
13029 if (length > SystemProperties.PROP_VALUE_MAX) {
13030 String errorStr = "shareTitle should be less than " +
13031 SystemProperties.PROP_VALUE_MAX + " bytes";
13032 throw new IllegalArgumentException(errorStr);
13034 SystemProperties.set("dumpstate.options.description", shareDescription);
13037 SystemProperties.set("dumpstate.options.title", shareTitle);
13041 Slog.d(TAG, "Bugreport notification title " + shareTitle
13042 + " description " + shareDescription);
13043 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13046 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13047 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13050 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13051 if (r != null && (r.instr != null || r.usingWrapper)) {
13052 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13054 return KEY_DISPATCHING_TIMEOUT;
13058 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13059 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13060 != PackageManager.PERMISSION_GRANTED) {
13061 throw new SecurityException("Requires permission "
13062 + android.Manifest.permission.FILTER_EVENTS);
13064 ProcessRecord proc;
13066 synchronized (this) {
13067 synchronized (mPidsSelfLocked) {
13068 proc = mPidsSelfLocked.get(pid);
13070 timeout = getInputDispatchingTimeoutLocked(proc);
13073 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13081 * Handle input dispatching timeouts.
13082 * Returns whether input dispatching should be aborted or not.
13084 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13085 final ActivityRecord activity, final ActivityRecord parent,
13086 final boolean aboveSystem, String reason) {
13087 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13088 != PackageManager.PERMISSION_GRANTED) {
13089 throw new SecurityException("Requires permission "
13090 + android.Manifest.permission.FILTER_EVENTS);
13093 final String annotation;
13094 if (reason == null) {
13095 annotation = "Input dispatching timed out";
13097 annotation = "Input dispatching timed out (" + reason + ")";
13100 if (proc != null) {
13101 synchronized (this) {
13102 if (proc.debugging) {
13106 if (proc.instr != null) {
13107 Bundle info = new Bundle();
13108 info.putString("shortMsg", "keyDispatchingTimedOut");
13109 info.putString("longMsg", annotation);
13110 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13114 mHandler.post(new Runnable() {
13116 public void run() {
13117 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13126 public Bundle getAssistContextExtras(int requestType) {
13127 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13128 null, null, true /* focused */, true /* newSessionId */,
13129 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13133 synchronized (pae) {
13134 while (!pae.haveResult) {
13137 } catch (InterruptedException e) {
13141 synchronized (this) {
13142 buildAssistBundleLocked(pae, pae.result);
13143 mPendingAssistExtras.remove(pae);
13144 mUiHandler.removeCallbacks(pae);
13150 public boolean isAssistDataAllowedOnCurrentActivity() {
13152 synchronized (this) {
13153 final ActivityStack focusedStack = getFocusedStack();
13154 if (focusedStack == null || focusedStack.isAssistantStack()) {
13158 final ActivityRecord activity = focusedStack.topActivity();
13159 if (activity == null) {
13162 userId = activity.userId;
13164 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13165 Context.DEVICE_POLICY_SERVICE);
13166 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13170 public boolean showAssistFromActivity(IBinder token, Bundle args) {
13171 long ident = Binder.clearCallingIdentity();
13173 synchronized (this) {
13174 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13175 ActivityRecord top = getFocusedStack().topActivity();
13176 if (top != caller) {
13177 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13178 + " is not current top " + top);
13181 if (!top.nowVisible) {
13182 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13183 + " is not visible");
13187 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13190 Binder.restoreCallingIdentity(ident);
13195 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13196 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13197 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13198 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13199 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13203 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13204 IBinder activityToken, int flags) {
13205 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13206 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13207 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13210 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13211 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13212 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13214 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13215 "enqueueAssistContext()");
13217 synchronized (this) {
13218 ActivityRecord activity = getFocusedStack().topActivity();
13219 if (activity == null) {
13220 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13223 if (activity.app == null || activity.app.thread == null) {
13224 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13228 if (activityToken != null) {
13229 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13230 if (activity != caller) {
13231 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13232 + " is not current top " + activity);
13237 activity = ActivityRecord.forTokenLocked(activityToken);
13238 if (activity == null) {
13239 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13240 + " couldn't be found");
13243 if (activity.app == null || activity.app.thread == null) {
13244 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13249 PendingAssistExtras pae;
13250 Bundle extras = new Bundle();
13251 if (args != null) {
13252 extras.putAll(args);
13254 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13255 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13257 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13259 pae.isHome = activity.isHomeActivity();
13261 // Increment the sessionId if necessary
13262 if (newSessionId) {
13266 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13267 mViSessionId, flags);
13268 mPendingAssistExtras.add(pae);
13269 mUiHandler.postDelayed(pae, timeout);
13270 } catch (RemoteException e) {
13271 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13278 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13279 IResultReceiver receiver;
13280 synchronized (this) {
13281 mPendingAssistExtras.remove(pae);
13282 receiver = pae.receiver;
13284 if (receiver != null) {
13285 // Caller wants result sent back to them.
13286 Bundle sendBundle = new Bundle();
13287 // At least return the receiver extras
13288 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13289 pae.receiverExtras);
13291 pae.receiver.send(0, sendBundle);
13292 } catch (RemoteException e) {
13297 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13298 if (result != null) {
13299 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13301 if (pae.hint != null) {
13302 pae.extras.putBoolean(pae.hint, true);
13306 /** Called from an app when assist data is ready. */
13308 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13309 AssistContent content, Uri referrer) {
13310 PendingAssistExtras pae = (PendingAssistExtras)token;
13311 synchronized (pae) {
13312 pae.result = extras;
13313 pae.structure = structure;
13314 pae.content = content;
13315 if (referrer != null) {
13316 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13318 if (structure != null) {
13319 structure.setHomeActivity(pae.isHome);
13321 pae.haveResult = true;
13323 if (pae.intent == null && pae.receiver == null) {
13324 // Caller is just waiting for the result.
13328 // We are now ready to launch the assist activity.
13329 IResultReceiver sendReceiver = null;
13330 Bundle sendBundle = null;
13331 synchronized (this) {
13332 buildAssistBundleLocked(pae, extras);
13333 boolean exists = mPendingAssistExtras.remove(pae);
13334 mUiHandler.removeCallbacks(pae);
13339 if ((sendReceiver=pae.receiver) != null) {
13340 // Caller wants result sent back to them.
13341 sendBundle = new Bundle();
13342 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13343 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13344 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13345 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13346 pae.receiverExtras);
13349 if (sendReceiver != null) {
13351 sendReceiver.send(0, sendBundle);
13352 } catch (RemoteException e) {
13357 final long ident = Binder.clearCallingIdentity();
13359 if (TextUtils.equals(pae.intent.getAction(),
13360 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13361 pae.intent.putExtras(pae.extras);
13362 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13364 pae.intent.replaceExtras(pae.extras);
13365 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13366 | Intent.FLAG_ACTIVITY_SINGLE_TOP
13367 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13368 closeSystemDialogs("assist");
13371 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13372 } catch (ActivityNotFoundException e) {
13373 Slog.w(TAG, "No activity to handle assist action.", e);
13377 Binder.restoreCallingIdentity(ident);
13381 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13383 return enqueueAssistContext(requestType, intent, hint, null, null, null,
13384 true /* focused */, true /* newSessionId */, userHandle, args,
13385 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13388 public void registerProcessObserver(IProcessObserver observer) {
13389 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13390 "registerProcessObserver()");
13391 synchronized (this) {
13392 mProcessObservers.register(observer);
13397 public void unregisterProcessObserver(IProcessObserver observer) {
13398 synchronized (this) {
13399 mProcessObservers.unregister(observer);
13404 public int getUidProcessState(int uid, String callingPackage) {
13405 if (!hasUsageStatsPermission(callingPackage)) {
13406 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13407 "getUidProcessState");
13410 synchronized (this) {
13411 UidRecord uidRec = mActiveUids.get(uid);
13412 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13417 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13418 String callingPackage) {
13419 if (!hasUsageStatsPermission(callingPackage)) {
13420 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13421 "registerUidObserver");
13423 synchronized (this) {
13424 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13425 callingPackage, which, cutpoint));
13430 public void unregisterUidObserver(IUidObserver observer) {
13431 synchronized (this) {
13432 mUidObservers.unregister(observer);
13437 public boolean convertFromTranslucent(IBinder token) {
13438 final long origId = Binder.clearCallingIdentity();
13440 synchronized (this) {
13441 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13445 final boolean translucentChanged = r.changeWindowTranslucency(true);
13446 if (translucentChanged) {
13447 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13449 mWindowManager.setAppFullscreen(token, true);
13450 return translucentChanged;
13453 Binder.restoreCallingIdentity(origId);
13458 public boolean convertToTranslucent(IBinder token, Bundle options) {
13459 final long origId = Binder.clearCallingIdentity();
13461 synchronized (this) {
13462 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13466 final TaskRecord task = r.getTask();
13467 int index = task.mActivities.lastIndexOf(r);
13469 ActivityRecord under = task.mActivities.get(index - 1);
13470 under.returningOptions = ActivityOptions.fromBundle(options);
13472 final boolean translucentChanged = r.changeWindowTranslucency(false);
13473 if (translucentChanged) {
13474 r.getStack().convertActivityToTranslucent(r);
13476 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13477 mWindowManager.setAppFullscreen(token, false);
13478 return translucentChanged;
13481 Binder.restoreCallingIdentity(origId);
13486 public Bundle getActivityOptions(IBinder token) {
13487 final long origId = Binder.clearCallingIdentity();
13489 synchronized (this) {
13490 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13492 final ActivityOptions activityOptions = r.takeOptionsLocked();
13493 return activityOptions == null ? null : activityOptions.toBundle();
13498 Binder.restoreCallingIdentity(origId);
13503 public void setImmersive(IBinder token, boolean immersive) {
13504 synchronized(this) {
13505 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13507 throw new IllegalArgumentException();
13509 r.immersive = immersive;
13511 // update associated state if we're frontmost
13512 if (r == mStackSupervisor.getResumedActivityLocked()) {
13513 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13514 applyUpdateLockStateLocked(r);
13520 public boolean isImmersive(IBinder token) {
13521 synchronized (this) {
13522 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13524 throw new IllegalArgumentException();
13526 return r.immersive;
13531 public void setVrThread(int tid) {
13532 enforceSystemHasVrFeature();
13533 synchronized (this) {
13534 synchronized (mPidsSelfLocked) {
13535 final int pid = Binder.getCallingPid();
13536 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13537 mVrController.setVrThreadLocked(tid, pid, proc);
13543 public void setPersistentVrThread(int tid) {
13544 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13545 final String msg = "Permission Denial: setPersistentVrThread() from pid="
13546 + Binder.getCallingPid()
13547 + ", uid=" + Binder.getCallingUid()
13548 + " requires " + permission.RESTRICTED_VR_ACCESS;
13550 throw new SecurityException(msg);
13552 enforceSystemHasVrFeature();
13553 synchronized (this) {
13554 synchronized (mPidsSelfLocked) {
13555 final int pid = Binder.getCallingPid();
13556 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13557 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13563 * Schedule the given thread a normal scheduling priority.
13565 * @param tid the tid of the thread to adjust the scheduling of.
13566 * @param suppressLogs {@code true} if any error logging should be disabled.
13568 * @return {@code true} if this succeeded.
13570 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13572 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13574 } catch (IllegalArgumentException e) {
13575 if (!suppressLogs) {
13576 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13578 } catch (SecurityException e) {
13579 if (!suppressLogs) {
13580 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13587 * Schedule the given thread an FIFO scheduling priority.
13589 * @param tid the tid of the thread to adjust the scheduling of.
13590 * @param suppressLogs {@code true} if any error logging should be disabled.
13592 * @return {@code true} if this succeeded.
13594 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13596 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13598 } catch (IllegalArgumentException e) {
13599 if (!suppressLogs) {
13600 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13602 } catch (SecurityException e) {
13603 if (!suppressLogs) {
13604 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13611 * Check that we have the features required for VR-related API calls, and throw an exception if
13614 private void enforceSystemHasVrFeature() {
13615 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13616 throw new UnsupportedOperationException("VR mode not supported on this device!");
13621 public void setRenderThread(int tid) {
13622 synchronized (this) {
13623 ProcessRecord proc;
13624 int pid = Binder.getCallingPid();
13625 if (pid == Process.myPid()) {
13626 demoteSystemServerRenderThread(tid);
13629 synchronized (mPidsSelfLocked) {
13630 proc = mPidsSelfLocked.get(pid);
13631 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13632 // ensure the tid belongs to the process
13633 if (!isThreadInProcess(pid, tid)) {
13634 throw new IllegalArgumentException(
13635 "Render thread does not belong to process");
13637 proc.renderThreadTid = tid;
13638 if (DEBUG_OOM_ADJ) {
13639 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13641 // promote to FIFO now
13642 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13643 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13644 if (mUseFifoUiScheduling) {
13645 setThreadScheduler(proc.renderThreadTid,
13646 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13648 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13652 if (DEBUG_OOM_ADJ) {
13653 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13654 "PID: " + pid + ", TID: " + tid + " FIFO: " +
13655 mUseFifoUiScheduling);
13663 * We only use RenderThread in system_server to store task snapshots to the disk, which should
13664 * happen in the background. Thus, demote render thread from system_server to a lower priority.
13666 * @param tid the tid of the RenderThread
13668 private void demoteSystemServerRenderThread(int tid) {
13669 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13673 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13674 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13675 throw new UnsupportedOperationException("VR mode not supported on this device!");
13678 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13681 synchronized (this) {
13682 r = ActivityRecord.isInStackLocked(token);
13686 throw new IllegalArgumentException();
13690 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13691 VrManagerInternal.NO_ERROR) {
13695 synchronized(this) {
13696 r.requestedVrComponent = (enabled) ? packageName : null;
13698 // Update associated state if this activity is currently focused
13699 if (r == mStackSupervisor.getResumedActivityLocked()) {
13700 applyUpdateVrModeLocked(r);
13707 public boolean isVrModePackageEnabled(ComponentName packageName) {
13708 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13709 throw new UnsupportedOperationException("VR mode not supported on this device!");
13712 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13714 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13715 VrManagerInternal.NO_ERROR;
13718 public boolean isTopActivityImmersive() {
13719 enforceNotIsolatedCaller("startActivity");
13720 synchronized (this) {
13721 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13722 return (r != null) ? r.immersive : false;
13727 * @return whether the system should disable UI modes incompatible with VR mode.
13729 boolean shouldDisableNonVrUiLocked() {
13730 return mVrController.shouldDisableNonVrUiLocked();
13734 public boolean isTopOfTask(IBinder token) {
13735 synchronized (this) {
13736 ActivityRecord r = ActivityRecord.isInStackLocked(token);
13738 throw new IllegalArgumentException();
13740 return r.getTask().getTopActivity() == r;
13745 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13746 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13747 String msg = "Permission Denial: setHasTopUi() from pid="
13748 + Binder.getCallingPid()
13749 + ", uid=" + Binder.getCallingUid()
13750 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13752 throw new SecurityException(msg);
13754 final int pid = Binder.getCallingPid();
13755 final long origId = Binder.clearCallingIdentity();
13757 synchronized (this) {
13758 boolean changed = false;
13760 synchronized (mPidsSelfLocked) {
13761 pr = mPidsSelfLocked.get(pid);
13763 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13766 if (pr.hasTopUi != hasTopUi) {
13767 if (DEBUG_OOM_ADJ) {
13768 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13770 pr.hasTopUi = hasTopUi;
13775 updateOomAdjLocked(pr, true);
13779 Binder.restoreCallingIdentity(origId);
13783 public final void enterSafeMode() {
13784 synchronized(this) {
13785 // It only makes sense to do this before the system is ready
13786 // and started launching other packages.
13787 if (!mSystemReady) {
13789 AppGlobals.getPackageManager().enterSafeMode();
13790 } catch (RemoteException e) {
13798 public final void showSafeModeOverlay() {
13799 View v = LayoutInflater.from(mContext).inflate(
13800 com.android.internal.R.layout.safe_mode, null);
13801 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13802 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13803 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13804 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13805 lp.gravity = Gravity.BOTTOM | Gravity.START;
13806 lp.format = v.getBackground().getOpacity();
13807 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13808 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13809 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13810 ((WindowManager)mContext.getSystemService(
13811 Context.WINDOW_SERVICE)).addView(v, lp);
13814 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13815 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13818 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13819 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13820 synchronized (stats) {
13821 if (mBatteryStatsService.isOnBattery()) {
13822 mBatteryStatsService.enforceCallingPermission();
13823 int MY_UID = Binder.getCallingUid();
13825 if (sender == null) {
13828 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13830 BatteryStatsImpl.Uid.Pkg pkg =
13831 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13832 sourcePkg != null ? sourcePkg : rec.key.packageName);
13833 pkg.noteWakeupAlarmLocked(tag);
13838 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13839 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13842 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13843 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13844 synchronized (stats) {
13845 mBatteryStatsService.enforceCallingPermission();
13846 int MY_UID = Binder.getCallingUid();
13848 if (sender == null) {
13851 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13853 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13857 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13858 if (sender != null && !(sender instanceof PendingIntentRecord)) {
13861 final PendingIntentRecord rec = (PendingIntentRecord)sender;
13862 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13863 synchronized (stats) {
13864 mBatteryStatsService.enforceCallingPermission();
13865 int MY_UID = Binder.getCallingUid();
13867 if (sender == null) {
13870 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13872 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13876 public boolean killPids(int[] pids, String pReason, boolean secure) {
13877 if (Binder.getCallingUid() != SYSTEM_UID) {
13878 throw new SecurityException("killPids only available to the system");
13880 String reason = (pReason == null) ? "Unknown" : pReason;
13881 // XXX Note: don't acquire main activity lock here, because the window
13882 // manager calls in with its locks held.
13884 boolean killed = false;
13885 synchronized (mPidsSelfLocked) {
13887 for (int i=0; i<pids.length; i++) {
13888 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13889 if (proc != null) {
13890 int type = proc.setAdj;
13891 if (type > worstType) {
13897 // If the worst oom_adj is somewhere in the cached proc LRU range,
13898 // then constrain it so we will kill all cached procs.
13899 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13900 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13901 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13904 // If this is not a secure call, don't let it kill processes that
13906 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13907 worstType = ProcessList.SERVICE_ADJ;
13910 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13911 for (int i=0; i<pids.length; i++) {
13912 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13913 if (proc == null) {
13916 int adj = proc.setAdj;
13917 if (adj >= worstType && !proc.killedByAm) {
13918 proc.kill(reason, true);
13927 public void killUid(int appId, int userId, String reason) {
13928 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13929 synchronized (this) {
13930 final long identity = Binder.clearCallingIdentity();
13932 killPackageProcessesLocked(null, appId, userId,
13933 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13934 reason != null ? reason : "kill uid");
13936 Binder.restoreCallingIdentity(identity);
13942 public boolean killProcessesBelowForeground(String reason) {
13943 if (Binder.getCallingUid() != SYSTEM_UID) {
13944 throw new SecurityException("killProcessesBelowForeground() only available to system");
13947 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13950 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13951 if (Binder.getCallingUid() != SYSTEM_UID) {
13952 throw new SecurityException("killProcessesBelowAdj() only available to system");
13955 boolean killed = false;
13956 synchronized (mPidsSelfLocked) {
13957 final int size = mPidsSelfLocked.size();
13958 for (int i = 0; i < size; i++) {
13959 final int pid = mPidsSelfLocked.keyAt(i);
13960 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13961 if (proc == null) continue;
13963 final int adj = proc.setAdj;
13964 if (adj > belowAdj && !proc.killedByAm) {
13965 proc.kill(reason, true);
13974 public void hang(final IBinder who, boolean allowRestart) {
13975 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13976 != PackageManager.PERMISSION_GRANTED) {
13977 throw new SecurityException("Requires permission "
13978 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13981 final IBinder.DeathRecipient death = new DeathRecipient() {
13983 public void binderDied() {
13984 synchronized (this) {
13991 who.linkToDeath(death, 0);
13992 } catch (RemoteException e) {
13993 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13997 synchronized (this) {
13998 Watchdog.getInstance().setAllowRestart(allowRestart);
13999 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14000 synchronized (death) {
14001 while (who.isBinderAlive()) {
14004 } catch (InterruptedException e) {
14008 Watchdog.getInstance().setAllowRestart(true);
14013 public void restart() {
14014 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14015 != PackageManager.PERMISSION_GRANTED) {
14016 throw new SecurityException("Requires permission "
14017 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14020 Log.i(TAG, "Sending shutdown broadcast...");
14022 BroadcastReceiver br = new BroadcastReceiver() {
14023 @Override public void onReceive(Context context, Intent intent) {
14024 // Now the broadcast is done, finish up the low-level shutdown.
14025 Log.i(TAG, "Shutting down activity manager...");
14027 Log.i(TAG, "Shutdown complete, restarting!");
14028 killProcess(myPid());
14033 // First send the high-level shut down broadcast.
14034 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14035 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14036 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14037 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14038 mContext.sendOrderedBroadcastAsUser(intent,
14039 UserHandle.ALL, null, br, mHandler, 0, null, null);
14041 br.onReceive(mContext, intent);
14044 private long getLowRamTimeSinceIdle(long now) {
14045 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14049 public void performIdleMaintenance() {
14050 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14051 != PackageManager.PERMISSION_GRANTED) {
14052 throw new SecurityException("Requires permission "
14053 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14056 synchronized (this) {
14057 final long now = SystemClock.uptimeMillis();
14058 final long timeSinceLastIdle = now - mLastIdleTime;
14059 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14060 mLastIdleTime = now;
14061 mLowRamTimeSinceLastIdle = 0;
14062 if (mLowRamStartTime != 0) {
14063 mLowRamStartTime = now;
14066 StringBuilder sb = new StringBuilder(128);
14067 sb.append("Idle maintenance over ");
14068 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14069 sb.append(" low RAM for ");
14070 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14071 Slog.i(TAG, sb.toString());
14073 // If at least 1/3 of our time since the last idle period has been spent
14074 // with RAM low, then we want to kill processes.
14075 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14077 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14078 ProcessRecord proc = mLruProcesses.get(i);
14079 if (proc.notCachedSinceIdle) {
14080 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14081 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14082 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14083 if (doKilling && proc.initialIdlePss != 0
14084 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14085 sb = new StringBuilder(128);
14087 sb.append(proc.processName);
14088 sb.append(" in idle maint: pss=");
14089 sb.append(proc.lastPss);
14090 sb.append(", swapPss=");
14091 sb.append(proc.lastSwapPss);
14092 sb.append(", initialPss=");
14093 sb.append(proc.initialIdlePss);
14094 sb.append(", period=");
14095 TimeUtils.formatDuration(timeSinceLastIdle, sb);
14096 sb.append(", lowRamPeriod=");
14097 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14098 Slog.wtfQuiet(TAG, sb.toString());
14099 proc.kill("idle maint (pss " + proc.lastPss
14100 + " from " + proc.initialIdlePss + ")", true);
14103 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14104 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14105 proc.notCachedSinceIdle = true;
14106 proc.initialIdlePss = 0;
14107 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14108 mTestPssMode, isSleepingLocked(), now);
14112 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14113 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14118 public void sendIdleJobTrigger() {
14119 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14120 != PackageManager.PERMISSION_GRANTED) {
14121 throw new SecurityException("Requires permission "
14122 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14125 final long ident = Binder.clearCallingIdentity();
14127 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14128 .setPackage("android")
14129 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14130 broadcastIntent(null, intent, null, null, 0, null, null, null,
14131 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14133 Binder.restoreCallingIdentity(ident);
14137 private void retrieveSettings() {
14138 final ContentResolver resolver = mContext.getContentResolver();
14139 final boolean freeformWindowManagement =
14140 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14141 || Settings.Global.getInt(
14142 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14144 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14145 final boolean supportsPictureInPicture = supportsMultiWindow &&
14146 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14147 final boolean supportsSplitScreenMultiWindow =
14148 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14149 final boolean supportsMultiDisplay = mContext.getPackageManager()
14150 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14151 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14152 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14153 final boolean alwaysFinishActivities =
14154 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14155 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14156 final boolean forceResizable = Settings.Global.getInt(
14157 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14158 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14159 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14160 final boolean supportsLeanbackOnly =
14161 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14163 // Transfer any global setting for forcing RTL layout, into a System Property
14164 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14166 final Configuration configuration = new Configuration();
14167 Settings.System.getConfiguration(resolver, configuration);
14169 // This will take care of setting the correct layout direction flags
14170 configuration.setLayoutDirection(configuration.locale);
14173 synchronized (this) {
14174 mDebugApp = mOrigDebugApp = debugApp;
14175 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14176 mAlwaysFinishActivities = alwaysFinishActivities;
14177 mSupportsLeanbackOnly = supportsLeanbackOnly;
14178 mForceResizableActivities = forceResizable;
14179 final boolean multiWindowFormEnabled = freeformWindowManagement
14180 || supportsSplitScreenMultiWindow
14181 || supportsPictureInPicture
14182 || supportsMultiDisplay;
14183 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14184 mSupportsMultiWindow = true;
14185 mSupportsFreeformWindowManagement = freeformWindowManagement;
14186 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14187 mSupportsPictureInPicture = supportsPictureInPicture;
14188 mSupportsMultiDisplay = supportsMultiDisplay;
14190 mSupportsMultiWindow = false;
14191 mSupportsFreeformWindowManagement = false;
14192 mSupportsSplitScreenMultiWindow = false;
14193 mSupportsPictureInPicture = false;
14194 mSupportsMultiDisplay = false;
14196 mWindowManager.setForceResizableTasks(mForceResizableActivities);
14197 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14198 // This happens before any activities are started, so we can change global configuration
14200 updateConfigurationLocked(configuration, null, true);
14201 final Configuration globalConfig = getGlobalConfiguration();
14202 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14204 // Load resources only after the current configuration has been set.
14205 final Resources res = mContext.getResources();
14206 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14207 mThumbnailWidth = res.getDimensionPixelSize(
14208 com.android.internal.R.dimen.thumbnail_width);
14209 mThumbnailHeight = res.getDimensionPixelSize(
14210 com.android.internal.R.dimen.thumbnail_height);
14211 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14212 com.android.internal.R.string.config_appsNotReportingCrashes));
14213 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14214 com.android.internal.R.bool.config_customUserSwitchUi);
14215 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14216 mFullscreenThumbnailScale = (float) res
14217 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14218 (float) globalConfig.screenWidthDp;
14220 mFullscreenThumbnailScale = res.getFraction(
14221 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14223 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14227 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14228 traceLog.traceBegin("PhaseActivityManagerReady");
14229 synchronized(this) {
14230 if (mSystemReady) {
14231 // If we're done calling all the receivers, run the next "boot phase" passed in
14232 // by the SystemServer
14233 if (goingCallback != null) {
14234 goingCallback.run();
14239 mLocalDeviceIdleController
14240 = LocalServices.getService(DeviceIdleController.LocalService.class);
14241 mAssistUtils = new AssistUtils(mContext);
14242 mVrController.onSystemReady();
14243 // Make sure we have the current profile info, since it is needed for security checks.
14244 mUserController.onSystemReady();
14245 mRecentTasks.onSystemReadyLocked();
14246 mAppOpsService.systemReady();
14247 mSystemReady = true;
14251 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14252 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14254 } catch (RemoteException e) {}
14256 ArrayList<ProcessRecord> procsToKill = null;
14257 synchronized(mPidsSelfLocked) {
14258 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14259 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14260 if (!isAllowedWhileBooting(proc.info)){
14261 if (procsToKill == null) {
14262 procsToKill = new ArrayList<ProcessRecord>();
14264 procsToKill.add(proc);
14269 synchronized(this) {
14270 if (procsToKill != null) {
14271 for (int i=procsToKill.size()-1; i>=0; i--) {
14272 ProcessRecord proc = procsToKill.get(i);
14273 Slog.i(TAG, "Removing system update proc: " + proc);
14274 removeProcessLocked(proc, true, false, "system update done");
14278 // Now that we have cleaned up any update processes, we
14279 // are ready to start launching real processes and know that
14280 // we won't trample on them any more.
14281 mProcessesReady = true;
14284 Slog.i(TAG, "System now ready");
14285 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14286 SystemClock.uptimeMillis());
14288 synchronized(this) {
14289 // Make sure we have no pre-ready processes sitting around.
14291 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14292 ResolveInfo ri = mContext.getPackageManager()
14293 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14295 CharSequence errorMsg = null;
14297 ActivityInfo ai = ri.activityInfo;
14298 ApplicationInfo app = ai.applicationInfo;
14299 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14300 mTopAction = Intent.ACTION_FACTORY_TEST;
14302 mTopComponent = new ComponentName(app.packageName,
14305 errorMsg = mContext.getResources().getText(
14306 com.android.internal.R.string.factorytest_not_system);
14309 errorMsg = mContext.getResources().getText(
14310 com.android.internal.R.string.factorytest_no_action);
14312 if (errorMsg != null) {
14315 mTopComponent = null;
14316 Message msg = Message.obtain();
14317 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14318 msg.getData().putCharSequence("msg", errorMsg);
14319 mUiHandler.sendMessage(msg);
14324 retrieveSettings();
14325 final int currentUserId;
14326 synchronized (this) {
14327 currentUserId = mUserController.getCurrentUserIdLocked();
14328 readGrantedUriPermissionsLocked();
14331 if (goingCallback != null) goingCallback.run();
14332 traceLog.traceBegin("ActivityManagerStartApps");
14333 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14334 Integer.toString(currentUserId), currentUserId);
14335 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14336 Integer.toString(currentUserId), currentUserId);
14337 mSystemServiceManager.startUser(currentUserId);
14339 synchronized (this) {
14340 // Only start up encryption-aware persistent apps; once user is
14341 // unlocked we'll come back around and start unaware apps
14342 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14344 // Start up initial activity.
14346 // Enable home activity for system user, so that the system can always boot. We don't
14347 // do this when the system user is not setup since the setup wizard should be the one
14348 // to handle home activity in this case.
14349 if (UserManager.isSplitSystemUser() &&
14350 Settings.Secure.getInt(mContext.getContentResolver(),
14351 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14352 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14354 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14355 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14356 UserHandle.USER_SYSTEM);
14357 } catch (RemoteException e) {
14358 throw e.rethrowAsRuntimeException();
14361 startHomeActivityLocked(currentUserId, "systemReady");
14364 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14365 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14366 + " data partition or your device will be unstable.");
14367 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14369 } catch (RemoteException e) {
14372 if (!Build.isBuildConsistent()) {
14373 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14374 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14377 long ident = Binder.clearCallingIdentity();
14379 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14380 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14381 | Intent.FLAG_RECEIVER_FOREGROUND);
14382 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14383 broadcastIntentLocked(null, null, intent,
14384 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14385 null, false, false, MY_PID, SYSTEM_UID,
14387 intent = new Intent(Intent.ACTION_USER_STARTING);
14388 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14389 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14390 broadcastIntentLocked(null, null, intent,
14391 null, new IIntentReceiver.Stub() {
14393 public void performReceive(Intent intent, int resultCode, String data,
14394 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14395 throws RemoteException {
14398 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14399 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14400 } catch (Throwable t) {
14401 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14403 Binder.restoreCallingIdentity(ident);
14405 mStackSupervisor.resumeFocusedStackTopActivityLocked();
14406 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14407 traceLog.traceEnd(); // ActivityManagerStartApps
14408 traceLog.traceEnd(); // PhaseActivityManagerReady
14412 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14413 synchronized (this) {
14414 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14418 void skipCurrentReceiverLocked(ProcessRecord app) {
14419 for (BroadcastQueue queue : mBroadcastQueues) {
14420 queue.skipCurrentReceiverLocked(app);
14425 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14426 * The application process will exit immediately after this call returns.
14427 * @param app object of the crashing app, null for the system server
14428 * @param crashInfo describing the exception
14430 public void handleApplicationCrash(IBinder app,
14431 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14432 ProcessRecord r = findAppProcess(app, "Crash");
14433 final String processName = app == null ? "system_server"
14434 : (r == null ? "unknown" : r.processName);
14436 handleApplicationCrashInner("crash", r, processName, crashInfo);
14439 /* Native crash reporting uses this inner version because it needs to be somewhat
14440 * decoupled from the AM-managed cleanup lifecycle
14442 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14443 ApplicationErrorReport.CrashInfo crashInfo) {
14444 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14445 UserHandle.getUserId(Binder.getCallingUid()), processName,
14446 r == null ? -1 : r.info.flags,
14447 crashInfo.exceptionClassName,
14448 crashInfo.exceptionMessage,
14449 crashInfo.throwFileName,
14450 crashInfo.throwLineNumber);
14452 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14454 mAppErrors.crashApplication(r, crashInfo);
14457 public void handleApplicationStrictModeViolation(
14460 StrictMode.ViolationInfo info) {
14461 ProcessRecord r = findAppProcess(app, "StrictMode");
14466 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14467 Integer stackFingerprint = info.hashCode();
14468 boolean logIt = true;
14469 synchronized (mAlreadyLoggedViolatedStacks) {
14470 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14472 // TODO: sub-sample into EventLog for these, with
14473 // the info.durationMillis? Then we'd get
14474 // the relative pain numbers, without logging all
14475 // the stack traces repeatedly. We'd want to do
14476 // likewise in the client code, which also does
14477 // dup suppression, before the Binder call.
14479 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14480 mAlreadyLoggedViolatedStacks.clear();
14482 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14486 logStrictModeViolationToDropBox(r, info);
14490 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14491 AppErrorResult result = new AppErrorResult();
14492 synchronized (this) {
14493 final long origId = Binder.clearCallingIdentity();
14495 Message msg = Message.obtain();
14496 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14497 HashMap<String, Object> data = new HashMap<String, Object>();
14498 data.put("result", result);
14499 data.put("app", r);
14500 data.put("violationMask", violationMask);
14501 data.put("info", info);
14503 mUiHandler.sendMessage(msg);
14505 Binder.restoreCallingIdentity(origId);
14507 int res = result.get();
14508 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14512 // Depending on the policy in effect, there could be a bunch of
14513 // these in quick succession so we try to batch these together to
14514 // minimize disk writes, number of dropbox entries, and maximize
14515 // compression, by having more fewer, larger records.
14516 private void logStrictModeViolationToDropBox(
14517 ProcessRecord process,
14518 StrictMode.ViolationInfo info) {
14519 if (info == null) {
14522 final boolean isSystemApp = process == null ||
14523 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14524 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14525 final String processName = process == null ? "unknown" : process.processName;
14526 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14527 final DropBoxManager dbox = (DropBoxManager)
14528 mContext.getSystemService(Context.DROPBOX_SERVICE);
14530 // Exit early if the dropbox isn't configured to accept this report type.
14531 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14533 boolean bufferWasEmpty;
14534 boolean needsFlush;
14535 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14536 synchronized (sb) {
14537 bufferWasEmpty = sb.length() == 0;
14538 appendDropBoxProcessHeaders(process, processName, sb);
14539 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14540 sb.append("System-App: ").append(isSystemApp).append("\n");
14541 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14542 if (info.violationNumThisLoop != 0) {
14543 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14545 if (info.numAnimationsRunning != 0) {
14546 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14548 if (info.broadcastIntentAction != null) {
14549 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14551 if (info.durationMillis != -1) {
14552 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14554 if (info.numInstances != -1) {
14555 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14557 if (info.tags != null) {
14558 for (String tag : info.tags) {
14559 sb.append("Span-Tag: ").append(tag).append("\n");
14563 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14564 sb.append(info.crashInfo.stackTrace);
14567 if (info.message != null) {
14568 sb.append(info.message);
14572 // Only buffer up to ~64k. Various logging bits truncate
14574 needsFlush = (sb.length() > 64 * 1024);
14577 // Flush immediately if the buffer's grown too large, or this
14578 // is a non-system app. Non-system apps are isolated with a
14579 // different tag & policy and not batched.
14581 // Batching is useful during internal testing with
14582 // StrictMode settings turned up high. Without batching,
14583 // thousands of separate files could be created on boot.
14584 if (!isSystemApp || needsFlush) {
14585 new Thread("Error dump: " + dropboxTag) {
14587 public void run() {
14589 synchronized (sb) {
14590 report = sb.toString();
14591 sb.delete(0, sb.length());
14594 if (report.length() != 0) {
14595 dbox.addText(dropboxTag, report);
14602 // System app batching:
14603 if (!bufferWasEmpty) {
14604 // An existing dropbox-writing thread is outstanding, so
14605 // we don't need to start it up. The existing thread will
14606 // catch the buffer appends we just did.
14610 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14611 // (After this point, we shouldn't access AMS internal data structures.)
14612 new Thread("Error dump: " + dropboxTag) {
14614 public void run() {
14615 // 5 second sleep to let stacks arrive and be batched together
14617 Thread.sleep(5000); // 5 seconds
14618 } catch (InterruptedException e) {}
14620 String errorReport;
14621 synchronized (mStrictModeBuffer) {
14622 errorReport = mStrictModeBuffer.toString();
14623 if (errorReport.length() == 0) {
14626 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14627 mStrictModeBuffer.trimToSize();
14629 dbox.addText(dropboxTag, errorReport);
14635 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14636 * @param app object of the crashing app, null for the system server
14637 * @param tag reported by the caller
14638 * @param system whether this wtf is coming from the system
14639 * @param crashInfo describing the context of the error
14640 * @return true if the process should exit immediately (WTF is fatal)
14642 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14643 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14644 final int callingUid = Binder.getCallingUid();
14645 final int callingPid = Binder.getCallingPid();
14648 // If this is coming from the system, we could very well have low-level
14649 // system locks held, so we want to do this all asynchronously. And we
14650 // never want this to become fatal, so there is that too.
14651 mHandler.post(new Runnable() {
14652 @Override public void run() {
14653 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14659 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14662 final boolean isFatal = Build.IS_ENG || Settings.Global
14663 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14664 final boolean isSystem = (r == null) || r.persistent;
14666 if (isFatal && !isSystem) {
14667 mAppErrors.crashApplication(r, crashInfo);
14674 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14675 final ApplicationErrorReport.CrashInfo crashInfo) {
14676 final ProcessRecord r = findAppProcess(app, "WTF");
14677 final String processName = app == null ? "system_server"
14678 : (r == null ? "unknown" : r.processName);
14680 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14681 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14683 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14689 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14690 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14692 private ProcessRecord findAppProcess(IBinder app, String reason) {
14697 synchronized (this) {
14698 final int NP = mProcessNames.getMap().size();
14699 for (int ip=0; ip<NP; ip++) {
14700 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14701 final int NA = apps.size();
14702 for (int ia=0; ia<NA; ia++) {
14703 ProcessRecord p = apps.valueAt(ia);
14704 if (p.thread != null && p.thread.asBinder() == app) {
14710 Slog.w(TAG, "Can't find mystery application for " + reason
14711 + " from pid=" + Binder.getCallingPid()
14712 + " uid=" + Binder.getCallingUid() + ": " + app);
14718 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14719 * to append various headers to the dropbox log text.
14721 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14722 StringBuilder sb) {
14723 // Watchdog thread ends up invoking this function (with
14724 // a null ProcessRecord) to add the stack file to dropbox.
14725 // Do not acquire a lock on this (am) in such cases, as it
14726 // could cause a potential deadlock, if and when watchdog
14727 // is invoked due to unavailability of lock on am and it
14728 // would prevent watchdog from killing system_server.
14729 if (process == null) {
14730 sb.append("Process: ").append(processName).append("\n");
14733 // Note: ProcessRecord 'process' is guarded by the service
14734 // instance. (notably process.pkgList, which could otherwise change
14735 // concurrently during execution of this method)
14736 synchronized (this) {
14737 sb.append("Process: ").append(processName).append("\n");
14738 sb.append("PID: ").append(process.pid).append("\n");
14739 int flags = process.info.flags;
14740 IPackageManager pm = AppGlobals.getPackageManager();
14741 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14742 for (int ip=0; ip<process.pkgList.size(); ip++) {
14743 String pkg = process.pkgList.keyAt(ip);
14744 sb.append("Package: ").append(pkg);
14746 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14748 sb.append(" v").append(pi.versionCode);
14749 if (pi.versionName != null) {
14750 sb.append(" (").append(pi.versionName).append(")");
14753 } catch (RemoteException e) {
14754 Slog.e(TAG, "Error getting package info: " + pkg, e);
14758 if (process.info.isInstantApp()) {
14759 sb.append("Instant-App: true\n");
14764 private static String processClass(ProcessRecord process) {
14765 if (process == null || process.pid == MY_PID) {
14766 return "system_server";
14767 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14768 return "system_app";
14774 private volatile long mWtfClusterStart;
14775 private volatile int mWtfClusterCount;
14778 * Write a description of an error (crash, WTF, ANR) to the drop box.
14779 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14780 * @param process which caused the error, null means the system server
14781 * @param activity which triggered the error, null if unknown
14782 * @param parent activity related to the error, null if unknown
14783 * @param subject line related to the error, null if absent
14784 * @param report in long form describing the error, null if absent
14785 * @param dataFile text file to include in the report, null if none
14786 * @param crashInfo giving an application stack trace, null if absent
14788 public void addErrorToDropBox(String eventType,
14789 ProcessRecord process, String processName, ActivityRecord activity,
14790 ActivityRecord parent, String subject,
14791 final String report, final File dataFile,
14792 final ApplicationErrorReport.CrashInfo crashInfo) {
14793 // NOTE -- this must never acquire the ActivityManagerService lock,
14794 // otherwise the watchdog may be prevented from resetting the system.
14796 // Bail early if not published yet
14797 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14798 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14800 // Exit early if the dropbox isn't configured to accept this report type.
14801 final String dropboxTag = processClass(process) + "_" + eventType;
14802 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14804 // Rate-limit how often we're willing to do the heavy lifting below to
14805 // collect and record logs; currently 5 logs per 10 second period.
14806 final long now = SystemClock.elapsedRealtime();
14807 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14808 mWtfClusterStart = now;
14809 mWtfClusterCount = 1;
14811 if (mWtfClusterCount++ >= 5) return;
14814 final StringBuilder sb = new StringBuilder(1024);
14815 appendDropBoxProcessHeaders(process, processName, sb);
14816 if (process != null) {
14817 sb.append("Foreground: ")
14818 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14821 if (activity != null) {
14822 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14824 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14825 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14827 if (parent != null && parent != activity) {
14828 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14830 if (subject != null) {
14831 sb.append("Subject: ").append(subject).append("\n");
14833 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14834 if (Debug.isDebuggerConnected()) {
14835 sb.append("Debugger: Connected\n");
14839 // Do the rest in a worker thread to avoid blocking the caller on I/O
14840 // (After this point, we shouldn't access AMS internal data structures.)
14841 Thread worker = new Thread("Error dump: " + dropboxTag) {
14843 public void run() {
14844 if (report != null) {
14848 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14849 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14850 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14851 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14853 if (dataFile != null && maxDataFileSize > 0) {
14855 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14856 "\n\n[[TRUNCATED]]"));
14857 } catch (IOException e) {
14858 Slog.e(TAG, "Error reading " + dataFile, e);
14861 if (crashInfo != null && crashInfo.stackTrace != null) {
14862 sb.append(crashInfo.stackTrace);
14868 // Merge several logcat streams, and take the last N lines
14869 InputStreamReader input = null;
14871 java.lang.Process logcat = new ProcessBuilder(
14872 "/system/bin/timeout", "-k", "15s", "10s",
14873 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14874 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14875 .redirectErrorStream(true).start();
14877 try { logcat.getOutputStream().close(); } catch (IOException e) {}
14878 try { logcat.getErrorStream().close(); } catch (IOException e) {}
14879 input = new InputStreamReader(logcat.getInputStream());
14882 char[] buf = new char[8192];
14883 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14884 } catch (IOException e) {
14885 Slog.e(TAG, "Error running logcat", e);
14887 if (input != null) try { input.close(); } catch (IOException e) {}
14891 dbox.addText(dropboxTag, sb.toString());
14895 if (process == null) {
14896 // If process is null, we are being called from some internal code
14897 // and may be about to die -- run this synchronously.
14905 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14906 enforceNotIsolatedCaller("getProcessesInErrorState");
14907 // assume our apps are happy - lazy create the list
14908 List<ActivityManager.ProcessErrorStateInfo> errList = null;
14910 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14911 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14912 int userId = UserHandle.getUserId(Binder.getCallingUid());
14914 synchronized (this) {
14916 // iterate across all processes
14917 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14918 ProcessRecord app = mLruProcesses.get(i);
14919 if (!allUsers && app.userId != userId) {
14922 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14923 // This one's in trouble, so we'll generate a report for it
14924 // crashes are higher priority (in case there's a crash *and* an anr)
14925 ActivityManager.ProcessErrorStateInfo report = null;
14926 if (app.crashing) {
14927 report = app.crashingReport;
14928 } else if (app.notResponding) {
14929 report = app.notRespondingReport;
14932 if (report != null) {
14933 if (errList == null) {
14934 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14936 errList.add(report);
14938 Slog.w(TAG, "Missing app error report, app = " + app.processName +
14939 " crashing = " + app.crashing +
14940 " notResponding = " + app.notResponding);
14949 static int procStateToImportance(int procState, int memAdj,
14950 ActivityManager.RunningAppProcessInfo currApp,
14951 int clientTargetSdk) {
14952 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14953 procState, clientTargetSdk);
14954 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14955 currApp.lru = memAdj;
14962 private void fillInProcMemInfo(ProcessRecord app,
14963 ActivityManager.RunningAppProcessInfo outInfo,
14964 int clientTargetSdk) {
14965 outInfo.pid = app.pid;
14966 outInfo.uid = app.info.uid;
14967 if (mHeavyWeightProcess == app) {
14968 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14970 if (app.persistent) {
14971 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14973 if (app.activities.size() > 0) {
14974 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14976 outInfo.lastTrimLevel = app.trimMemoryLevel;
14977 int adj = app.curAdj;
14978 int procState = app.curProcState;
14979 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14980 outInfo.importanceReasonCode = app.adjTypeCode;
14981 outInfo.processState = app.curProcState;
14985 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14986 enforceNotIsolatedCaller("getRunningAppProcesses");
14988 final int callingUid = Binder.getCallingUid();
14989 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14991 // Lazy instantiation of list
14992 List<ActivityManager.RunningAppProcessInfo> runList = null;
14993 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14994 callingUid) == PackageManager.PERMISSION_GRANTED;
14995 final int userId = UserHandle.getUserId(callingUid);
14996 final boolean allUids = isGetTasksAllowed(
14997 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14999 synchronized (this) {
15000 // Iterate across all processes
15001 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15002 ProcessRecord app = mLruProcesses.get(i);
15003 if ((!allUsers && app.userId != userId)
15004 || (!allUids && app.uid != callingUid)) {
15007 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15008 // Generate process state info for running application
15009 ActivityManager.RunningAppProcessInfo currApp =
15010 new ActivityManager.RunningAppProcessInfo(app.processName,
15011 app.pid, app.getPackageList());
15012 fillInProcMemInfo(app, currApp, clientTargetSdk);
15013 if (app.adjSource instanceof ProcessRecord) {
15014 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15015 currApp.importanceReasonImportance =
15016 ActivityManager.RunningAppProcessInfo.procStateToImportance(
15017 app.adjSourceProcState);
15018 } else if (app.adjSource instanceof ActivityRecord) {
15019 ActivityRecord r = (ActivityRecord)app.adjSource;
15020 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15022 if (app.adjTarget instanceof ComponentName) {
15023 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15025 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15026 // + " lru=" + currApp.lru);
15027 if (runList == null) {
15028 runList = new ArrayList<>();
15030 runList.add(currApp);
15038 public List<ApplicationInfo> getRunningExternalApplications() {
15039 enforceNotIsolatedCaller("getRunningExternalApplications");
15040 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15041 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15042 if (runningApps != null && runningApps.size() > 0) {
15043 Set<String> extList = new HashSet<String>();
15044 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15045 if (app.pkgList != null) {
15046 for (String pkg : app.pkgList) {
15051 IPackageManager pm = AppGlobals.getPackageManager();
15052 for (String pkg : extList) {
15054 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15055 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15058 } catch (RemoteException e) {
15066 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15067 enforceNotIsolatedCaller("getMyMemoryState");
15069 final int callingUid = Binder.getCallingUid();
15070 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15072 synchronized (this) {
15073 ProcessRecord proc;
15074 synchronized (mPidsSelfLocked) {
15075 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15077 fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15082 public int getMemoryTrimLevel() {
15083 enforceNotIsolatedCaller("getMyMemoryState");
15084 synchronized (this) {
15085 return mLastMemoryLevel;
15090 public void onShellCommand(FileDescriptor in, FileDescriptor out,
15091 FileDescriptor err, String[] args, ShellCallback callback,
15092 ResultReceiver resultReceiver) {
15093 (new ActivityManagerShellCommand(this, false)).exec(
15094 this, in, out, err, args, callback, resultReceiver);
15097 SleepToken acquireSleepToken(String tag, int displayId) {
15098 synchronized (this) {
15099 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15100 updateSleepIfNeededLocked();
15106 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15107 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15109 boolean dumpAll = false;
15110 boolean dumpClient = false;
15111 boolean dumpCheckin = false;
15112 boolean dumpCheckinFormat = false;
15113 boolean dumpVisibleStacksOnly = false;
15114 boolean dumpFocusedStackOnly = false;
15115 String dumpPackage = null;
15118 while (opti < args.length) {
15119 String opt = args[opti];
15120 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15124 if ("-a".equals(opt)) {
15126 } else if ("-c".equals(opt)) {
15128 } else if ("-v".equals(opt)) {
15129 dumpVisibleStacksOnly = true;
15130 } else if ("-f".equals(opt)) {
15131 dumpFocusedStackOnly = true;
15132 } else if ("-p".equals(opt)) {
15133 if (opti < args.length) {
15134 dumpPackage = args[opti];
15137 pw.println("Error: -p option requires package argument");
15141 } else if ("--checkin".equals(opt)) {
15142 dumpCheckin = dumpCheckinFormat = true;
15143 } else if ("-C".equals(opt)) {
15144 dumpCheckinFormat = true;
15145 } else if ("-h".equals(opt)) {
15146 ActivityManagerShellCommand.dumpHelp(pw, true);
15149 pw.println("Unknown argument: " + opt + "; use -h for help");
15153 long origId = Binder.clearCallingIdentity();
15154 boolean more = false;
15155 // Is the caller requesting to dump a particular piece of data?
15156 if (opti < args.length) {
15157 String cmd = args[opti];
15159 if ("activities".equals(cmd) || "a".equals(cmd)) {
15160 synchronized (this) {
15161 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15163 } else if ("lastanr".equals(cmd)) {
15164 synchronized (this) {
15165 dumpLastANRLocked(pw);
15167 } else if ("starter".equals(cmd)) {
15168 synchronized (this) {
15169 dumpActivityStarterLocked(pw, dumpPackage);
15171 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15172 synchronized (this) {
15173 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15175 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15178 if (opti >= args.length) {
15180 newArgs = EMPTY_STRING_ARRAY;
15182 dumpPackage = args[opti];
15184 newArgs = new String[args.length - opti];
15185 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15186 args.length - opti);
15188 synchronized (this) {
15189 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15191 } else if ("broadcast-stats".equals(cmd)) {
15194 if (opti >= args.length) {
15196 newArgs = EMPTY_STRING_ARRAY;
15198 dumpPackage = args[opti];
15200 newArgs = new String[args.length - opti];
15201 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15202 args.length - opti);
15204 synchronized (this) {
15205 if (dumpCheckinFormat) {
15206 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15209 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15212 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15215 if (opti >= args.length) {
15217 newArgs = EMPTY_STRING_ARRAY;
15219 dumpPackage = args[opti];
15221 newArgs = new String[args.length - opti];
15222 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15223 args.length - opti);
15225 synchronized (this) {
15226 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15228 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15231 if (opti >= args.length) {
15233 newArgs = EMPTY_STRING_ARRAY;
15235 dumpPackage = args[opti];
15237 newArgs = new String[args.length - opti];
15238 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15239 args.length - opti);
15241 synchronized (this) {
15242 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15244 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15245 synchronized (this) {
15246 dumpOomLocked(fd, pw, args, opti, true);
15248 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15249 synchronized (this) {
15250 dumpPermissionsLocked(fd, pw, args, opti, true, null);
15252 } else if ("provider".equals(cmd)) {
15255 if (opti >= args.length) {
15257 newArgs = EMPTY_STRING_ARRAY;
15261 newArgs = new String[args.length - opti];
15262 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15264 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15265 pw.println("No providers match: " + name);
15266 pw.println("Use -h for help.");
15268 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15269 synchronized (this) {
15270 dumpProvidersLocked(fd, pw, args, opti, true, null);
15272 } else if ("service".equals(cmd)) {
15275 if (opti >= args.length) {
15277 newArgs = EMPTY_STRING_ARRAY;
15281 newArgs = new String[args.length - opti];
15282 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15283 args.length - opti);
15285 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15286 pw.println("No services match: " + name);
15287 pw.println("Use -h for help.");
15289 } else if ("package".equals(cmd)) {
15291 if (opti >= args.length) {
15292 pw.println("package: no package name specified");
15293 pw.println("Use -h for help.");
15295 dumpPackage = args[opti];
15297 newArgs = new String[args.length - opti];
15298 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15299 args.length - opti);
15304 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15305 synchronized (this) {
15306 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15308 } else if ("settings".equals(cmd)) {
15309 synchronized (this) {
15310 mConstants.dump(pw);
15312 } else if ("services".equals(cmd) || "s".equals(cmd)) {
15314 ActiveServices.ServiceDumper dumper;
15315 synchronized (this) {
15316 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15319 dumper.dumpWithClient();
15321 synchronized (this) {
15322 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15323 dumpPackage).dumpLocked();
15326 } else if ("locks".equals(cmd)) {
15327 LockGuard.dump(fd, pw, args);
15329 // Dumping a single activity?
15330 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15331 dumpFocusedStackOnly)) {
15332 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15333 int res = shell.exec(this, null, fd, null, args, null,
15334 new ResultReceiver(null));
15336 pw.println("Bad activity command, or no activities match: " + cmd);
15337 pw.println("Use -h for help.");
15342 Binder.restoreCallingIdentity(origId);
15347 // No piece of data specified, dump everything.
15348 if (dumpCheckinFormat) {
15349 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15350 } else if (dumpClient) {
15351 ActiveServices.ServiceDumper sdumper;
15352 synchronized (this) {
15353 mConstants.dump(pw);
15356 pw.println("-------------------------------------------------------------------------------");
15358 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15361 pw.println("-------------------------------------------------------------------------------");
15363 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15366 pw.println("-------------------------------------------------------------------------------");
15368 if (dumpAll || dumpPackage != null) {
15369 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15372 pw.println("-------------------------------------------------------------------------------");
15375 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15378 pw.println("-------------------------------------------------------------------------------");
15380 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15383 pw.println("-------------------------------------------------------------------------------");
15385 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15388 sdumper.dumpWithClient();
15390 synchronized (this) {
15392 pw.println("-------------------------------------------------------------------------------");
15394 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15397 pw.println("-------------------------------------------------------------------------------");
15399 dumpLastANRLocked(pw);
15402 pw.println("-------------------------------------------------------------------------------");
15404 dumpActivityStarterLocked(pw, dumpPackage);
15407 pw.println("-------------------------------------------------------------------------------");
15409 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15410 if (mAssociations.size() > 0) {
15413 pw.println("-------------------------------------------------------------------------------");
15415 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15419 pw.println("-------------------------------------------------------------------------------");
15421 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15425 synchronized (this) {
15426 mConstants.dump(pw);
15429 pw.println("-------------------------------------------------------------------------------");
15431 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15434 pw.println("-------------------------------------------------------------------------------");
15436 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15439 pw.println("-------------------------------------------------------------------------------");
15441 if (dumpAll || dumpPackage != null) {
15442 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15445 pw.println("-------------------------------------------------------------------------------");
15448 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15451 pw.println("-------------------------------------------------------------------------------");
15453 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15456 pw.println("-------------------------------------------------------------------------------");
15458 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15462 pw.println("-------------------------------------------------------------------------------");
15464 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15467 pw.println("-------------------------------------------------------------------------------");
15469 dumpLastANRLocked(pw);
15472 pw.println("-------------------------------------------------------------------------------");
15474 dumpActivityStarterLocked(pw, dumpPackage);
15477 pw.println("-------------------------------------------------------------------------------");
15479 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15480 if (mAssociations.size() > 0) {
15483 pw.println("-------------------------------------------------------------------------------");
15485 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15489 pw.println("-------------------------------------------------------------------------------");
15491 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15494 Binder.restoreCallingIdentity(origId);
15497 private void dumpLastANRLocked(PrintWriter pw) {
15498 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15499 if (mLastANRState == null) {
15500 pw.println(" <no ANR has occurred since boot>");
15502 pw.println(mLastANRState);
15506 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15507 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15508 mActivityStarter.dump(pw, "", dumpPackage);
15511 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15512 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15513 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15514 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15517 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15518 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15519 pw.println(header);
15521 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15523 boolean needSep = printedAnything;
15525 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15526 mStackSupervisor.getResumedActivityLocked(),
15527 dumpPackage, needSep, " ResumedActivity: ");
15529 printedAnything = true;
15533 if (dumpPackage == null) {
15537 printedAnything = true;
15538 mStackSupervisor.dump(pw, " ");
15541 if (!printedAnything) {
15542 pw.println(" (nothing)");
15546 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15547 int opti, boolean dumpAll, String dumpPackage) {
15548 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15550 boolean printedAnything = false;
15552 if (mRecentTasks != null && mRecentTasks.size() > 0) {
15553 boolean printedHeader = false;
15555 final int N = mRecentTasks.size();
15556 for (int i=0; i<N; i++) {
15557 TaskRecord tr = mRecentTasks.get(i);
15558 if (dumpPackage != null) {
15559 if (tr.realActivity == null ||
15560 !dumpPackage.equals(tr.realActivity.getPackageName())) {
15564 if (!printedHeader) {
15565 pw.println(" Recent tasks:");
15566 printedHeader = true;
15567 printedAnything = true;
15569 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
15572 mRecentTasks.get(i).dump(pw, " ");
15577 if (!printedAnything) {
15578 pw.println(" (nothing)");
15582 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15583 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15584 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15587 if (dumpPackage != null) {
15588 IPackageManager pm = AppGlobals.getPackageManager();
15590 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15591 } catch (RemoteException e) {
15595 boolean printedAnything = false;
15597 final long now = SystemClock.uptimeMillis();
15599 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15600 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15601 = mAssociations.valueAt(i1);
15602 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15603 SparseArray<ArrayMap<String, Association>> sourceUids
15604 = targetComponents.valueAt(i2);
15605 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15606 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15607 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15608 Association ass = sourceProcesses.valueAt(i4);
15609 if (dumpPackage != null) {
15610 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15611 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15615 printedAnything = true;
15617 pw.print(ass.mTargetProcess);
15619 UserHandle.formatUid(pw, ass.mTargetUid);
15621 pw.print(ass.mSourceProcess);
15623 UserHandle.formatUid(pw, ass.mSourceUid);
15626 pw.print(ass.mTargetComponent.flattenToShortString());
15629 long dur = ass.mTime;
15630 if (ass.mNesting > 0) {
15631 dur += now - ass.mStartTime;
15633 TimeUtils.formatDuration(dur, pw);
15635 pw.print(ass.mCount);
15636 pw.print(" times)");
15638 for (int i=0; i<ass.mStateTimes.length; i++) {
15639 long amt = ass.mStateTimes[i];
15640 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15641 amt += now - ass.mLastStateUptime;
15645 pw.print(ProcessList.makeProcStateString(
15646 i + ActivityManager.MIN_PROCESS_STATE));
15648 TimeUtils.formatDuration(amt, pw);
15649 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15655 if (ass.mNesting > 0) {
15656 pw.print(" Currently active: ");
15657 TimeUtils.formatDuration(now - ass.mStartTime, pw);
15666 if (!printedAnything) {
15667 pw.println(" (nothing)");
15671 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15672 String header, boolean needSep) {
15673 boolean printed = false;
15674 int whichAppId = -1;
15675 if (dumpPackage != null) {
15677 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15679 whichAppId = UserHandle.getAppId(info.uid);
15680 } catch (NameNotFoundException e) {
15681 e.printStackTrace();
15684 for (int i=0; i<uids.size(); i++) {
15685 UidRecord uidRec = uids.valueAt(i);
15686 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15695 pw.println(header);
15698 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
15699 pw.print(": "); pw.println(uidRec);
15704 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15705 int opti, boolean dumpAll, String dumpPackage) {
15706 boolean needSep = false;
15707 boolean printedAnything = false;
15710 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15713 final int NP = mProcessNames.getMap().size();
15714 for (int ip=0; ip<NP; ip++) {
15715 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15716 final int NA = procs.size();
15717 for (int ia=0; ia<NA; ia++) {
15718 ProcessRecord r = procs.valueAt(ia);
15719 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15723 pw.println(" All known processes:");
15725 printedAnything = true;
15727 pw.print(r.persistent ? " *PERS*" : " *APP*");
15728 pw.print(" UID "); pw.print(procs.keyAt(ia));
15729 pw.print(" "); pw.println(r);
15731 if (r.persistent) {
15738 if (mIsolatedProcesses.size() > 0) {
15739 boolean printed = false;
15740 for (int i=0; i<mIsolatedProcesses.size(); i++) {
15741 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15742 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15749 pw.println(" Isolated process list (sorted by uid):");
15750 printedAnything = true;
15754 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
15759 if (mActiveInstrumentation.size() > 0) {
15760 boolean printed = false;
15761 for (int i=0; i<mActiveInstrumentation.size(); i++) {
15762 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15763 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15764 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15771 pw.println(" Active instrumentation:");
15772 printedAnything = true;
15776 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
15782 if (mActiveUids.size() > 0) {
15783 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15784 printedAnything = needSep = true;
15788 if (mValidateUids.size() > 0) {
15789 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15790 printedAnything = needSep = true;
15795 if (mLruProcesses.size() > 0) {
15799 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15800 pw.print(" total, non-act at ");
15801 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15802 pw.print(", non-svc at ");
15803 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15805 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
15807 printedAnything = true;
15810 if (dumpAll || dumpPackage != null) {
15811 synchronized (mPidsSelfLocked) {
15812 boolean printed = false;
15813 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15814 ProcessRecord r = mPidsSelfLocked.valueAt(i);
15815 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15819 if (needSep) pw.println();
15821 pw.println(" PID mappings:");
15823 printedAnything = true;
15825 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15826 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15831 if (mImportantProcesses.size() > 0) {
15832 synchronized (mPidsSelfLocked) {
15833 boolean printed = false;
15834 for (int i = 0; i< mImportantProcesses.size(); i++) {
15835 ProcessRecord r = mPidsSelfLocked.get(
15836 mImportantProcesses.valueAt(i).pid);
15837 if (dumpPackage != null && (r == null
15838 || !r.pkgList.containsKey(dumpPackage))) {
15842 if (needSep) pw.println();
15844 pw.println(" Foreground Processes:");
15846 printedAnything = true;
15848 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
15849 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15854 if (mPersistentStartingProcesses.size() > 0) {
15855 if (needSep) pw.println();
15857 printedAnything = true;
15858 pw.println(" Persisent processes that are starting:");
15859 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
15860 "Starting Norm", "Restarting PERS", dumpPackage);
15863 if (mRemovedProcesses.size() > 0) {
15864 if (needSep) pw.println();
15866 printedAnything = true;
15867 pw.println(" Processes that are being removed:");
15868 dumpProcessList(pw, this, mRemovedProcesses, " ",
15869 "Removed Norm", "Removed PERS", dumpPackage);
15872 if (mProcessesOnHold.size() > 0) {
15873 if (needSep) pw.println();
15875 printedAnything = true;
15876 pw.println(" Processes that are on old until the system is ready:");
15877 dumpProcessList(pw, this, mProcessesOnHold, " ",
15878 "OnHold Norm", "OnHold PERS", dumpPackage);
15881 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15883 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15885 printedAnything = true;
15888 if (dumpPackage == null) {
15891 mUserController.dump(pw, dumpAll);
15893 if (mHomeProcess != null && (dumpPackage == null
15894 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15899 pw.println(" mHomeProcess: " + mHomeProcess);
15901 if (mPreviousProcess != null && (dumpPackage == null
15902 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15907 pw.println(" mPreviousProcess: " + mPreviousProcess);
15910 StringBuilder sb = new StringBuilder(128);
15911 sb.append(" mPreviousProcessVisibleTime: ");
15912 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15915 if (mHeavyWeightProcess != null && (dumpPackage == null
15916 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15921 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15923 if (dumpPackage == null) {
15924 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
15925 mStackSupervisor.dumpDisplayConfigs(pw, " ");
15928 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15929 if (mCompatModePackages.getPackages().size() > 0) {
15930 boolean printed = false;
15931 for (Map.Entry<String, Integer> entry
15932 : mCompatModePackages.getPackages().entrySet()) {
15933 String pkg = entry.getKey();
15934 int mode = entry.getValue();
15935 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15939 pw.println(" mScreenCompatPackages:");
15942 pw.print(" "); pw.print(pkg); pw.print(": ");
15943 pw.print(mode); pw.println();
15946 final int NI = mUidObservers.getRegisteredCallbackCount();
15947 boolean printed = false;
15948 for (int i=0; i<NI; i++) {
15949 final UidObserverRegistration reg = (UidObserverRegistration)
15950 mUidObservers.getRegisteredCallbackCookie(i);
15951 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15953 pw.println(" mUidObservers:");
15956 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
15957 pw.print(" "); pw.print(reg.pkg); pw.print(":");
15958 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15961 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15964 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15967 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15968 pw.print(" STATE");
15969 pw.print(" (cut="); pw.print(reg.cutpoint);
15973 if (reg.lastProcStates != null) {
15974 final int NJ = reg.lastProcStates.size();
15975 for (int j=0; j<NJ; j++) {
15976 pw.print(" Last ");
15977 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15978 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15983 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15984 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15985 if (mPendingTempWhitelist.size() > 0) {
15986 pw.println(" mPendingTempWhitelist:");
15987 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15988 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15990 UserHandle.formatUid(pw, ptw.targetUid);
15992 TimeUtils.formatDuration(ptw.duration, pw);
15994 pw.println(ptw.tag);
15998 if (dumpPackage == null) {
15999 pw.println(" mWakefulness="
16000 + PowerManagerInternal.wakefulnessToString(mWakefulness));
16001 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
16002 pw.println(" mSleeping=" + mSleeping);
16003 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16004 if (mRunningVoice != null) {
16005 pw.println(" mRunningVoice=" + mRunningVoice);
16006 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
16009 pw.println(" mVrController=" + mVrController);
16010 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16011 || mOrigWaitForDebugger) {
16012 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16013 || dumpPackage.equals(mOrigDebugApp)) {
16018 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16019 + " mDebugTransient=" + mDebugTransient
16020 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16023 if (mCurAppTimeTracker != null) {
16024 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
16026 if (mMemWatchProcesses.getMap().size() > 0) {
16027 pw.println(" Mem watch processes:");
16028 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16029 = mMemWatchProcesses.getMap();
16030 for (int i=0; i<procs.size(); i++) {
16031 final String proc = procs.keyAt(i);
16032 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16033 for (int j=0; j<uids.size(); j++) {
16038 StringBuilder sb = new StringBuilder();
16039 sb.append(" ").append(proc).append('/');
16040 UserHandle.formatUid(sb, uids.keyAt(j));
16041 Pair<Long, String> val = uids.valueAt(j);
16042 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16043 if (val.second != null) {
16044 sb.append(", report to ").append(val.second);
16046 pw.println(sb.toString());
16049 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16050 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16051 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16052 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16054 if (mTrackAllocationApp != null) {
16055 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16060 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
16063 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16064 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16065 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16070 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16071 if (mProfilerInfo != null) {
16072 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16073 mProfilerInfo.profileFd);
16074 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
16075 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16076 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16077 pw.println(" mProfileType=" + mProfileType);
16081 if (mNativeDebuggingApp != null) {
16082 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16087 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
16090 if (dumpPackage == null) {
16091 if (mAlwaysFinishActivities) {
16092 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16094 if (mController != null) {
16095 pw.println(" mController=" + mController
16096 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16099 pw.println(" Total persistent processes: " + numPers);
16100 pw.println(" mProcessesReady=" + mProcessesReady
16101 + " mSystemReady=" + mSystemReady
16102 + " mBooted=" + mBooted
16103 + " mFactoryTest=" + mFactoryTest);
16104 pw.println(" mBooting=" + mBooting
16105 + " mCallFinishBooting=" + mCallFinishBooting
16106 + " mBootAnimationComplete=" + mBootAnimationComplete);
16107 pw.print(" mLastPowerCheckUptime=");
16108 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16110 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16111 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16112 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16113 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
16114 + " (" + mLruProcesses.size() + " total)"
16115 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16116 + " mNumServiceProcs=" + mNumServiceProcs
16117 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16118 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
16119 + " mLastMemoryLevel=" + mLastMemoryLevel
16120 + " mLastNumProcesses=" + mLastNumProcesses);
16121 long now = SystemClock.uptimeMillis();
16122 pw.print(" mLastIdleTime=");
16123 TimeUtils.formatDuration(now, mLastIdleTime, pw);
16124 pw.print(" mLowRamSinceLastIdle=");
16125 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16130 if (!printedAnything) {
16131 pw.println(" (nothing)");
16135 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16136 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16137 if (mProcessesToGc.size() > 0) {
16138 boolean printed = false;
16139 long now = SystemClock.uptimeMillis();
16140 for (int i=0; i<mProcessesToGc.size(); i++) {
16141 ProcessRecord proc = mProcessesToGc.get(i);
16142 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16146 if (needSep) pw.println();
16148 pw.println(" Processes that are waiting to GC:");
16151 pw.print(" Process "); pw.println(proc);
16152 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
16153 pw.print(", last gced=");
16154 pw.print(now-proc.lastRequestedGc);
16155 pw.print(" ms ago, last lowMem=");
16156 pw.print(now-proc.lastLowMemory);
16157 pw.println(" ms ago");
16164 void printOomLevel(PrintWriter pw, String name, int adj) {
16168 if (adj < 10) pw.print(' ');
16170 if (adj > -10) pw.print(' ');
16176 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16180 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16181 int opti, boolean dumpAll) {
16182 boolean needSep = false;
16184 if (mLruProcesses.size() > 0) {
16185 if (needSep) pw.println();
16187 pw.println(" OOM levels:");
16188 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16189 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16190 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16191 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16192 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16193 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16194 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16195 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16196 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16197 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16198 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16199 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16200 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16201 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16203 if (needSep) pw.println();
16204 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
16205 pw.print(" total, non-act at ");
16206 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16207 pw.print(", non-svc at ");
16208 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16210 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
16214 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16217 pw.println(" mHomeProcess: " + mHomeProcess);
16218 pw.println(" mPreviousProcess: " + mPreviousProcess);
16219 if (mHeavyWeightProcess != null) {
16220 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
16227 * There are three ways to call this:
16228 * - no provider specified: dump all the providers
16229 * - a flattened component name that matched an existing provider was specified as the
16230 * first arg: dump that one provider
16231 * - the first arg isn't the flattened component name of an existing provider:
16232 * dump all providers whose component contains the first arg as a substring
16234 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16235 int opti, boolean dumpAll) {
16236 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16239 static class ItemMatcher {
16240 ArrayList<ComponentName> components;
16241 ArrayList<String> strings;
16242 ArrayList<Integer> objects;
16249 void build(String name) {
16250 ComponentName componentName = ComponentName.unflattenFromString(name);
16251 if (componentName != null) {
16252 if (components == null) {
16253 components = new ArrayList<ComponentName>();
16255 components.add(componentName);
16259 // Not a '/' separated full component name; maybe an object ID?
16261 objectId = Integer.parseInt(name, 16);
16262 if (objects == null) {
16263 objects = new ArrayList<Integer>();
16265 objects.add(objectId);
16267 } catch (RuntimeException e) {
16268 // Not an integer; just do string match.
16269 if (strings == null) {
16270 strings = new ArrayList<String>();
16278 int build(String[] args, int opti) {
16279 for (; opti<args.length; opti++) {
16280 String name = args[opti];
16281 if ("--".equals(name)) {
16289 boolean match(Object object, ComponentName comp) {
16293 if (components != null) {
16294 for (int i=0; i<components.size(); i++) {
16295 if (components.get(i).equals(comp)) {
16300 if (objects != null) {
16301 for (int i=0; i<objects.size(); i++) {
16302 if (System.identityHashCode(object) == objects.get(i)) {
16307 if (strings != null) {
16308 String flat = comp.flattenToString();
16309 for (int i=0; i<strings.size(); i++) {
16310 if (flat.contains(strings.get(i))) {
16320 * There are three things that cmd can be:
16321 * - a flattened component name that matches an existing activity
16322 * - the cmd arg isn't the flattened component name of an existing activity:
16323 * dump all activity whose component contains the cmd as a substring
16324 * - A hex number of the ActivityRecord object instance.
16326 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16327 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16329 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16330 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16331 ArrayList<ActivityRecord> activities;
16333 synchronized (this) {
16334 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16335 dumpFocusedStackOnly);
16338 if (activities.size() <= 0) {
16342 String[] newArgs = new String[args.length - opti];
16343 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16345 TaskRecord lastTask = null;
16346 boolean needSep = false;
16347 for (int i=activities.size()-1; i>=0; i--) {
16348 ActivityRecord r = activities.get(i);
16353 synchronized (this) {
16354 final TaskRecord task = r.getTask();
16355 if (lastTask != task) {
16357 pw.print("TASK "); pw.print(lastTask.affinity);
16358 pw.print(" id="); pw.print(lastTask.taskId);
16359 pw.print(" userId="); pw.println(lastTask.userId);
16361 lastTask.dump(pw, " ");
16365 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
16371 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16372 * there is a thread associated with the activity.
16374 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16375 final ActivityRecord r, String[] args, boolean dumpAll) {
16376 String innerPrefix = prefix + " ";
16377 synchronized (this) {
16378 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16379 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16381 if (r.app != null) pw.println(r.app.pid);
16382 else pw.println("(not running)");
16384 r.dump(pw, innerPrefix);
16387 if (r.app != null && r.app.thread != null) {
16388 // flush anything that is already in the PrintWriter since the thread is going
16389 // to write to the file descriptor directly
16392 TransferPipe tp = new TransferPipe();
16394 r.app.thread.dumpActivity(tp.getWriteFd(),
16395 r.appToken, innerPrefix, args);
16400 } catch (IOException e) {
16401 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16402 } catch (RemoteException e) {
16403 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16408 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16409 int opti, boolean dumpAll, String dumpPackage) {
16410 boolean needSep = false;
16411 boolean onlyHistory = false;
16412 boolean printedAnything = false;
16414 if ("history".equals(dumpPackage)) {
16415 if (opti < args.length && "-s".equals(args[opti])) {
16418 onlyHistory = true;
16419 dumpPackage = null;
16422 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16423 if (!onlyHistory && dumpAll) {
16424 if (mRegisteredReceivers.size() > 0) {
16425 boolean printed = false;
16426 Iterator it = mRegisteredReceivers.values().iterator();
16427 while (it.hasNext()) {
16428 ReceiverList r = (ReceiverList)it.next();
16429 if (dumpPackage != null && (r.app == null ||
16430 !dumpPackage.equals(r.app.info.packageName))) {
16434 pw.println(" Registered Receivers:");
16437 printedAnything = true;
16439 pw.print(" * "); pw.println(r);
16444 if (mReceiverResolver.dump(pw, needSep ?
16445 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
16446 " ", dumpPackage, false, false)) {
16448 printedAnything = true;
16452 for (BroadcastQueue q : mBroadcastQueues) {
16453 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16454 printedAnything |= needSep;
16459 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16460 for (int user=0; user<mStickyBroadcasts.size(); user++) {
16465 printedAnything = true;
16466 pw.print(" Sticky broadcasts for user ");
16467 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16468 StringBuilder sb = new StringBuilder(128);
16469 for (Map.Entry<String, ArrayList<Intent>> ent
16470 : mStickyBroadcasts.valueAt(user).entrySet()) {
16471 pw.print(" * Sticky action "); pw.print(ent.getKey());
16474 ArrayList<Intent> intents = ent.getValue();
16475 final int N = intents.size();
16476 for (int i=0; i<N; i++) {
16478 sb.append(" Intent: ");
16479 intents.get(i).toShortString(sb, false, true, false, false);
16480 pw.println(sb.toString());
16481 Bundle bundle = intents.get(i).getExtras();
16482 if (bundle != null) {
16484 pw.println(bundle.toString());
16494 if (!onlyHistory && dumpAll) {
16496 for (BroadcastQueue queue : mBroadcastQueues) {
16497 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
16498 + queue.mBroadcastsScheduled);
16500 pw.println(" mHandler:");
16501 mHandler.dump(new PrintWriterPrinter(pw), " ");
16503 printedAnything = true;
16506 if (!printedAnything) {
16507 pw.println(" (nothing)");
16511 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16512 int opti, boolean dumpAll, String dumpPackage) {
16513 if (mCurBroadcastStats == null) {
16517 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16518 final long now = SystemClock.elapsedRealtime();
16519 if (mLastBroadcastStats != null) {
16520 pw.print(" Last stats (from ");
16521 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16523 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16525 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16526 - mLastBroadcastStats.mStartUptime, pw);
16527 pw.println(" uptime):");
16528 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16529 pw.println(" (nothing)");
16533 pw.print(" Current stats (from ");
16534 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16535 pw.print(" to now, ");
16536 TimeUtils.formatDuration(SystemClock.uptimeMillis()
16537 - mCurBroadcastStats.mStartUptime, pw);
16538 pw.println(" uptime):");
16539 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
16540 pw.println(" (nothing)");
16544 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16545 int opti, boolean fullCheckin, String dumpPackage) {
16546 if (mCurBroadcastStats == null) {
16550 if (mLastBroadcastStats != null) {
16551 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16553 mLastBroadcastStats = null;
16557 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16559 mCurBroadcastStats = null;
16563 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16564 int opti, boolean dumpAll, String dumpPackage) {
16566 boolean printedAnything = false;
16568 ItemMatcher matcher = new ItemMatcher();
16569 matcher.build(args, opti);
16571 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16573 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16574 printedAnything |= needSep;
16576 if (mLaunchingProviders.size() > 0) {
16577 boolean printed = false;
16578 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16579 ContentProviderRecord r = mLaunchingProviders.get(i);
16580 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16584 if (needSep) pw.println();
16586 pw.println(" Launching content providers:");
16588 printedAnything = true;
16590 pw.print(" Launching #"); pw.print(i); pw.print(": ");
16595 if (!printedAnything) {
16596 pw.println(" (nothing)");
16600 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16601 int opti, boolean dumpAll, String dumpPackage) {
16602 boolean needSep = false;
16603 boolean printedAnything = false;
16605 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16607 if (mGrantedUriPermissions.size() > 0) {
16608 boolean printed = false;
16610 if (dumpPackage != null) {
16612 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16613 MATCH_ANY_USER, 0);
16614 } catch (NameNotFoundException e) {
16618 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16619 int uid = mGrantedUriPermissions.keyAt(i);
16620 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16623 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16625 if (needSep) pw.println();
16627 pw.println(" Granted Uri Permissions:");
16629 printedAnything = true;
16631 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
16632 for (UriPermission perm : perms.values()) {
16633 pw.print(" "); pw.println(perm);
16635 perm.dump(pw, " ");
16641 if (!printedAnything) {
16642 pw.println(" (nothing)");
16646 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16647 int opti, boolean dumpAll, String dumpPackage) {
16648 boolean printed = false;
16650 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16652 if (mIntentSenderRecords.size() > 0) {
16653 // Organize these by package name, so they are easier to read.
16654 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16655 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16656 final Iterator<WeakReference<PendingIntentRecord>> it
16657 = mIntentSenderRecords.values().iterator();
16658 while (it.hasNext()) {
16659 WeakReference<PendingIntentRecord> ref = it.next();
16660 PendingIntentRecord rec = ref != null ? ref.get() : null;
16665 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16668 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16669 if (list == null) {
16670 list = new ArrayList<>();
16671 byPackage.put(rec.key.packageName, list);
16675 for (int i = 0; i < byPackage.size(); i++) {
16676 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16678 pw.print(" * "); pw.print(byPackage.keyAt(i));
16679 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16680 for (int j = 0; j < intents.size(); j++) {
16681 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16683 intents.get(j).dump(pw, " ");
16687 if (weakRefs.size() > 0) {
16689 pw.println(" * WEAK REFS:");
16690 for (int i = 0; i < weakRefs.size(); i++) {
16691 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16697 pw.println(" (nothing)");
16701 private static final int dumpProcessList(PrintWriter pw,
16702 ActivityManagerService service, List list,
16703 String prefix, String normalLabel, String persistentLabel,
16704 String dumpPackage) {
16706 final int N = list.size()-1;
16707 for (int i=N; i>=0; i--) {
16708 ProcessRecord r = (ProcessRecord)list.get(i);
16709 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16712 pw.println(String.format("%s%s #%2d: %s",
16713 prefix, (r.persistent ? persistentLabel : normalLabel),
16715 if (r.persistent) {
16722 private static final boolean dumpProcessOomList(PrintWriter pw,
16723 ActivityManagerService service, List<ProcessRecord> origList,
16724 String prefix, String normalLabel, String persistentLabel,
16725 boolean inclDetails, String dumpPackage) {
16727 ArrayList<Pair<ProcessRecord, Integer>> list
16728 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16729 for (int i=0; i<origList.size(); i++) {
16730 ProcessRecord r = origList.get(i);
16731 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16734 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16737 if (list.size() <= 0) {
16741 Comparator<Pair<ProcessRecord, Integer>> comparator
16742 = new Comparator<Pair<ProcessRecord, Integer>>() {
16744 public int compare(Pair<ProcessRecord, Integer> object1,
16745 Pair<ProcessRecord, Integer> object2) {
16746 if (object1.first.setAdj != object2.first.setAdj) {
16747 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16749 if (object1.first.setProcState != object2.first.setProcState) {
16750 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16752 if (object1.second.intValue() != object2.second.intValue()) {
16753 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16759 Collections.sort(list, comparator);
16761 final long curUptime = SystemClock.uptimeMillis();
16762 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16764 for (int i=list.size()-1; i>=0; i--) {
16765 ProcessRecord r = list.get(i).first;
16766 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16768 switch (r.setSchedGroup) {
16769 case ProcessList.SCHED_GROUP_BACKGROUND:
16772 case ProcessList.SCHED_GROUP_DEFAULT:
16775 case ProcessList.SCHED_GROUP_TOP_APP:
16783 if (r.foregroundActivities) {
16785 } else if (r.foregroundServices) {
16790 String procState = ProcessList.makeProcStateString(r.curProcState);
16792 pw.print(r.persistent ? persistentLabel : normalLabel);
16794 int num = (origList.size()-1)-list.get(i).second;
16795 if (num < 10) pw.print(' ');
16800 pw.print(schedGroup);
16802 pw.print(foreground);
16804 pw.print(procState);
16806 if (r.trimMemoryLevel < 10) pw.print(' ');
16807 pw.print(r.trimMemoryLevel);
16809 pw.print(r.toShortString());
16811 pw.print(r.adjType);
16813 if (r.adjSource != null || r.adjTarget != null) {
16816 if (r.adjTarget instanceof ComponentName) {
16817 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16818 } else if (r.adjTarget != null) {
16819 pw.print(r.adjTarget.toString());
16821 pw.print("{null}");
16824 if (r.adjSource instanceof ProcessRecord) {
16826 pw.print(((ProcessRecord)r.adjSource).toShortString());
16828 } else if (r.adjSource != null) {
16829 pw.println(r.adjSource.toString());
16831 pw.println("{null}");
16837 pw.print("oom: max="); pw.print(r.maxAdj);
16838 pw.print(" curRaw="); pw.print(r.curRawAdj);
16839 pw.print(" setRaw="); pw.print(r.setRawAdj);
16840 pw.print(" cur="); pw.print(r.curAdj);
16841 pw.print(" set="); pw.println(r.setAdj);
16844 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16845 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16846 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16847 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16848 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16852 pw.print("cached="); pw.print(r.cached);
16853 pw.print(" empty="); pw.print(r.empty);
16854 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16856 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16857 if (r.lastCpuTime != 0) {
16858 long timeUsed = r.curCpuTime - r.lastCpuTime;
16861 pw.print("run cpu over ");
16862 TimeUtils.formatDuration(uptimeSince, pw);
16863 pw.print(" used ");
16864 TimeUtils.formatDuration(timeUsed, pw);
16866 pw.print((timeUsed*100)/uptimeSince);
16875 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16877 ArrayList<ProcessRecord> procs;
16878 synchronized (this) {
16879 if (args != null && args.length > start
16880 && args[start].charAt(0) != '-') {
16881 procs = new ArrayList<ProcessRecord>();
16884 pid = Integer.parseInt(args[start]);
16885 } catch (NumberFormatException e) {
16887 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16888 ProcessRecord proc = mLruProcesses.get(i);
16889 if (proc.pid == pid) {
16891 } else if (allPkgs && proc.pkgList != null
16892 && proc.pkgList.containsKey(args[start])) {
16894 } else if (proc.processName.equals(args[start])) {
16898 if (procs.size() <= 0) {
16902 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16908 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16909 PrintWriter pw, String[] args) {
16910 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16911 if (procs == null) {
16912 pw.println("No process found for: " + args[0]);
16916 long uptime = SystemClock.uptimeMillis();
16917 long realtime = SystemClock.elapsedRealtime();
16918 pw.println("Applications Graphics Acceleration Info:");
16919 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16921 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16922 ProcessRecord r = procs.get(i);
16923 if (r.thread != null) {
16924 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16927 TransferPipe tp = new TransferPipe();
16929 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16934 } catch (IOException e) {
16935 pw.println("Failure while dumping the app: " + r);
16937 } catch (RemoteException e) {
16938 pw.println("Got a RemoteException while dumping the app " + r);
16945 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16946 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16947 if (procs == null) {
16948 pw.println("No process found for: " + args[0]);
16952 pw.println("Applications Database Info:");
16954 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16955 ProcessRecord r = procs.get(i);
16956 if (r.thread != null) {
16957 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16960 TransferPipe tp = new TransferPipe();
16962 r.thread.dumpDbInfo(tp.getWriteFd(), args);
16967 } catch (IOException e) {
16968 pw.println("Failure while dumping the app: " + r);
16970 } catch (RemoteException e) {
16971 pw.println("Got a RemoteException while dumping the app " + r);
16978 final static class MemItem {
16979 final boolean isProc;
16980 final String label;
16981 final String shortLabel;
16983 final long swapPss;
16985 final boolean hasActivities;
16986 ArrayList<MemItem> subitems;
16988 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16989 boolean _hasActivities) {
16992 shortLabel = _shortLabel;
16994 swapPss = _swapPss;
16996 hasActivities = _hasActivities;
16999 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
17002 shortLabel = _shortLabel;
17004 swapPss = _swapPss;
17006 hasActivities = false;
17010 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
17011 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
17012 if (sort && !isCompact) {
17013 Collections.sort(items, new Comparator<MemItem>() {
17015 public int compare(MemItem lhs, MemItem rhs) {
17016 if (lhs.pss < rhs.pss) {
17018 } else if (lhs.pss > rhs.pss) {
17026 for (int i=0; i<items.size(); i++) {
17027 MemItem mi = items.get(i);
17030 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
17031 mi.label, stringifyKBSize(mi.swapPss));
17033 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
17035 } else if (mi.isProc) {
17036 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
17037 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
17038 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
17039 pw.println(mi.hasActivities ? ",a" : ",e");
17041 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
17042 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
17044 if (mi.subitems != null) {
17045 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
17046 true, isCompact, dumpSwapPss);
17051 // These are in KB.
17052 static final long[] DUMP_MEM_BUCKETS = new long[] {
17053 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
17054 120*1024, 160*1024, 200*1024,
17055 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
17056 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
17059 static final void appendMemBucket(StringBuilder out, long memKB, String label,
17060 boolean stackLike) {
17061 int start = label.lastIndexOf('.');
17062 if (start >= 0) start++;
17064 int end = label.length();
17065 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
17066 if (DUMP_MEM_BUCKETS[i] >= memKB) {
17067 long bucket = DUMP_MEM_BUCKETS[i]/1024;
17068 out.append(bucket);
17069 out.append(stackLike ? "MB." : "MB ");
17070 out.append(label, start, end);
17074 out.append(memKB/1024);
17075 out.append(stackLike ? "MB." : "MB ");
17076 out.append(label, start, end);
17079 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17080 ProcessList.NATIVE_ADJ,
17081 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17082 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17083 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17084 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17085 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17086 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17088 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17090 "System", "Persistent", "Persistent Service", "Foreground",
17091 "Visible", "Perceptible",
17092 "Heavy Weight", "Backup",
17093 "A Services", "Home",
17094 "Previous", "B Services", "Cached"
17096 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17098 "sys", "pers", "persvc", "fore",
17101 "servicea", "home",
17102 "prev", "serviceb", "cached"
17105 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17106 long realtime, boolean isCheckinRequest, boolean isCompact) {
17108 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17110 if (isCheckinRequest || isCompact) {
17111 // short checkin version
17112 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17114 pw.println("Applications Memory Usage (in Kilobytes):");
17115 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17119 private static final int KSM_SHARED = 0;
17120 private static final int KSM_SHARING = 1;
17121 private static final int KSM_UNSHARED = 2;
17122 private static final int KSM_VOLATILE = 3;
17124 private final long[] getKsmInfo() {
17125 long[] longOut = new long[4];
17126 final int[] SINGLE_LONG_FORMAT = new int[] {
17127 PROC_SPACE_TERM| PROC_OUT_LONG
17129 long[] longTmp = new long[1];
17130 readProcFile("/sys/kernel/mm/ksm/pages_shared",
17131 SINGLE_LONG_FORMAT, null, longTmp, null);
17132 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17134 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17135 SINGLE_LONG_FORMAT, null, longTmp, null);
17136 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17138 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17139 SINGLE_LONG_FORMAT, null, longTmp, null);
17140 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17142 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17143 SINGLE_LONG_FORMAT, null, longTmp, null);
17144 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17148 private static String stringifySize(long size, int order) {
17149 Locale locale = Locale.US;
17152 return String.format(locale, "%,13d", size);
17154 return String.format(locale, "%,9dK", size / 1024);
17156 return String.format(locale, "%,5dM", size / 1024 / 1024);
17157 case 1024 * 1024 * 1024:
17158 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17160 throw new IllegalArgumentException("Invalid size order");
17164 private static String stringifyKBSize(long size) {
17165 return stringifySize(size * 1024, 1024);
17168 // Update this version number in case you change the 'compact' format
17169 private static final int MEMINFO_COMPACT_VERSION = 1;
17171 final void dumpApplicationMemoryUsage(FileDescriptor fd,
17172 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17173 boolean dumpDetails = false;
17174 boolean dumpFullDetails = false;
17175 boolean dumpDalvik = false;
17176 boolean dumpSummaryOnly = false;
17177 boolean dumpUnreachable = false;
17178 boolean oomOnly = false;
17179 boolean isCompact = false;
17180 boolean localOnly = false;
17181 boolean packages = false;
17182 boolean isCheckinRequest = false;
17183 boolean dumpSwapPss = false;
17186 while (opti < args.length) {
17187 String opt = args[opti];
17188 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17192 if ("-a".equals(opt)) {
17193 dumpDetails = true;
17194 dumpFullDetails = true;
17196 dumpSwapPss = true;
17197 } else if ("-d".equals(opt)) {
17199 } else if ("-c".equals(opt)) {
17201 } else if ("-s".equals(opt)) {
17202 dumpDetails = true;
17203 dumpSummaryOnly = true;
17204 } else if ("-S".equals(opt)) {
17205 dumpSwapPss = true;
17206 } else if ("--unreachable".equals(opt)) {
17207 dumpUnreachable = true;
17208 } else if ("--oom".equals(opt)) {
17210 } else if ("--local".equals(opt)) {
17212 } else if ("--package".equals(opt)) {
17214 } else if ("--checkin".equals(opt)) {
17215 isCheckinRequest = true;
17217 } else if ("-h".equals(opt)) {
17218 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17219 pw.println(" -a: include all available information for each process.");
17220 pw.println(" -d: include dalvik details.");
17221 pw.println(" -c: dump in a compact machine-parseable representation.");
17222 pw.println(" -s: dump only summary of application memory usage.");
17223 pw.println(" -S: dump also SwapPss.");
17224 pw.println(" --oom: only show processes organized by oom adj.");
17225 pw.println(" --local: only collect details locally, don't call process.");
17226 pw.println(" --package: interpret process arg as package, dumping all");
17227 pw.println(" processes that have loaded that package.");
17228 pw.println(" --checkin: dump data for a checkin");
17229 pw.println("If [process] is specified it can be the name or ");
17230 pw.println("pid of a specific process to dump.");
17233 pw.println("Unknown argument: " + opt + "; use -h for help");
17237 long uptime = SystemClock.uptimeMillis();
17238 long realtime = SystemClock.elapsedRealtime();
17239 final long[] tmpLong = new long[1];
17241 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17242 if (procs == null) {
17243 // No Java processes. Maybe they want to print a native process.
17244 if (args != null && args.length > opti
17245 && args[opti].charAt(0) != '-') {
17246 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17247 = new ArrayList<ProcessCpuTracker.Stats>();
17248 updateCpuStatsNow();
17251 findPid = Integer.parseInt(args[opti]);
17252 } catch (NumberFormatException e) {
17254 synchronized (mProcessCpuTracker) {
17255 final int N = mProcessCpuTracker.countStats();
17256 for (int i=0; i<N; i++) {
17257 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17258 if (st.pid == findPid || (st.baseName != null
17259 && st.baseName.equals(args[opti]))) {
17260 nativeProcs.add(st);
17264 if (nativeProcs.size() > 0) {
17265 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17267 Debug.MemoryInfo mi = null;
17268 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17269 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17270 final int pid = r.pid;
17271 if (!isCheckinRequest && dumpDetails) {
17272 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17275 mi = new Debug.MemoryInfo();
17277 if (dumpDetails || (!brief && !oomOnly)) {
17278 Debug.getMemoryInfo(pid, mi);
17280 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17281 mi.dalvikPrivateDirty = (int)tmpLong[0];
17283 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17284 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17285 if (isCheckinRequest) {
17292 pw.println("No process found for: " + args[opti]);
17296 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17297 dumpDetails = true;
17300 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17302 String[] innerArgs = new String[args.length-opti];
17303 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17305 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17306 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17307 long nativePss = 0;
17308 long nativeSwapPss = 0;
17309 long dalvikPss = 0;
17310 long dalvikSwapPss = 0;
17311 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17313 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17316 long otherSwapPss = 0;
17317 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17318 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17320 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17321 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17322 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17323 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17326 long totalSwapPss = 0;
17327 long cachedPss = 0;
17328 long cachedSwapPss = 0;
17329 boolean hasSwapPss = false;
17331 Debug.MemoryInfo mi = null;
17332 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17333 final ProcessRecord r = procs.get(i);
17334 final IApplicationThread thread;
17337 final boolean hasActivities;
17338 synchronized (this) {
17341 oomAdj = r.getSetAdjWithServices();
17342 hasActivities = r.activities.size() > 0;
17344 if (thread != null) {
17345 if (!isCheckinRequest && dumpDetails) {
17346 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17349 mi = new Debug.MemoryInfo();
17351 if (dumpDetails || (!brief && !oomOnly)) {
17352 Debug.getMemoryInfo(pid, mi);
17353 hasSwapPss = mi.hasSwappedOutPss;
17355 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17356 mi.dalvikPrivateDirty = (int)tmpLong[0];
17360 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17361 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17362 if (isCheckinRequest) {
17368 TransferPipe tp = new TransferPipe();
17370 thread.dumpMemInfo(tp.getWriteFd(),
17371 mi, isCheckinRequest, dumpFullDetails,
17372 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17377 } catch (IOException e) {
17378 if (!isCheckinRequest) {
17379 pw.println("Got IoException! " + e);
17382 } catch (RemoteException e) {
17383 if (!isCheckinRequest) {
17384 pw.println("Got RemoteException! " + e);
17391 final long myTotalPss = mi.getTotalPss();
17392 final long myTotalUss = mi.getTotalUss();
17393 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17395 synchronized (this) {
17396 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17397 // Record this for posterity if the process has been stable.
17398 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17402 if (!isCheckinRequest && mi != null) {
17403 totalPss += myTotalPss;
17404 totalSwapPss += myTotalSwapPss;
17405 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17406 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17407 myTotalSwapPss, pid, hasActivities);
17408 procMems.add(pssItem);
17409 procMemsMap.put(pid, pssItem);
17411 nativePss += mi.nativePss;
17412 nativeSwapPss += mi.nativeSwappedOutPss;
17413 dalvikPss += mi.dalvikPss;
17414 dalvikSwapPss += mi.dalvikSwappedOutPss;
17415 for (int j=0; j<dalvikSubitemPss.length; j++) {
17416 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17417 dalvikSubitemSwapPss[j] +=
17418 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17420 otherPss += mi.otherPss;
17421 otherSwapPss += mi.otherSwappedOutPss;
17422 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17423 long mem = mi.getOtherPss(j);
17426 mem = mi.getOtherSwappedOutPss(j);
17427 miscSwapPss[j] += mem;
17428 otherSwapPss -= mem;
17431 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17432 cachedPss += myTotalPss;
17433 cachedSwapPss += myTotalSwapPss;
17436 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17437 if (oomIndex == (oomPss.length - 1)
17438 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17439 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17440 oomPss[oomIndex] += myTotalPss;
17441 oomSwapPss[oomIndex] += myTotalSwapPss;
17442 if (oomProcs[oomIndex] == null) {
17443 oomProcs[oomIndex] = new ArrayList<MemItem>();
17445 oomProcs[oomIndex].add(pssItem);
17453 long nativeProcTotalPss = 0;
17455 if (!isCheckinRequest && procs.size() > 1 && !packages) {
17456 // If we are showing aggregations, also look for native processes to
17457 // include so that our aggregations are more accurate.
17458 updateCpuStatsNow();
17460 synchronized (mProcessCpuTracker) {
17461 final int N = mProcessCpuTracker.countStats();
17462 for (int i=0; i<N; i++) {
17463 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17464 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17466 mi = new Debug.MemoryInfo();
17468 if (!brief && !oomOnly) {
17469 Debug.getMemoryInfo(st.pid, mi);
17471 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17472 mi.nativePrivateDirty = (int)tmpLong[0];
17475 final long myTotalPss = mi.getTotalPss();
17476 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17477 totalPss += myTotalPss;
17478 nativeProcTotalPss += myTotalPss;
17480 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17481 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17482 procMems.add(pssItem);
17484 nativePss += mi.nativePss;
17485 nativeSwapPss += mi.nativeSwappedOutPss;
17486 dalvikPss += mi.dalvikPss;
17487 dalvikSwapPss += mi.dalvikSwappedOutPss;
17488 for (int j=0; j<dalvikSubitemPss.length; j++) {
17489 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17490 dalvikSubitemSwapPss[j] +=
17491 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17493 otherPss += mi.otherPss;
17494 otherSwapPss += mi.otherSwappedOutPss;
17495 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17496 long mem = mi.getOtherPss(j);
17499 mem = mi.getOtherSwappedOutPss(j);
17500 miscSwapPss[j] += mem;
17501 otherSwapPss -= mem;
17503 oomPss[0] += myTotalPss;
17504 oomSwapPss[0] += myTotalSwapPss;
17505 if (oomProcs[0] == null) {
17506 oomProcs[0] = new ArrayList<MemItem>();
17508 oomProcs[0].add(pssItem);
17513 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17515 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17516 final int dalvikId = -2;
17517 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17518 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17519 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17520 String label = Debug.MemoryInfo.getOtherLabel(j);
17521 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17523 if (dalvikSubitemPss.length > 0) {
17524 // Add dalvik subitems.
17525 for (MemItem memItem : catMems) {
17526 int memItemStart = 0, memItemEnd = 0;
17527 if (memItem.id == dalvikId) {
17528 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17529 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17530 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17531 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17532 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17533 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17534 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17535 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17536 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17537 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17538 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17540 continue; // No subitems, continue.
17542 memItem.subitems = new ArrayList<MemItem>();
17543 for (int j=memItemStart; j<=memItemEnd; j++) {
17544 final String name = Debug.MemoryInfo.getOtherLabel(
17545 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17546 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17547 dalvikSubitemSwapPss[j], j));
17552 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17553 for (int j=0; j<oomPss.length; j++) {
17554 if (oomPss[j] != 0) {
17555 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17556 : DUMP_MEM_OOM_LABEL[j];
17557 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17558 DUMP_MEM_OOM_ADJ[j]);
17559 item.subitems = oomProcs[j];
17564 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17565 if (!brief && !oomOnly && !isCompact) {
17567 pw.println("Total PSS by process:");
17568 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
17572 pw.println("Total PSS by OOM adjustment:");
17574 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
17575 if (!brief && !oomOnly) {
17576 PrintWriter out = categoryPw != null ? categoryPw : pw;
17579 out.println("Total PSS by category:");
17581 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
17586 MemInfoReader memInfo = new MemInfoReader();
17587 memInfo.readMemInfo();
17588 if (nativeProcTotalPss > 0) {
17589 synchronized (this) {
17590 final long cachedKb = memInfo.getCachedSizeKb();
17591 final long freeKb = memInfo.getFreeSizeKb();
17592 final long zramKb = memInfo.getZramTotalSizeKb();
17593 final long kernelKb = memInfo.getKernelUsedSizeKb();
17594 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17595 kernelKb*1024, nativeProcTotalPss*1024);
17596 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17597 nativeProcTotalPss);
17602 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17603 pw.print(" (status ");
17604 switch (mLastMemoryLevel) {
17605 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17606 pw.println("normal)");
17608 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17609 pw.println("moderate)");
17611 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17612 pw.println("low)");
17614 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17615 pw.println("critical)");
17618 pw.print(mLastMemoryLevel);
17622 pw.print(" Free RAM: ");
17623 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17624 + memInfo.getFreeSizeKb()));
17626 pw.print(stringifyKBSize(cachedPss));
17627 pw.print(" cached pss + ");
17628 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17629 pw.print(" cached kernel + ");
17630 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17631 pw.println(" free)");
17633 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17634 pw.print(cachedPss + memInfo.getCachedSizeKb()
17635 + memInfo.getFreeSizeKb()); pw.print(",");
17636 pw.println(totalPss - cachedPss);
17639 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17640 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17641 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17643 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17644 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17645 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17646 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17647 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17649 pw.print("lostram,"); pw.println(lostRAM);
17652 if (memInfo.getZramTotalSizeKb() != 0) {
17654 pw.print(" ZRAM: ");
17655 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17656 pw.print(" physical used for ");
17657 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17658 - memInfo.getSwapFreeSizeKb()));
17659 pw.print(" in swap (");
17660 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17661 pw.println(" total swap)");
17663 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17664 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17665 pw.println(memInfo.getSwapFreeSizeKb());
17668 final long[] ksm = getKsmInfo();
17670 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17671 || ksm[KSM_VOLATILE] != 0) {
17672 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17673 pw.print(" saved from shared ");
17674 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17675 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17676 pw.print(" unshared; ");
17677 pw.print(stringifyKBSize(
17678 ksm[KSM_VOLATILE])); pw.println(" volatile");
17680 pw.print(" Tuning: ");
17681 pw.print(ActivityManager.staticGetMemoryClass());
17682 pw.print(" (large ");
17683 pw.print(ActivityManager.staticGetLargeMemoryClass());
17684 pw.print("), oom ");
17685 pw.print(stringifySize(
17686 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17687 pw.print(", restore limit ");
17688 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17689 if (ActivityManager.isLowRamDeviceStatic()) {
17690 pw.print(" (low-ram)");
17692 if (ActivityManager.isHighEndGfx()) {
17693 pw.print(" (high-end-gfx)");
17697 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17698 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17699 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17700 pw.print("tuning,");
17701 pw.print(ActivityManager.staticGetMemoryClass());
17703 pw.print(ActivityManager.staticGetLargeMemoryClass());
17705 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17706 if (ActivityManager.isLowRamDeviceStatic()) {
17707 pw.print(",low-ram");
17709 if (ActivityManager.isHighEndGfx()) {
17710 pw.print(",high-end-gfx");
17718 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17719 long memtrack, String name) {
17721 sb.append(ProcessList.makeOomAdjString(oomAdj));
17723 sb.append(ProcessList.makeProcStateString(procState));
17725 ProcessList.appendRamKb(sb, pss);
17728 if (memtrack > 0) {
17730 sb.append(stringifyKBSize(memtrack));
17731 sb.append(" memtrack)");
17735 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17736 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17737 sb.append(" (pid ");
17740 sb.append(mi.adjType);
17742 if (mi.adjReason != null) {
17744 sb.append(mi.adjReason);
17749 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17750 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17751 for (int i=0, N=memInfos.size(); i<N; i++) {
17752 ProcessMemInfo mi = memInfos.get(i);
17753 infoMap.put(mi.pid, mi);
17755 updateCpuStatsNow();
17756 long[] memtrackTmp = new long[1];
17757 final List<ProcessCpuTracker.Stats> stats;
17758 // Get a list of Stats that have vsize > 0
17759 synchronized (mProcessCpuTracker) {
17760 stats = mProcessCpuTracker.getStats((st) -> {
17761 return st.vsize > 0;
17764 final int statsCount = stats.size();
17765 for (int i = 0; i < statsCount; i++) {
17766 ProcessCpuTracker.Stats st = stats.get(i);
17767 long pss = Debug.getPss(st.pid, null, memtrackTmp);
17769 if (infoMap.indexOfKey(st.pid) < 0) {
17770 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17771 ProcessList.NATIVE_ADJ, -1, "native", null);
17773 mi.memtrack = memtrackTmp[0];
17780 long totalMemtrack = 0;
17781 for (int i=0, N=memInfos.size(); i<N; i++) {
17782 ProcessMemInfo mi = memInfos.get(i);
17784 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17785 mi.memtrack = memtrackTmp[0];
17787 totalPss += mi.pss;
17788 totalMemtrack += mi.memtrack;
17790 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17791 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17792 if (lhs.oomAdj != rhs.oomAdj) {
17793 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17795 if (lhs.pss != rhs.pss) {
17796 return lhs.pss < rhs.pss ? 1 : -1;
17802 StringBuilder tag = new StringBuilder(128);
17803 StringBuilder stack = new StringBuilder(128);
17804 tag.append("Low on memory -- ");
17805 appendMemBucket(tag, totalPss, "total", false);
17806 appendMemBucket(stack, totalPss, "total", true);
17808 StringBuilder fullNativeBuilder = new StringBuilder(1024);
17809 StringBuilder shortNativeBuilder = new StringBuilder(1024);
17810 StringBuilder fullJavaBuilder = new StringBuilder(1024);
17812 boolean firstLine = true;
17813 int lastOomAdj = Integer.MIN_VALUE;
17814 long extraNativeRam = 0;
17815 long extraNativeMemtrack = 0;
17816 long cachedPss = 0;
17817 for (int i=0, N=memInfos.size(); i<N; i++) {
17818 ProcessMemInfo mi = memInfos.get(i);
17820 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17821 cachedPss += mi.pss;
17824 if (mi.oomAdj != ProcessList.NATIVE_ADJ
17825 && (mi.oomAdj < ProcessList.SERVICE_ADJ
17826 || mi.oomAdj == ProcessList.HOME_APP_ADJ
17827 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17828 if (lastOomAdj != mi.oomAdj) {
17829 lastOomAdj = mi.oomAdj;
17830 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17833 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17838 stack.append("\n\t at ");
17846 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17847 appendMemBucket(tag, mi.pss, mi.name, false);
17849 appendMemBucket(stack, mi.pss, mi.name, true);
17850 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17851 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17853 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17854 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17855 stack.append(DUMP_MEM_OOM_LABEL[k]);
17857 stack.append(DUMP_MEM_OOM_ADJ[k]);
17864 appendMemInfo(fullNativeBuilder, mi);
17865 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17866 // The short form only has native processes that are >= 512K.
17867 if (mi.pss >= 512) {
17868 appendMemInfo(shortNativeBuilder, mi);
17870 extraNativeRam += mi.pss;
17871 extraNativeMemtrack += mi.memtrack;
17874 // Short form has all other details, but if we have collected RAM
17875 // from smaller native processes let's dump a summary of that.
17876 if (extraNativeRam > 0) {
17877 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17878 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17879 shortNativeBuilder.append('\n');
17880 extraNativeRam = 0;
17882 appendMemInfo(fullJavaBuilder, mi);
17886 fullJavaBuilder.append(" ");
17887 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17888 fullJavaBuilder.append(": TOTAL");
17889 if (totalMemtrack > 0) {
17890 fullJavaBuilder.append(" (");
17891 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17892 fullJavaBuilder.append(" memtrack)");
17895 fullJavaBuilder.append("\n");
17897 MemInfoReader memInfo = new MemInfoReader();
17898 memInfo.readMemInfo();
17899 final long[] infos = memInfo.getRawInfo();
17901 StringBuilder memInfoBuilder = new StringBuilder(1024);
17902 Debug.getMemInfo(infos);
17903 memInfoBuilder.append(" MemInfo: ");
17904 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17905 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17906 memInfoBuilder.append(stringifyKBSize(
17907 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17908 memInfoBuilder.append(stringifyKBSize(
17909 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17910 memInfoBuilder.append(stringifyKBSize(
17911 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17912 memInfoBuilder.append(" ");
17913 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17914 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17915 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17916 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17917 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17918 memInfoBuilder.append(" ZRAM: ");
17919 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17920 memInfoBuilder.append(" RAM, ");
17921 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17922 memInfoBuilder.append(" swap total, ");
17923 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17924 memInfoBuilder.append(" swap free\n");
17926 final long[] ksm = getKsmInfo();
17927 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17928 || ksm[KSM_VOLATILE] != 0) {
17929 memInfoBuilder.append(" KSM: ");
17930 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17931 memInfoBuilder.append(" saved from shared ");
17932 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17933 memInfoBuilder.append("\n ");
17934 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17935 memInfoBuilder.append(" unshared; ");
17936 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17937 memInfoBuilder.append(" volatile\n");
17939 memInfoBuilder.append(" Free RAM: ");
17940 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17941 + memInfo.getFreeSizeKb()));
17942 memInfoBuilder.append("\n");
17943 memInfoBuilder.append(" Used RAM: ");
17944 memInfoBuilder.append(stringifyKBSize(
17945 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17946 memInfoBuilder.append("\n");
17947 memInfoBuilder.append(" Lost RAM: ");
17948 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17949 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17950 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17951 memInfoBuilder.append("\n");
17952 Slog.i(TAG, "Low on memory:");
17953 Slog.i(TAG, shortNativeBuilder.toString());
17954 Slog.i(TAG, fullJavaBuilder.toString());
17955 Slog.i(TAG, memInfoBuilder.toString());
17957 StringBuilder dropBuilder = new StringBuilder(1024);
17959 StringWriter oomSw = new StringWriter();
17960 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17961 StringWriter catSw = new StringWriter();
17962 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17963 String[] emptyArgs = new String[] { };
17964 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
17966 String oomString = oomSw.toString();
17968 dropBuilder.append("Low on memory:");
17969 dropBuilder.append(stack);
17970 dropBuilder.append('\n');
17971 dropBuilder.append(fullNativeBuilder);
17972 dropBuilder.append(fullJavaBuilder);
17973 dropBuilder.append('\n');
17974 dropBuilder.append(memInfoBuilder);
17975 dropBuilder.append('\n');
17977 dropBuilder.append(oomString);
17978 dropBuilder.append('\n');
17980 StringWriter catSw = new StringWriter();
17981 synchronized (ActivityManagerService.this) {
17982 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17983 String[] emptyArgs = new String[] { };
17985 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17987 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17988 false, null).dumpLocked();
17990 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17993 dropBuilder.append(catSw.toString());
17994 addErrorToDropBox("lowmem", null, "system_server", null,
17995 null, tag.toString(), dropBuilder.toString(), null, null);
17996 //Slog.i(TAG, "Sent to dropbox:");
17997 //Slog.i(TAG, dropBuilder.toString());
17998 synchronized (ActivityManagerService.this) {
17999 long now = SystemClock.uptimeMillis();
18000 if (mLastMemUsageReportTime < now) {
18001 mLastMemUsageReportTime = now;
18007 * Searches array of arguments for the specified string
18008 * @param args array of argument strings
18009 * @param value value to search for
18010 * @return true if the value is contained in the array
18012 private static boolean scanArgs(String[] args, String value) {
18013 if (args != null) {
18014 for (String arg : args) {
18015 if (value.equals(arg)) {
18023 private final boolean removeDyingProviderLocked(ProcessRecord proc,
18024 ContentProviderRecord cpr, boolean always) {
18025 final boolean inLaunching = mLaunchingProviders.contains(cpr);
18027 if (!inLaunching || always) {
18028 synchronized (cpr) {
18029 cpr.launchingApp = null;
18032 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
18033 String names[] = cpr.info.authority.split(";");
18034 for (int j = 0; j < names.length; j++) {
18035 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
18039 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
18040 ContentProviderConnection conn = cpr.connections.get(i);
18041 if (conn.waiting) {
18042 // If this connection is waiting for the provider, then we don't
18043 // need to mess with its process unless we are always removing
18044 // or for some reason the provider is not currently launching.
18045 if (inLaunching && !always) {
18049 ProcessRecord capp = conn.client;
18051 if (conn.stableCount > 0) {
18052 if (!capp.persistent && capp.thread != null
18054 && capp.pid != MY_PID) {
18055 capp.kill("depends on provider "
18056 + cpr.name.flattenToShortString()
18057 + " in dying proc " + (proc != null ? proc.processName : "??")
18058 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
18060 } else if (capp.thread != null && conn.provider.provider != null) {
18062 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
18063 } catch (RemoteException e) {
18065 // In the protocol here, we don't expect the client to correctly
18066 // clean up this connection, we'll just remove it.
18067 cpr.connections.remove(i);
18068 if (conn.client.conProviders.remove(conn)) {
18069 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18074 if (inLaunching && always) {
18075 mLaunchingProviders.remove(cpr);
18077 return inLaunching;
18081 * Main code for cleaning up a process when it has gone away. This is
18082 * called both as a result of the process dying, or directly when stopping
18083 * a process when running in single process mode.
18085 * @return Returns true if the given process has been restarted, so the
18086 * app that was passed in must remain on the process lists.
18088 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18089 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18091 removeLruProcessLocked(app);
18092 ProcessList.remove(app.pid);
18095 mProcessesToGc.remove(app);
18096 mPendingPssProcesses.remove(app);
18098 // Dismiss any open dialogs.
18099 if (app.crashDialog != null && !app.forceCrashReport) {
18100 app.crashDialog.dismiss();
18101 app.crashDialog = null;
18103 if (app.anrDialog != null) {
18104 app.anrDialog.dismiss();
18105 app.anrDialog = null;
18107 if (app.waitDialog != null) {
18108 app.waitDialog.dismiss();
18109 app.waitDialog = null;
18112 app.crashing = false;
18113 app.notResponding = false;
18115 app.resetPackageList(mProcessStats);
18116 app.unlinkDeathRecipient();
18117 app.makeInactive(mProcessStats);
18118 app.waitingToKill = null;
18119 app.forcingToImportant = null;
18120 updateProcessForegroundLocked(app, false, false);
18121 app.foregroundActivities = false;
18122 app.hasShownUi = false;
18123 app.treatLikeActivity = false;
18124 app.hasAboveClient = false;
18125 app.hasClientActivities = false;
18127 mServices.killServicesLocked(app, allowRestart);
18129 boolean restart = false;
18131 // Remove published content providers.
18132 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18133 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18134 final boolean always = app.bad || !allowRestart;
18135 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18136 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18137 // We left the provider in the launching list, need to
18142 cpr.provider = null;
18145 app.pubProviders.clear();
18147 // Take care of any launching providers waiting for this process.
18148 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18152 // Unregister from connected content providers.
18153 if (!app.conProviders.isEmpty()) {
18154 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18155 ContentProviderConnection conn = app.conProviders.get(i);
18156 conn.provider.connections.remove(conn);
18157 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18158 conn.provider.name);
18160 app.conProviders.clear();
18163 // At this point there may be remaining entries in mLaunchingProviders
18164 // where we were the only one waiting, so they are no longer of use.
18165 // Look for these and clean up if found.
18166 // XXX Commented out for now. Trying to figure out a way to reproduce
18167 // the actual situation to identify what is actually going on.
18169 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18170 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18171 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18172 synchronized (cpr) {
18173 cpr.launchingApp = null;
18180 skipCurrentReceiverLocked(app);
18182 // Unregister any receivers.
18183 for (int i = app.receivers.size() - 1; i >= 0; i--) {
18184 removeReceiverLocked(app.receivers.valueAt(i));
18186 app.receivers.clear();
18188 // If the app is undergoing backup, tell the backup manager about it
18189 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18190 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18191 + mBackupTarget.appInfo + " died during backup");
18192 mHandler.post(new Runnable() {
18196 IBackupManager bm = IBackupManager.Stub.asInterface(
18197 ServiceManager.getService(Context.BACKUP_SERVICE));
18198 bm.agentDisconnected(app.info.packageName);
18199 } catch (RemoteException e) {
18200 // can't happen; backup manager is local
18206 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18207 ProcessChangeItem item = mPendingProcessChanges.get(i);
18208 if (item.pid == app.pid) {
18209 mPendingProcessChanges.remove(i);
18210 mAvailProcessChanges.add(item);
18213 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18214 null).sendToTarget();
18216 // If the caller is restarting this app, then leave it in its
18217 // current lists and let the caller take care of it.
18222 if (!app.persistent || app.isolated) {
18223 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18224 "Removing non-persistent process during cleanup: " + app);
18225 if (!replacingPid) {
18226 removeProcessNameLocked(app.processName, app.uid, app);
18228 if (mHeavyWeightProcess == app) {
18229 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18230 mHeavyWeightProcess.userId, 0));
18231 mHeavyWeightProcess = null;
18233 } else if (!app.removed) {
18234 // This app is persistent, so we need to keep its record around.
18235 // If it is not already on the pending app list, add it there
18236 // and start a new process for it.
18237 if (mPersistentStartingProcesses.indexOf(app) < 0) {
18238 mPersistentStartingProcesses.add(app);
18242 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18243 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18244 mProcessesOnHold.remove(app);
18246 if (app == mHomeProcess) {
18247 mHomeProcess = null;
18249 if (app == mPreviousProcess) {
18250 mPreviousProcess = null;
18253 if (restart && !app.isolated) {
18254 // We have components that still need to be running in the
18255 // process, so re-launch it.
18257 ProcessList.remove(app.pid);
18259 addProcessNameLocked(app);
18260 startProcessLocked(app, "restart", app.processName);
18262 } else if (app.pid > 0 && app.pid != MY_PID) {
18265 synchronized (mPidsSelfLocked) {
18266 mPidsSelfLocked.remove(app.pid);
18267 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18269 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18270 if (app.isolated) {
18271 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18278 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18279 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18280 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18281 if (cpr.launchingApp == app) {
18288 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18289 // Look through the content providers we are waiting to have launched,
18290 // and if any run in this process then either schedule a restart of
18291 // the process or kill the client waiting for it if this process has
18293 boolean restart = false;
18294 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18295 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18296 if (cpr.launchingApp == app) {
18297 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18300 removeDyingProviderLocked(app, cpr, true);
18307 // =========================================================
18309 // =========================================================
18312 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18314 enforceNotIsolatedCaller("getServices");
18316 final int callingUid = Binder.getCallingUid();
18317 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18318 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18319 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18321 synchronized (this) {
18322 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18323 allowed, canInteractAcrossUsers);
18328 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18329 enforceNotIsolatedCaller("getRunningServiceControlPanel");
18330 synchronized (this) {
18331 return mServices.getRunningServiceControlPanelLocked(name);
18336 public ComponentName startService(IApplicationThread caller, Intent service,
18337 String resolvedType, boolean requireForeground, String callingPackage, int userId)
18338 throws TransactionTooLargeException {
18339 enforceNotIsolatedCaller("startService");
18340 // Refuse possible leaked file descriptors
18341 if (service != null && service.hasFileDescriptors() == true) {
18342 throw new IllegalArgumentException("File descriptors passed in Intent");
18345 if (callingPackage == null) {
18346 throw new IllegalArgumentException("callingPackage cannot be null");
18349 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18350 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18351 synchronized(this) {
18352 final int callingPid = Binder.getCallingPid();
18353 final int callingUid = Binder.getCallingUid();
18354 final long origId = Binder.clearCallingIdentity();
18357 res = mServices.startServiceLocked(caller, service,
18358 resolvedType, callingPid, callingUid,
18359 requireForeground, callingPackage, userId);
18361 Binder.restoreCallingIdentity(origId);
18367 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18368 boolean fgRequired, String callingPackage, int userId)
18369 throws TransactionTooLargeException {
18370 synchronized(this) {
18371 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18372 "startServiceInPackage: " + service + " type=" + resolvedType);
18373 final long origId = Binder.clearCallingIdentity();
18376 res = mServices.startServiceLocked(null, service,
18377 resolvedType, -1, uid, fgRequired, callingPackage, userId);
18379 Binder.restoreCallingIdentity(origId);
18386 public int stopService(IApplicationThread caller, Intent service,
18387 String resolvedType, int userId) {
18388 enforceNotIsolatedCaller("stopService");
18389 // Refuse possible leaked file descriptors
18390 if (service != null && service.hasFileDescriptors() == true) {
18391 throw new IllegalArgumentException("File descriptors passed in Intent");
18394 synchronized(this) {
18395 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18400 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18401 enforceNotIsolatedCaller("peekService");
18402 // Refuse possible leaked file descriptors
18403 if (service != null && service.hasFileDescriptors() == true) {
18404 throw new IllegalArgumentException("File descriptors passed in Intent");
18407 if (callingPackage == null) {
18408 throw new IllegalArgumentException("callingPackage cannot be null");
18411 synchronized(this) {
18412 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18417 public boolean stopServiceToken(ComponentName className, IBinder token,
18419 synchronized(this) {
18420 return mServices.stopServiceTokenLocked(className, token, startId);
18425 public void setServiceForeground(ComponentName className, IBinder token,
18426 int id, Notification notification, int flags) {
18427 synchronized(this) {
18428 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18433 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18434 boolean requireFull, String name, String callerPackage) {
18435 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18436 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18439 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18440 String className, int flags) {
18441 boolean result = false;
18442 // For apps that don't have pre-defined UIDs, check for permission
18443 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18444 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18445 if (ActivityManager.checkUidPermission(
18446 INTERACT_ACROSS_USERS,
18447 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18448 ComponentName comp = new ComponentName(aInfo.packageName, className);
18449 String msg = "Permission Denial: Component " + comp.flattenToShortString()
18450 + " requests FLAG_SINGLE_USER, but app does not hold "
18451 + INTERACT_ACROSS_USERS;
18453 throw new SecurityException(msg);
18455 // Permission passed
18458 } else if ("system".equals(componentProcessName)) {
18460 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18461 // Phone app and persistent apps are allowed to export singleuser providers.
18462 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18463 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18465 if (DEBUG_MU) Slog.v(TAG_MU,
18466 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18467 + Integer.toHexString(flags) + ") = " + result);
18472 * Checks to see if the caller is in the same app as the singleton
18473 * component, or the component is in a special app. It allows special apps
18474 * to export singleton components but prevents exporting singleton
18475 * components for regular apps.
18477 boolean isValidSingletonCall(int callingUid, int componentUid) {
18478 int componentAppId = UserHandle.getAppId(componentUid);
18479 return UserHandle.isSameApp(callingUid, componentUid)
18480 || componentAppId == SYSTEM_UID
18481 || componentAppId == PHONE_UID
18482 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18483 == PackageManager.PERMISSION_GRANTED;
18486 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18487 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18488 int userId) throws TransactionTooLargeException {
18489 enforceNotIsolatedCaller("bindService");
18491 // Refuse possible leaked file descriptors
18492 if (service != null && service.hasFileDescriptors() == true) {
18493 throw new IllegalArgumentException("File descriptors passed in Intent");
18496 if (callingPackage == null) {
18497 throw new IllegalArgumentException("callingPackage cannot be null");
18500 synchronized(this) {
18501 return mServices.bindServiceLocked(caller, token, service,
18502 resolvedType, connection, flags, callingPackage, userId);
18506 public boolean unbindService(IServiceConnection connection) {
18507 synchronized (this) {
18508 return mServices.unbindServiceLocked(connection);
18512 public void publishService(IBinder token, Intent intent, IBinder service) {
18513 // Refuse possible leaked file descriptors
18514 if (intent != null && intent.hasFileDescriptors() == true) {
18515 throw new IllegalArgumentException("File descriptors passed in Intent");
18518 synchronized(this) {
18519 if (!(token instanceof ServiceRecord)) {
18520 throw new IllegalArgumentException("Invalid service token");
18522 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18526 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18527 // Refuse possible leaked file descriptors
18528 if (intent != null && intent.hasFileDescriptors() == true) {
18529 throw new IllegalArgumentException("File descriptors passed in Intent");
18532 synchronized(this) {
18533 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18537 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18538 synchronized(this) {
18539 if (!(token instanceof ServiceRecord)) {
18540 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18541 throw new IllegalArgumentException("Invalid service token");
18543 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18547 // =========================================================
18548 // BACKUP AND RESTORE
18549 // =========================================================
18551 // Cause the target app to be launched if necessary and its backup agent
18552 // instantiated. The backup agent will invoke backupAgentCreated() on the
18553 // activity manager to announce its creation.
18554 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18555 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18556 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18558 IPackageManager pm = AppGlobals.getPackageManager();
18559 ApplicationInfo app = null;
18561 app = pm.getApplicationInfo(packageName, 0, userId);
18562 } catch (RemoteException e) {
18563 // can't happen; package manager is process-local
18566 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18573 synchronized(this) {
18574 // !!! TODO: currently no check here that we're already bound
18575 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18576 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18577 synchronized (stats) {
18578 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18581 // Backup agent is now in use, its package can't be stopped.
18583 AppGlobals.getPackageManager().setPackageStoppedState(
18584 app.packageName, false, UserHandle.getUserId(app.uid));
18585 } catch (RemoteException e) {
18586 } catch (IllegalArgumentException e) {
18587 Slog.w(TAG, "Failed trying to unstop package "
18588 + app.packageName + ": " + e);
18591 BackupRecord r = new BackupRecord(ss, app, backupMode);
18592 ComponentName hostingName =
18593 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18594 ? new ComponentName(app.packageName, app.backupAgentName)
18595 : new ComponentName("android", "FullBackupAgent");
18596 // startProcessLocked() returns existing proc's record if it's already running
18597 ProcessRecord proc = startProcessLocked(app.processName, app,
18598 false, 0, "backup", hostingName, false, false, false);
18599 if (proc == null) {
18600 Slog.e(TAG, "Unable to start backup agent process " + r);
18604 // If the app is a regular app (uid >= 10000) and not the system server or phone
18605 // process, etc, then mark it as being in full backup so that certain calls to the
18606 // process can be blocked. This is not reset to false anywhere because we kill the
18607 // process after the full backup is done and the ProcessRecord will vaporize anyway.
18608 if (UserHandle.isApp(app.uid) &&
18609 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18610 proc.inFullBackup = true;
18613 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18614 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18616 mBackupAppName = app.packageName;
18618 // Try not to kill the process during backup
18619 updateOomAdjLocked(proc, true);
18621 // If the process is already attached, schedule the creation of the backup agent now.
18622 // If it is not yet live, this will be done when it attaches to the framework.
18623 if (proc.thread != null) {
18624 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18626 proc.thread.scheduleCreateBackupAgent(app,
18627 compatibilityInfoForPackageLocked(app), backupMode);
18628 } catch (RemoteException e) {
18629 // Will time out on the backup manager side
18632 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18634 // Invariants: at this point, the target app process exists and the application
18635 // is either already running or in the process of coming up. mBackupTarget and
18636 // mBackupAppName describe the app, so that when it binds back to the AM we
18637 // know that it's scheduled for a backup-agent operation.
18640 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18641 if (oldBackupUid != -1) {
18642 js.removeBackingUpUid(oldBackupUid);
18644 if (newBackupUid != -1) {
18645 js.addBackingUpUid(newBackupUid);
18652 public void clearPendingBackup() {
18653 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18654 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18656 synchronized (this) {
18657 mBackupTarget = null;
18658 mBackupAppName = null;
18661 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18662 js.clearAllBackingUpUids();
18665 // A backup agent has just come up
18666 public void backupAgentCreated(String agentPackageName, IBinder agent) {
18667 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18670 synchronized(this) {
18671 if (!agentPackageName.equals(mBackupAppName)) {
18672 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18677 long oldIdent = Binder.clearCallingIdentity();
18679 IBackupManager bm = IBackupManager.Stub.asInterface(
18680 ServiceManager.getService(Context.BACKUP_SERVICE));
18681 bm.agentConnected(agentPackageName, agent);
18682 } catch (RemoteException e) {
18683 // can't happen; the backup manager service is local
18684 } catch (Exception e) {
18685 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18686 e.printStackTrace();
18688 Binder.restoreCallingIdentity(oldIdent);
18692 // done with this agent
18693 public void unbindBackupAgent(ApplicationInfo appInfo) {
18694 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18695 if (appInfo == null) {
18696 Slog.w(TAG, "unbind backup agent for null app");
18702 synchronized(this) {
18704 if (mBackupAppName == null) {
18705 Slog.w(TAG, "Unbinding backup agent with no active backup");
18709 if (!mBackupAppName.equals(appInfo.packageName)) {
18710 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18714 // Not backing this app up any more; reset its OOM adjustment
18715 final ProcessRecord proc = mBackupTarget.app;
18716 updateOomAdjLocked(proc, true);
18717 proc.inFullBackup = false;
18719 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18721 // If the app crashed during backup, 'thread' will be null here
18722 if (proc.thread != null) {
18724 proc.thread.scheduleDestroyBackupAgent(appInfo,
18725 compatibilityInfoForPackageLocked(appInfo));
18726 } catch (Exception e) {
18727 Slog.e(TAG, "Exception when unbinding backup agent:");
18728 e.printStackTrace();
18732 mBackupTarget = null;
18733 mBackupAppName = null;
18737 if (oldBackupUid != -1) {
18738 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18739 js.removeBackingUpUid(oldBackupUid);
18743 // =========================================================
18745 // =========================================================
18747 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18748 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18751 // Easy case -- we have the app's ProcessRecord.
18752 if (record != null) {
18753 return record.info.isInstantApp();
18755 // Otherwise check with PackageManager.
18756 if (callerPackage == null) {
18757 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18758 throw new IllegalArgumentException("Calling application did not provide package name");
18760 mAppOpsService.checkPackage(uid, callerPackage);
18762 IPackageManager pm = AppGlobals.getPackageManager();
18763 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18764 } catch (RemoteException e) {
18765 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18770 boolean isPendingBroadcastProcessLocked(int pid) {
18771 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18772 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18775 void skipPendingBroadcastLocked(int pid) {
18776 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18777 for (BroadcastQueue queue : mBroadcastQueues) {
18778 queue.skipPendingBroadcastLocked(pid);
18782 // The app just attached; send any pending broadcasts that it should receive
18783 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18784 boolean didSomething = false;
18785 for (BroadcastQueue queue : mBroadcastQueues) {
18786 didSomething |= queue.sendPendingBroadcastsLocked(app);
18788 return didSomething;
18791 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18792 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18794 enforceNotIsolatedCaller("registerReceiver");
18795 ArrayList<Intent> stickyIntents = null;
18796 ProcessRecord callerApp = null;
18797 final boolean visibleToInstantApps
18798 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18801 boolean instantApp;
18802 synchronized(this) {
18803 if (caller != null) {
18804 callerApp = getRecordForAppLocked(caller);
18805 if (callerApp == null) {
18806 throw new SecurityException(
18807 "Unable to find app for caller " + caller
18808 + " (pid=" + Binder.getCallingPid()
18809 + ") when registering receiver " + receiver);
18811 if (callerApp.info.uid != SYSTEM_UID &&
18812 !callerApp.pkgList.containsKey(callerPackage) &&
18813 !"android".equals(callerPackage)) {
18814 throw new SecurityException("Given caller package " + callerPackage
18815 + " is not running in process " + callerApp);
18817 callingUid = callerApp.info.uid;
18818 callingPid = callerApp.pid;
18820 callerPackage = null;
18821 callingUid = Binder.getCallingUid();
18822 callingPid = Binder.getCallingPid();
18825 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18826 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18827 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18829 Iterator<String> actions = filter.actionsIterator();
18830 if (actions == null) {
18831 ArrayList<String> noAction = new ArrayList<String>(1);
18832 noAction.add(null);
18833 actions = noAction.iterator();
18836 // Collect stickies of users
18837 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18838 while (actions.hasNext()) {
18839 String action = actions.next();
18840 for (int id : userIds) {
18841 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18842 if (stickies != null) {
18843 ArrayList<Intent> intents = stickies.get(action);
18844 if (intents != null) {
18845 if (stickyIntents == null) {
18846 stickyIntents = new ArrayList<Intent>();
18848 stickyIntents.addAll(intents);
18855 ArrayList<Intent> allSticky = null;
18856 if (stickyIntents != null) {
18857 final ContentResolver resolver = mContext.getContentResolver();
18858 // Look for any matching sticky broadcasts...
18859 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18860 Intent intent = stickyIntents.get(i);
18861 // Don't provided intents that aren't available to instant apps.
18863 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18866 // If intent has scheme "content", it will need to acccess
18867 // provider that needs to lock mProviderMap in ActivityThread
18868 // and also it may need to wait application response, so we
18869 // cannot lock ActivityManagerService here.
18870 if (filter.match(resolver, intent, true, TAG) >= 0) {
18871 if (allSticky == null) {
18872 allSticky = new ArrayList<Intent>();
18874 allSticky.add(intent);
18879 // The first sticky in the list is returned directly back to the client.
18880 Intent sticky = allSticky != null ? allSticky.get(0) : null;
18881 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18882 if (receiver == null) {
18886 synchronized (this) {
18887 if (callerApp != null && (callerApp.thread == null
18888 || callerApp.thread.asBinder() != caller.asBinder())) {
18889 // Original caller already died
18892 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18894 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18896 if (rl.app != null) {
18897 rl.app.receivers.add(rl);
18900 receiver.asBinder().linkToDeath(rl, 0);
18901 } catch (RemoteException e) {
18904 rl.linkedToDeath = true;
18906 mRegisteredReceivers.put(receiver.asBinder(), rl);
18907 } else if (rl.uid != callingUid) {
18908 throw new IllegalArgumentException(
18909 "Receiver requested to register for uid " + callingUid
18910 + " was previously registered for uid " + rl.uid
18911 + " callerPackage is " + callerPackage);
18912 } else if (rl.pid != callingPid) {
18913 throw new IllegalArgumentException(
18914 "Receiver requested to register for pid " + callingPid
18915 + " was previously registered for pid " + rl.pid
18916 + " callerPackage is " + callerPackage);
18917 } else if (rl.userId != userId) {
18918 throw new IllegalArgumentException(
18919 "Receiver requested to register for user " + userId
18920 + " was previously registered for user " + rl.userId
18921 + " callerPackage is " + callerPackage);
18923 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18924 permission, callingUid, userId, instantApp, visibleToInstantApps);
18926 if (!bf.debugCheck()) {
18927 Slog.w(TAG, "==> For Dynamic broadcast");
18929 mReceiverResolver.addFilter(bf);
18931 // Enqueue broadcasts for all existing stickies that match
18933 if (allSticky != null) {
18934 ArrayList receivers = new ArrayList();
18937 final int stickyCount = allSticky.size();
18938 for (int i = 0; i < stickyCount; i++) {
18939 Intent intent = allSticky.get(i);
18940 BroadcastQueue queue = broadcastQueueForIntent(intent);
18941 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18942 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18943 null, 0, null, null, false, true, true, -1);
18944 queue.enqueueParallelBroadcastLocked(r);
18945 queue.scheduleBroadcastsLocked();
18953 public void unregisterReceiver(IIntentReceiver receiver) {
18954 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18956 final long origId = Binder.clearCallingIdentity();
18958 boolean doTrim = false;
18960 synchronized(this) {
18961 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18963 final BroadcastRecord r = rl.curBroadcast;
18964 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18965 final boolean doNext = r.queue.finishReceiverLocked(
18966 r, r.resultCode, r.resultData, r.resultExtras,
18967 r.resultAbort, false);
18970 r.queue.processNextBroadcast(false);
18974 if (rl.app != null) {
18975 rl.app.receivers.remove(rl);
18977 removeReceiverLocked(rl);
18978 if (rl.linkedToDeath) {
18979 rl.linkedToDeath = false;
18980 rl.receiver.asBinder().unlinkToDeath(rl, 0);
18985 // If we actually concluded any broadcasts, we might now be able
18986 // to trim the recipients' apps from our working set
18988 trimApplications();
18993 Binder.restoreCallingIdentity(origId);
18997 void removeReceiverLocked(ReceiverList rl) {
18998 mRegisteredReceivers.remove(rl.receiver.asBinder());
18999 for (int i = rl.size() - 1; i >= 0; i--) {
19000 mReceiverResolver.removeFilter(rl.get(i));
19004 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
19005 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19006 ProcessRecord r = mLruProcesses.get(i);
19007 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
19009 r.thread.dispatchPackageBroadcast(cmd, packages);
19010 } catch (RemoteException ex) {
19016 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
19017 int callingUid, int[] users) {
19018 // TODO: come back and remove this assumption to triage all broadcasts
19019 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
19021 List<ResolveInfo> receivers = null;
19023 HashSet<ComponentName> singleUserReceivers = null;
19024 boolean scannedFirstReceivers = false;
19025 for (int user : users) {
19026 // Skip users that have Shell restrictions, with exception of always permitted
19027 // Shell broadcasts
19028 if (callingUid == SHELL_UID
19029 && mUserController.hasUserRestriction(
19030 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
19031 && !isPermittedShellBroadcast(intent)) {
19034 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
19035 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
19036 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
19037 // If this is not the system user, we need to check for
19038 // any receivers that should be filtered out.
19039 for (int i=0; i<newReceivers.size(); i++) {
19040 ResolveInfo ri = newReceivers.get(i);
19041 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
19042 newReceivers.remove(i);
19047 if (newReceivers != null && newReceivers.size() == 0) {
19048 newReceivers = null;
19050 if (receivers == null) {
19051 receivers = newReceivers;
19052 } else if (newReceivers != null) {
19053 // We need to concatenate the additional receivers
19054 // found with what we have do far. This would be easy,
19055 // but we also need to de-dup any receivers that are
19057 if (!scannedFirstReceivers) {
19058 // Collect any single user receivers we had already retrieved.
19059 scannedFirstReceivers = true;
19060 for (int i=0; i<receivers.size(); i++) {
19061 ResolveInfo ri = receivers.get(i);
19062 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19063 ComponentName cn = new ComponentName(
19064 ri.activityInfo.packageName, ri.activityInfo.name);
19065 if (singleUserReceivers == null) {
19066 singleUserReceivers = new HashSet<ComponentName>();
19068 singleUserReceivers.add(cn);
19072 // Add the new results to the existing results, tracking
19073 // and de-dupping single user receivers.
19074 for (int i=0; i<newReceivers.size(); i++) {
19075 ResolveInfo ri = newReceivers.get(i);
19076 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19077 ComponentName cn = new ComponentName(
19078 ri.activityInfo.packageName, ri.activityInfo.name);
19079 if (singleUserReceivers == null) {
19080 singleUserReceivers = new HashSet<ComponentName>();
19082 if (!singleUserReceivers.contains(cn)) {
19083 singleUserReceivers.add(cn);
19092 } catch (RemoteException ex) {
19093 // pm is in same process, this will never happen.
19098 private boolean isPermittedShellBroadcast(Intent intent) {
19099 // remote bugreport should always be allowed to be taken
19100 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19103 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19104 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19105 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19106 // Don't yell about broadcasts sent via shell
19110 final String action = intent.getAction();
19111 if (isProtectedBroadcast
19112 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19113 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19114 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19115 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19116 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19117 || Intent.ACTION_MASTER_CLEAR.equals(action)
19118 || Intent.ACTION_FACTORY_RESET.equals(action)
19119 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19120 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19121 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19122 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19123 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19124 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19125 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19126 // Broadcast is either protected, or it's a public action that
19127 // we've relaxed, so it's fine for system internals to send.
19131 // This broadcast may be a problem... but there are often system components that
19132 // want to send an internal broadcast to themselves, which is annoying to have to
19133 // explicitly list each action as a protected broadcast, so we will check for that
19134 // one safe case and allow it: an explicit broadcast, only being received by something
19135 // that has protected itself.
19136 if (receivers != null && receivers.size() > 0
19137 && (intent.getPackage() != null || intent.getComponent() != null)) {
19138 boolean allProtected = true;
19139 for (int i = receivers.size()-1; i >= 0; i--) {
19140 Object target = receivers.get(i);
19141 if (target instanceof ResolveInfo) {
19142 ResolveInfo ri = (ResolveInfo)target;
19143 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19144 allProtected = false;
19148 BroadcastFilter bf = (BroadcastFilter)target;
19149 if (bf.requiredPermission == null) {
19150 allProtected = false;
19155 if (allProtected) {
19161 // The vast majority of broadcasts sent from system internals
19162 // should be protected to avoid security holes, so yell loudly
19163 // to ensure we examine these cases.
19164 if (callerApp != null) {
19165 Log.wtf(TAG, "Sending non-protected broadcast " + action
19166 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19169 Log.wtf(TAG, "Sending non-protected broadcast " + action
19170 + " from system uid " + UserHandle.formatUid(callingUid)
19171 + " pkg " + callerPackage,
19176 final int broadcastIntentLocked(ProcessRecord callerApp,
19177 String callerPackage, Intent intent, String resolvedType,
19178 IIntentReceiver resultTo, int resultCode, String resultData,
19179 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19180 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19181 intent = new Intent(intent);
19183 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19184 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19185 if (callerInstantApp) {
19186 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19189 // By default broadcasts do not go to stopped apps.
19190 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19192 // If we have not finished booting, don't allow this to launch new processes.
19193 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19194 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19197 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19198 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19199 + " ordered=" + ordered + " userid=" + userId);
19200 if ((resultTo != null) && !ordered) {
19201 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19204 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19205 ALLOW_NON_FULL, "broadcast", callerPackage);
19207 // Make sure that the user who is receiving this broadcast is running.
19208 // If not, we will just skip it. Make an exception for shutdown broadcasts
19209 // and upgrade steps.
19211 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19212 if ((callingUid != SYSTEM_UID
19213 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19214 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19215 Slog.w(TAG, "Skipping broadcast of " + intent
19216 + ": user " + userId + " is stopped");
19217 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19221 BroadcastOptions brOptions = null;
19222 if (bOptions != null) {
19223 brOptions = new BroadcastOptions(bOptions);
19224 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19225 // See if the caller is allowed to do this. Note we are checking against
19226 // the actual real caller (not whoever provided the operation as say a
19227 // PendingIntent), because that who is actually supplied the arguments.
19228 if (checkComponentPermission(
19229 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19230 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19231 != PackageManager.PERMISSION_GRANTED) {
19232 String msg = "Permission Denial: " + intent.getAction()
19233 + " broadcast from " + callerPackage + " (pid=" + callingPid
19234 + ", uid=" + callingUid + ")"
19236 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19238 throw new SecurityException(msg);
19243 // Verify that protected broadcasts are only being sent by system code,
19244 // and that system code is only sending protected broadcasts.
19245 final String action = intent.getAction();
19246 final boolean isProtectedBroadcast;
19248 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19249 } catch (RemoteException e) {
19250 Slog.w(TAG, "Remote exception", e);
19251 return ActivityManager.BROADCAST_SUCCESS;
19254 final boolean isCallerSystem;
19255 switch (UserHandle.getAppId(callingUid)) {
19259 case BLUETOOTH_UID:
19261 isCallerSystem = true;
19264 isCallerSystem = (callerApp != null) && callerApp.persistent;
19268 // First line security check before anything else: stop non-system apps from
19269 // sending protected broadcasts.
19270 if (!isCallerSystem) {
19271 if (isProtectedBroadcast) {
19272 String msg = "Permission Denial: not allowed to send broadcast "
19273 + action + " from pid="
19274 + callingPid + ", uid=" + callingUid;
19276 throw new SecurityException(msg);
19278 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19279 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19280 // Special case for compatibility: we don't want apps to send this,
19281 // but historically it has not been protected and apps may be using it
19282 // to poke their own app widget. So, instead of making it protected,
19283 // just limit it to the caller.
19284 if (callerPackage == null) {
19285 String msg = "Permission Denial: not allowed to send broadcast "
19286 + action + " from unknown caller.";
19288 throw new SecurityException(msg);
19289 } else if (intent.getComponent() != null) {
19290 // They are good enough to send to an explicit component... verify
19291 // it is being sent to the calling app.
19292 if (!intent.getComponent().getPackageName().equals(
19294 String msg = "Permission Denial: not allowed to send broadcast "
19296 + intent.getComponent().getPackageName() + " from "
19299 throw new SecurityException(msg);
19302 // Limit broadcast to their own package.
19303 intent.setPackage(callerPackage);
19308 if (action != null) {
19309 if (getBackgroundLaunchBroadcasts().contains(action)) {
19310 if (DEBUG_BACKGROUND_CHECK) {
19311 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19313 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19317 case Intent.ACTION_UID_REMOVED:
19318 case Intent.ACTION_PACKAGE_REMOVED:
19319 case Intent.ACTION_PACKAGE_CHANGED:
19320 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19321 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19322 case Intent.ACTION_PACKAGES_SUSPENDED:
19323 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19324 // Handle special intents: if this broadcast is from the package
19325 // manager about a package being removed, we need to remove all of
19326 // its activities from the history stack.
19327 if (checkComponentPermission(
19328 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19329 callingPid, callingUid, -1, true)
19330 != PackageManager.PERMISSION_GRANTED) {
19331 String msg = "Permission Denial: " + intent.getAction()
19332 + " broadcast from " + callerPackage + " (pid=" + callingPid
19333 + ", uid=" + callingUid + ")"
19335 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19337 throw new SecurityException(msg);
19340 case Intent.ACTION_UID_REMOVED:
19341 final int uid = getUidFromIntent(intent);
19343 mBatteryStatsService.removeUid(uid);
19344 mAppOpsService.uidRemoved(uid);
19347 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19348 // If resources are unavailable just force stop all those packages
19349 // and flush the attribute cache as well.
19351 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19352 if (list != null && list.length > 0) {
19353 for (int i = 0; i < list.length; i++) {
19354 forceStopPackageLocked(list[i], -1, false, true, true,
19355 false, false, userId, "storage unmount");
19357 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19358 sendPackageBroadcastLocked(
19359 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19363 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19364 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19366 case Intent.ACTION_PACKAGE_REMOVED:
19367 case Intent.ACTION_PACKAGE_CHANGED:
19368 Uri data = intent.getData();
19370 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19371 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19372 final boolean replacing =
19373 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19374 final boolean killProcess =
19375 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19376 final boolean fullUninstall = removed && !replacing;
19379 forceStopPackageLocked(ssp, UserHandle.getAppId(
19380 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19381 false, true, true, false, fullUninstall, userId,
19382 removed ? "pkg removed" : "pkg changed");
19384 final int cmd = killProcess
19385 ? ApplicationThreadConstants.PACKAGE_REMOVED
19386 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19387 sendPackageBroadcastLocked(cmd,
19388 new String[] {ssp}, userId);
19389 if (fullUninstall) {
19390 mAppOpsService.packageRemoved(
19391 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19393 // Remove all permissions granted from/to this package
19394 removeUriPermissionsForPackageLocked(ssp, userId, true);
19396 removeTasksByPackageNameLocked(ssp, userId);
19398 mServices.forceStopPackageLocked(ssp, userId);
19400 // Hide the "unsupported display" dialog if necessary.
19401 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19402 mUnsupportedDisplaySizeDialog.getPackageName())) {
19403 mUnsupportedDisplaySizeDialog.dismiss();
19404 mUnsupportedDisplaySizeDialog = null;
19406 mCompatModePackages.handlePackageUninstalledLocked(ssp);
19407 mBatteryStatsService.notePackageUninstalled(ssp);
19411 killPackageProcessesLocked(ssp, UserHandle.getAppId(
19412 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19413 userId, ProcessList.INVALID_ADJ,
19414 false, true, true, false, "change " + ssp);
19416 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19417 intent.getStringArrayExtra(
19418 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19422 case Intent.ACTION_PACKAGES_SUSPENDED:
19423 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19424 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19425 intent.getAction());
19426 final String[] packageNames = intent.getStringArrayExtra(
19427 Intent.EXTRA_CHANGED_PACKAGE_LIST);
19428 final int userHandle = intent.getIntExtra(
19429 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19431 synchronized(ActivityManagerService.this) {
19432 mRecentTasks.onPackagesSuspendedChanged(
19433 packageNames, suspended, userHandle);
19438 case Intent.ACTION_PACKAGE_REPLACED:
19440 final Uri data = intent.getData();
19442 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19443 ApplicationInfo aInfo = null;
19445 aInfo = AppGlobals.getPackageManager()
19446 .getApplicationInfo(ssp, 0 /*flags*/, userId);
19447 } catch (RemoteException ignore) {}
19448 if (aInfo == null) {
19449 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19450 + " ssp=" + ssp + " data=" + data);
19451 return ActivityManager.BROADCAST_SUCCESS;
19453 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19454 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19455 new String[] {ssp}, userId);
19459 case Intent.ACTION_PACKAGE_ADDED:
19461 // Special case for adding a package: by default turn on compatibility mode.
19462 Uri data = intent.getData();
19464 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19465 final boolean replacing =
19466 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19467 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19470 ApplicationInfo ai = AppGlobals.getPackageManager().
19471 getApplicationInfo(ssp, 0, 0);
19472 mBatteryStatsService.notePackageInstalled(ssp,
19473 ai != null ? ai.versionCode : 0);
19474 } catch (RemoteException e) {
19479 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19481 Uri data = intent.getData();
19483 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19484 // Hide the "unsupported display" dialog if necessary.
19485 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19486 mUnsupportedDisplaySizeDialog.getPackageName())) {
19487 mUnsupportedDisplaySizeDialog.dismiss();
19488 mUnsupportedDisplaySizeDialog = null;
19490 mCompatModePackages.handlePackageDataClearedLocked(ssp);
19494 case Intent.ACTION_TIMEZONE_CHANGED:
19495 // If this is the time zone changed action, queue up a message that will reset
19496 // the timezone of all currently running processes. This message will get
19497 // queued up before the broadcast happens.
19498 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19500 case Intent.ACTION_TIME_CHANGED:
19501 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19502 // the tri-state value it may contain and "unknown".
19503 // For convenience we re-use the Intent extra values.
19504 final int NO_EXTRA_VALUE_FOUND = -1;
19505 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19506 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19507 NO_EXTRA_VALUE_FOUND /* defaultValue */);
19508 // Only send a message if the time preference is available.
19509 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19510 Message updateTimePreferenceMsg =
19511 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19512 timeFormatPreferenceMsgValue, 0);
19513 mHandler.sendMessage(updateTimePreferenceMsg);
19515 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19516 synchronized (stats) {
19517 stats.noteCurrentTimeChangedLocked();
19520 case Intent.ACTION_CLEAR_DNS_CACHE:
19521 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19523 case Proxy.PROXY_CHANGE_ACTION:
19524 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19525 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19527 case android.hardware.Camera.ACTION_NEW_PICTURE:
19528 case android.hardware.Camera.ACTION_NEW_VIDEO:
19529 // In N we just turned these off; in O we are turing them back on partly,
19530 // only for registered receivers. This will still address the main problem
19531 // (a spam of apps waking up when a picture is taken putting significant
19532 // memory pressure on the system at a bad point), while still allowing apps
19533 // that are already actively running to know about this happening.
19534 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19536 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19537 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19539 case "com.android.launcher.action.INSTALL_SHORTCUT":
19540 // As of O, we no longer support this broadcasts, even for pre-O apps.
19541 // Apps should now be using ShortcutManager.pinRequestShortcut().
19542 Log.w(TAG, "Broadcast " + action
19543 + " no longer supported. It will not be delivered.");
19544 return ActivityManager.BROADCAST_SUCCESS;
19547 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19548 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19549 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19550 final int uid = getUidFromIntent(intent);
19552 final UidRecord uidRec = mActiveUids.get(uid);
19553 if (uidRec != null) {
19554 uidRec.updateHasInternetPermission();
19560 // Add to the sticky list if requested.
19562 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19563 callingPid, callingUid)
19564 != PackageManager.PERMISSION_GRANTED) {
19565 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19566 + callingPid + ", uid=" + callingUid
19567 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19569 throw new SecurityException(msg);
19571 if (requiredPermissions != null && requiredPermissions.length > 0) {
19572 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19573 + " and enforce permissions " + Arrays.toString(requiredPermissions));
19574 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19576 if (intent.getComponent() != null) {
19577 throw new SecurityException(
19578 "Sticky broadcasts can't target a specific component");
19580 // We use userId directly here, since the "all" target is maintained
19581 // as a separate set of sticky broadcasts.
19582 if (userId != UserHandle.USER_ALL) {
19583 // But first, if this is not a broadcast to all users, then
19584 // make sure it doesn't conflict with an existing broadcast to
19586 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19587 UserHandle.USER_ALL);
19588 if (stickies != null) {
19589 ArrayList<Intent> list = stickies.get(intent.getAction());
19590 if (list != null) {
19591 int N = list.size();
19593 for (i=0; i<N; i++) {
19594 if (intent.filterEquals(list.get(i))) {
19595 throw new IllegalArgumentException(
19596 "Sticky broadcast " + intent + " for user "
19597 + userId + " conflicts with existing global broadcast");
19603 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19604 if (stickies == null) {
19605 stickies = new ArrayMap<>();
19606 mStickyBroadcasts.put(userId, stickies);
19608 ArrayList<Intent> list = stickies.get(intent.getAction());
19609 if (list == null) {
19610 list = new ArrayList<>();
19611 stickies.put(intent.getAction(), list);
19613 final int stickiesCount = list.size();
19615 for (i = 0; i < stickiesCount; i++) {
19616 if (intent.filterEquals(list.get(i))) {
19617 // This sticky already exists, replace it.
19618 list.set(i, new Intent(intent));
19622 if (i >= stickiesCount) {
19623 list.add(new Intent(intent));
19628 if (userId == UserHandle.USER_ALL) {
19629 // Caller wants broadcast to go to all started users.
19630 users = mUserController.getStartedUserArrayLocked();
19632 // Caller wants broadcast to go to one specific user.
19633 users = new int[] {userId};
19636 // Figure out who all will receive this broadcast.
19637 List receivers = null;
19638 List<BroadcastFilter> registeredReceivers = null;
19639 // Need to resolve the intent to interested receivers...
19640 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19642 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19644 if (intent.getComponent() == null) {
19645 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19646 // Query one target user at a time, excluding shell-restricted users
19647 for (int i = 0; i < users.length; i++) {
19648 if (mUserController.hasUserRestriction(
19649 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19652 List<BroadcastFilter> registeredReceiversForUser =
19653 mReceiverResolver.queryIntent(intent,
19654 resolvedType, false /*defaultOnly*/, users[i]);
19655 if (registeredReceivers == null) {
19656 registeredReceivers = registeredReceiversForUser;
19657 } else if (registeredReceiversForUser != null) {
19658 registeredReceivers.addAll(registeredReceiversForUser);
19662 registeredReceivers = mReceiverResolver.queryIntent(intent,
19663 resolvedType, false /*defaultOnly*/, userId);
19667 final boolean replacePending =
19668 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19670 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19671 + " replacePending=" + replacePending);
19673 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19674 if (!ordered && NR > 0) {
19675 // If we are not serializing this broadcast, then send the
19676 // registered receivers separately so they don't wait for the
19677 // components to be launched.
19678 if (isCallerSystem) {
19679 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19680 isProtectedBroadcast, registeredReceivers);
19682 final BroadcastQueue queue = broadcastQueueForIntent(intent);
19683 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19684 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19685 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19686 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19687 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19688 final boolean replaced = replacePending
19689 && (queue.replaceParallelBroadcastLocked(r) != null);
19690 // Note: We assume resultTo is null for non-ordered broadcasts.
19692 queue.enqueueParallelBroadcastLocked(r);
19693 queue.scheduleBroadcastsLocked();
19695 registeredReceivers = null;
19699 // Merge into one list.
19701 if (receivers != null) {
19702 // A special case for PACKAGE_ADDED: do not allow the package
19703 // being added to see this broadcast. This prevents them from
19704 // using this as a back door to get run as soon as they are
19705 // installed. Maybe in the future we want to have a special install
19706 // broadcast or such for apps, but we'd like to deliberately make
19708 String skipPackages[] = null;
19709 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19710 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19711 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19712 Uri data = intent.getData();
19713 if (data != null) {
19714 String pkgName = data.getSchemeSpecificPart();
19715 if (pkgName != null) {
19716 skipPackages = new String[] { pkgName };
19719 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19720 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19722 if (skipPackages != null && (skipPackages.length > 0)) {
19723 for (String skipPackage : skipPackages) {
19724 if (skipPackage != null) {
19725 int NT = receivers.size();
19726 for (int it=0; it<NT; it++) {
19727 ResolveInfo curt = (ResolveInfo)receivers.get(it);
19728 if (curt.activityInfo.packageName.equals(skipPackage)) {
19729 receivers.remove(it);
19738 int NT = receivers != null ? receivers.size() : 0;
19740 ResolveInfo curt = null;
19741 BroadcastFilter curr = null;
19742 while (it < NT && ir < NR) {
19743 if (curt == null) {
19744 curt = (ResolveInfo)receivers.get(it);
19746 if (curr == null) {
19747 curr = registeredReceivers.get(ir);
19749 if (curr.getPriority() >= curt.priority) {
19750 // Insert this broadcast record into the final list.
19751 receivers.add(it, curr);
19757 // Skip to the next ResolveInfo in the final list.
19764 if (receivers == null) {
19765 receivers = new ArrayList();
19767 receivers.add(registeredReceivers.get(ir));
19771 if (isCallerSystem) {
19772 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19773 isProtectedBroadcast, receivers);
19776 if ((receivers != null && receivers.size() > 0)
19777 || resultTo != null) {
19778 BroadcastQueue queue = broadcastQueueForIntent(intent);
19779 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19780 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19781 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19782 resultData, resultExtras, ordered, sticky, false, userId);
19784 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19785 + ": prev had " + queue.mOrderedBroadcasts.size());
19786 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19787 "Enqueueing broadcast " + r.intent.getAction());
19789 final BroadcastRecord oldRecord =
19790 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19791 if (oldRecord != null) {
19792 // Replaced, fire the result-to receiver.
19793 if (oldRecord.resultTo != null) {
19794 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19796 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19798 Activity.RESULT_CANCELED, null, null,
19799 false, false, oldRecord.userId);
19800 } catch (RemoteException e) {
19801 Slog.w(TAG, "Failure ["
19802 + queue.mQueueName + "] sending broadcast result of "
19808 queue.enqueueOrderedBroadcastLocked(r);
19809 queue.scheduleBroadcastsLocked();
19812 // There was nobody interested in the broadcast, but we still want to record
19813 // that it happened.
19814 if (intent.getComponent() == null && intent.getPackage() == null
19815 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19816 // This was an implicit broadcast... let's record it for posterity.
19817 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19821 return ActivityManager.BROADCAST_SUCCESS;
19825 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19827 private int getUidFromIntent(Intent intent) {
19828 if (intent == null) {
19831 final Bundle intentExtras = intent.getExtras();
19832 return intent.hasExtra(Intent.EXTRA_UID)
19833 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19836 final void rotateBroadcastStatsIfNeededLocked() {
19837 final long now = SystemClock.elapsedRealtime();
19838 if (mCurBroadcastStats == null ||
19839 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19840 mLastBroadcastStats = mCurBroadcastStats;
19841 if (mLastBroadcastStats != null) {
19842 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19843 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19845 mCurBroadcastStats = new BroadcastStats();
19849 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19850 int skipCount, long dispatchTime) {
19851 rotateBroadcastStatsIfNeededLocked();
19852 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19855 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19856 rotateBroadcastStatsIfNeededLocked();
19857 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19860 final Intent verifyBroadcastLocked(Intent intent) {
19861 // Refuse possible leaked file descriptors
19862 if (intent != null && intent.hasFileDescriptors() == true) {
19863 throw new IllegalArgumentException("File descriptors passed in Intent");
19866 int flags = intent.getFlags();
19868 if (!mProcessesReady) {
19869 // if the caller really truly claims to know what they're doing, go
19870 // ahead and allow the broadcast without launching any receivers
19871 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19872 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19873 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19874 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19875 + " before boot completion");
19876 throw new IllegalStateException("Cannot broadcast before boot completed");
19880 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19881 throw new IllegalArgumentException(
19882 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19885 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19886 switch (Binder.getCallingUid()) {
19891 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19892 + Binder.getCallingUid());
19893 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19901 public final int broadcastIntent(IApplicationThread caller,
19902 Intent intent, String resolvedType, IIntentReceiver resultTo,
19903 int resultCode, String resultData, Bundle resultExtras,
19904 String[] requiredPermissions, int appOp, Bundle bOptions,
19905 boolean serialized, boolean sticky, int userId) {
19906 enforceNotIsolatedCaller("broadcastIntent");
19907 synchronized(this) {
19908 intent = verifyBroadcastLocked(intent);
19910 final ProcessRecord callerApp = getRecordForAppLocked(caller);
19911 final int callingPid = Binder.getCallingPid();
19912 final int callingUid = Binder.getCallingUid();
19913 final long origId = Binder.clearCallingIdentity();
19914 int res = broadcastIntentLocked(callerApp,
19915 callerApp != null ? callerApp.info.packageName : null,
19916 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19917 requiredPermissions, appOp, bOptions, serialized, sticky,
19918 callingPid, callingUid, userId);
19919 Binder.restoreCallingIdentity(origId);
19925 int broadcastIntentInPackage(String packageName, int uid,
19926 Intent intent, String resolvedType, IIntentReceiver resultTo,
19927 int resultCode, String resultData, Bundle resultExtras,
19928 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19930 synchronized(this) {
19931 intent = verifyBroadcastLocked(intent);
19933 final long origId = Binder.clearCallingIdentity();
19934 String[] requiredPermissions = requiredPermission == null ? null
19935 : new String[] {requiredPermission};
19936 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19937 resultTo, resultCode, resultData, resultExtras,
19938 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19939 sticky, -1, uid, userId);
19940 Binder.restoreCallingIdentity(origId);
19945 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19946 // Refuse possible leaked file descriptors
19947 if (intent != null && intent.hasFileDescriptors() == true) {
19948 throw new IllegalArgumentException("File descriptors passed in Intent");
19951 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19952 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19954 synchronized(this) {
19955 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19956 != PackageManager.PERMISSION_GRANTED) {
19957 String msg = "Permission Denial: unbroadcastIntent() from pid="
19958 + Binder.getCallingPid()
19959 + ", uid=" + Binder.getCallingUid()
19960 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19962 throw new SecurityException(msg);
19964 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19965 if (stickies != null) {
19966 ArrayList<Intent> list = stickies.get(intent.getAction());
19967 if (list != null) {
19968 int N = list.size();
19970 for (i=0; i<N; i++) {
19971 if (intent.filterEquals(list.get(i))) {
19976 if (list.size() <= 0) {
19977 stickies.remove(intent.getAction());
19980 if (stickies.size() <= 0) {
19981 mStickyBroadcasts.remove(userId);
19987 void backgroundServicesFinishedLocked(int userId) {
19988 for (BroadcastQueue queue : mBroadcastQueues) {
19989 queue.backgroundServicesFinishedLocked(userId);
19993 public void finishReceiver(IBinder who, int resultCode, String resultData,
19994 Bundle resultExtras, boolean resultAbort, int flags) {
19995 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19997 // Refuse possible leaked file descriptors
19998 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19999 throw new IllegalArgumentException("File descriptors passed in Bundle");
20002 final long origId = Binder.clearCallingIdentity();
20004 boolean doNext = false;
20007 synchronized(this) {
20008 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
20009 ? mFgBroadcastQueue : mBgBroadcastQueue;
20010 r = queue.getMatchingOrderedReceiver(who);
20012 doNext = r.queue.finishReceiverLocked(r, resultCode,
20013 resultData, resultExtras, resultAbort, true);
20018 r.queue.processNextBroadcast(false);
20020 trimApplications();
20022 Binder.restoreCallingIdentity(origId);
20026 // =========================================================
20028 // =========================================================
20030 public boolean startInstrumentation(ComponentName className,
20031 String profileFile, int flags, Bundle arguments,
20032 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
20033 int userId, String abiOverride) {
20034 enforceNotIsolatedCaller("startInstrumentation");
20035 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20036 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
20037 // Refuse possible leaked file descriptors
20038 if (arguments != null && arguments.hasFileDescriptors()) {
20039 throw new IllegalArgumentException("File descriptors passed in Bundle");
20042 synchronized(this) {
20043 InstrumentationInfo ii = null;
20044 ApplicationInfo ai = null;
20046 ii = mContext.getPackageManager().getInstrumentationInfo(
20047 className, STOCK_PM_FLAGS);
20048 ai = AppGlobals.getPackageManager().getApplicationInfo(
20049 ii.targetPackage, STOCK_PM_FLAGS, userId);
20050 } catch (PackageManager.NameNotFoundException e) {
20051 } catch (RemoteException e) {
20054 reportStartInstrumentationFailureLocked(watcher, className,
20055 "Unable to find instrumentation info for: " + className);
20059 reportStartInstrumentationFailureLocked(watcher, className,
20060 "Unable to find instrumentation target package: " + ii.targetPackage);
20063 if (!ai.hasCode()) {
20064 reportStartInstrumentationFailureLocked(watcher, className,
20065 "Instrumentation target has no code: " + ii.targetPackage);
20069 int match = mContext.getPackageManager().checkSignatures(
20070 ii.targetPackage, ii.packageName);
20071 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20072 String msg = "Permission Denial: starting instrumentation "
20073 + className + " from pid="
20074 + Binder.getCallingPid()
20075 + ", uid=" + Binder.getCallingPid()
20076 + " not allowed because package " + ii.packageName
20077 + " does not have a signature matching the target "
20078 + ii.targetPackage;
20079 reportStartInstrumentationFailureLocked(watcher, className, msg);
20080 throw new SecurityException(msg);
20083 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20084 activeInstr.mClass = className;
20085 String defProcess = ai.processName;;
20086 if (ii.targetProcesses == null) {
20087 activeInstr.mTargetProcesses = new String[]{ai.processName};
20088 } else if (ii.targetProcesses.equals("*")) {
20089 activeInstr.mTargetProcesses = new String[0];
20091 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20092 defProcess = activeInstr.mTargetProcesses[0];
20094 activeInstr.mTargetInfo = ai;
20095 activeInstr.mProfileFile = profileFile;
20096 activeInstr.mArguments = arguments;
20097 activeInstr.mWatcher = watcher;
20098 activeInstr.mUiAutomationConnection = uiAutomationConnection;
20099 activeInstr.mResultClass = className;
20101 final long origId = Binder.clearCallingIdentity();
20102 // Instrumentation can kill and relaunch even persistent processes
20103 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20105 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20106 app.instr = activeInstr;
20107 activeInstr.mFinished = false;
20108 activeInstr.mRunningProcesses.add(app);
20109 if (!mActiveInstrumentation.contains(activeInstr)) {
20110 mActiveInstrumentation.add(activeInstr);
20112 Binder.restoreCallingIdentity(origId);
20119 * Report errors that occur while attempting to start Instrumentation. Always writes the
20120 * error to the logs, but if somebody is watching, send the report there too. This enables
20121 * the "am" command to report errors with more information.
20123 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
20124 * @param cn The component name of the instrumentation.
20125 * @param report The error report.
20127 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20128 ComponentName cn, String report) {
20129 Slog.w(TAG, report);
20130 if (watcher != null) {
20131 Bundle results = new Bundle();
20132 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20133 results.putString("Error", report);
20134 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20138 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20139 if (app.instr == null) {
20140 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20144 if (!app.instr.mFinished && results != null) {
20145 if (app.instr.mCurResults == null) {
20146 app.instr.mCurResults = new Bundle(results);
20148 app.instr.mCurResults.putAll(results);
20153 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20154 int userId = UserHandle.getCallingUserId();
20155 // Refuse possible leaked file descriptors
20156 if (results != null && results.hasFileDescriptors()) {
20157 throw new IllegalArgumentException("File descriptors passed in Intent");
20160 synchronized(this) {
20161 ProcessRecord app = getRecordForAppLocked(target);
20163 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20166 final long origId = Binder.clearCallingIdentity();
20167 addInstrumentationResultsLocked(app, results);
20168 Binder.restoreCallingIdentity(origId);
20172 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20173 if (app.instr == null) {
20174 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20178 if (!app.instr.mFinished) {
20179 if (app.instr.mWatcher != null) {
20180 Bundle finalResults = app.instr.mCurResults;
20181 if (finalResults != null) {
20182 if (app.instr.mCurResults != null && results != null) {
20183 finalResults.putAll(results);
20186 finalResults = results;
20188 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20189 app.instr.mClass, resultCode, finalResults);
20192 // Can't call out of the system process with a lock held, so post a message.
20193 if (app.instr.mUiAutomationConnection != null) {
20194 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20195 app.instr.mUiAutomationConnection).sendToTarget();
20197 app.instr.mFinished = true;
20200 app.instr.removeProcess(app);
20203 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20207 public void finishInstrumentation(IApplicationThread target,
20208 int resultCode, Bundle results) {
20209 int userId = UserHandle.getCallingUserId();
20210 // Refuse possible leaked file descriptors
20211 if (results != null && results.hasFileDescriptors()) {
20212 throw new IllegalArgumentException("File descriptors passed in Intent");
20215 synchronized(this) {
20216 ProcessRecord app = getRecordForAppLocked(target);
20218 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20221 final long origId = Binder.clearCallingIdentity();
20222 finishInstrumentationLocked(app, resultCode, results);
20223 Binder.restoreCallingIdentity(origId);
20227 // =========================================================
20229 // =========================================================
20231 public ConfigurationInfo getDeviceConfigurationInfo() {
20232 ConfigurationInfo config = new ConfigurationInfo();
20233 synchronized (this) {
20234 final Configuration globalConfig = getGlobalConfiguration();
20235 config.reqTouchScreen = globalConfig.touchscreen;
20236 config.reqKeyboardType = globalConfig.keyboard;
20237 config.reqNavigation = globalConfig.navigation;
20238 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20239 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20240 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20242 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20243 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20244 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20246 config.reqGlEsVersion = GL_ES_VERSION;
20251 ActivityStack getFocusedStack() {
20252 return mStackSupervisor.getFocusedStack();
20256 public int getFocusedStackId() throws RemoteException {
20257 ActivityStack focusedStack = getFocusedStack();
20258 if (focusedStack != null) {
20259 return focusedStack.getStackId();
20264 public Configuration getConfiguration() {
20266 synchronized(this) {
20267 ci = new Configuration(getGlobalConfiguration());
20268 ci.userSetLocale = false;
20274 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20275 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20276 synchronized (this) {
20277 mSuppressResizeConfigChanges = suppress;
20282 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20283 * animated the stack to the fullscreen, but can also be called if we are relaunching an
20284 * activity and clearing the task at the same time.
20287 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20288 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20289 if (StackId.isHomeOrRecentsStack(fromStackId)) {
20290 throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20292 synchronized (this) {
20293 final long origId = Binder.clearCallingIdentity();
20295 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20297 Binder.restoreCallingIdentity(origId);
20303 public void updatePersistentConfiguration(Configuration values) {
20304 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20305 enforceWriteSettingsPermission("updatePersistentConfiguration()");
20306 if (values == null) {
20307 throw new NullPointerException("Configuration must not be null");
20310 int userId = UserHandle.getCallingUserId();
20312 synchronized(this) {
20313 updatePersistentConfigurationLocked(values, userId);
20317 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20318 final long origId = Binder.clearCallingIdentity();
20320 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20322 Binder.restoreCallingIdentity(origId);
20326 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20327 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20328 FONT_SCALE, 1.0f, userId);
20330 synchronized (this) {
20331 if (getGlobalConfiguration().fontScale == scaleFactor) {
20335 final Configuration configuration
20336 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20337 configuration.fontScale = scaleFactor;
20338 updatePersistentConfigurationLocked(configuration, userId);
20342 private void enforceWriteSettingsPermission(String func) {
20343 int uid = Binder.getCallingUid();
20344 if (uid == ROOT_UID) {
20348 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20349 Settings.getPackageNameForUid(mContext, uid), false)) {
20353 String msg = "Permission Denial: " + func + " from pid="
20354 + Binder.getCallingPid()
20356 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20358 throw new SecurityException(msg);
20362 public boolean updateConfiguration(Configuration values) {
20363 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20365 synchronized(this) {
20366 if (values == null && mWindowManager != null) {
20367 // sentinel: fetch the current configuration from the window manager
20368 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20371 if (mWindowManager != null) {
20372 // Update OOM levels based on display size.
20373 mProcessList.applyDisplaySize(mWindowManager);
20376 final long origId = Binder.clearCallingIdentity();
20378 if (values != null) {
20379 Settings.System.clearConfiguration(values);
20381 updateConfigurationLocked(values, null, false, false /* persistent */,
20382 UserHandle.USER_NULL, false /* deferResume */,
20383 mTmpUpdateConfigurationResult);
20384 return mTmpUpdateConfigurationResult.changes != 0;
20386 Binder.restoreCallingIdentity(origId);
20391 void updateUserConfigurationLocked() {
20392 final Configuration configuration = new Configuration(getGlobalConfiguration());
20393 final int currentUserId = mUserController.getCurrentUserIdLocked();
20394 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20395 currentUserId, Settings.System.canWrite(mContext));
20396 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20397 false /* persistent */, currentUserId, false /* deferResume */);
20400 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20401 boolean initLocale) {
20402 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20405 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20406 boolean initLocale, boolean deferResume) {
20407 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20408 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20409 UserHandle.USER_NULL, deferResume);
20412 // To cache the list of supported system locales
20413 private String[] mSupportedSystemLocales = null;
20415 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20416 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20417 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20418 deferResume, null /* result */);
20422 * Do either or both things: (1) change the current configuration, and (2)
20423 * make sure the given activity is running with the (now) current
20424 * configuration. Returns true if the activity has been left running, or
20425 * false if <var>starting</var> is being destroyed to match the new
20428 * @param userId is only used when persistent parameter is set to true to persist configuration
20429 * for that particular user
20431 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20432 boolean initLocale, boolean persistent, int userId, boolean deferResume,
20433 UpdateConfigurationResult result) {
20435 boolean kept = true;
20437 if (mWindowManager != null) {
20438 mWindowManager.deferSurfaceLayout();
20441 if (values != null) {
20442 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20446 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20448 if (mWindowManager != null) {
20449 mWindowManager.continueSurfaceLayout();
20453 if (result != null) {
20454 result.changes = changes;
20455 result.activityRelaunched = !kept;
20460 /** Update default (global) configuration and notify listeners about changes. */
20461 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20462 boolean persistent, int userId, boolean deferResume) {
20463 mTempConfig.setTo(getGlobalConfiguration());
20464 final int changes = mTempConfig.updateFrom(values);
20465 if (changes == 0) {
20466 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20467 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20468 // performDisplayOverrideConfigUpdate in order to send the new display configuration
20469 // (even if there are no actual changes) to unfreeze the window.
20470 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20474 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20475 "Updating global configuration to: " + values);
20477 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20479 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20480 final LocaleList locales = values.getLocales();
20481 int bestLocaleIndex = 0;
20482 if (locales.size() > 1) {
20483 if (mSupportedSystemLocales == null) {
20484 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20486 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20488 SystemProperties.set("persist.sys.locale",
20489 locales.get(bestLocaleIndex).toLanguageTag());
20490 LocaleList.setDefault(locales, bestLocaleIndex);
20491 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20492 locales.get(bestLocaleIndex)));
20495 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20496 mTempConfig.seq = mConfigurationSeq;
20498 // Update stored global config and notify everyone about the change.
20499 mStackSupervisor.onConfigurationChanged(mTempConfig);
20501 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20502 // TODO(multi-display): Update UsageEvents#Event to include displayId.
20503 mUsageStatsService.reportConfigurationChange(mTempConfig,
20504 mUserController.getCurrentUserIdLocked());
20506 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20507 mShowDialogs = shouldShowDialogs(mTempConfig);
20509 AttributeCache ac = AttributeCache.instance();
20511 ac.updateConfiguration(mTempConfig);
20514 // Make sure all resources in our process are updated right now, so that anyone who is going
20515 // to retrieve resource values after we return will be sure to get the new ones. This is
20516 // especially important during boot, where the first config change needs to guarantee all
20517 // resources have that config before following boot code is executed.
20518 mSystemThread.applyConfigurationToResources(mTempConfig);
20520 // We need another copy of global config because we're scheduling some calls instead of
20521 // running them in place. We need to be sure that object we send will be handled unchanged.
20522 final Configuration configCopy = new Configuration(mTempConfig);
20523 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20524 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20525 msg.obj = configCopy;
20527 mHandler.sendMessage(msg);
20530 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20531 ProcessRecord app = mLruProcesses.get(i);
20533 if (app.thread != null) {
20534 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20535 + app.processName + " new config " + configCopy);
20536 app.thread.scheduleConfigurationChanged(configCopy);
20538 } catch (Exception e) {
20542 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20543 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20544 | Intent.FLAG_RECEIVER_FOREGROUND
20545 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20546 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20547 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20548 UserHandle.USER_ALL);
20549 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20550 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20551 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20552 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20553 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20554 if (initLocale || !mProcessesReady) {
20555 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20557 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20558 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20559 UserHandle.USER_ALL);
20562 // Override configuration of the default display duplicates global config, so we need to
20563 // update it also. This will also notify WindowManager about changes.
20564 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20571 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20572 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20574 synchronized (this) {
20575 // Check if display is initialized in AM.
20576 if (!mStackSupervisor.isDisplayAdded(displayId)) {
20577 // Call might come when display is not yet added or has already been removed.
20578 if (DEBUG_CONFIGURATION) {
20579 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20585 if (values == null && mWindowManager != null) {
20586 // sentinel: fetch the current configuration from the window manager
20587 values = mWindowManager.computeNewConfiguration(displayId);
20590 if (mWindowManager != null) {
20591 // Update OOM levels based on display size.
20592 mProcessList.applyDisplaySize(mWindowManager);
20595 final long origId = Binder.clearCallingIdentity();
20597 if (values != null) {
20598 Settings.System.clearConfiguration(values);
20600 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20601 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20602 return mTmpUpdateConfigurationResult.changes != 0;
20604 Binder.restoreCallingIdentity(origId);
20609 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20610 boolean deferResume, int displayId) {
20611 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20612 displayId, null /* result */);
20616 * Updates override configuration specific for the selected display. If no config is provided,
20617 * new one will be computed in WM based on current display info.
20619 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20620 ActivityRecord starting, boolean deferResume, int displayId,
20621 UpdateConfigurationResult result) {
20623 boolean kept = true;
20625 if (mWindowManager != null) {
20626 mWindowManager.deferSurfaceLayout();
20629 if (values != null) {
20630 if (displayId == DEFAULT_DISPLAY) {
20631 // Override configuration of the default display duplicates global config, so
20632 // we're calling global config update instead for default display. It will also
20633 // apply the correct override config.
20634 changes = updateGlobalConfiguration(values, false /* initLocale */,
20635 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20637 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20641 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20643 if (mWindowManager != null) {
20644 mWindowManager.continueSurfaceLayout();
20648 if (result != null) {
20649 result.changes = changes;
20650 result.activityRelaunched = !kept;
20655 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20657 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20658 final int changes = mTempConfig.updateFrom(values);
20659 if (changes != 0) {
20660 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20661 + mTempConfig + " for displayId=" + displayId);
20662 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20664 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20665 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20666 // Reset the unsupported display size dialog.
20667 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20669 killAllBackgroundProcessesExcept(N,
20670 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20674 // Update the configuration with WM first and check if any of the stacks need to be resized
20675 // due to the configuration change. If so, resize the stacks now and do any relaunches if
20676 // necessary. This way we don't need to relaunch again afterwards in
20677 // ensureActivityConfigurationLocked().
20678 if (mWindowManager != null) {
20679 final int[] resizedStacks =
20680 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20681 if (resizedStacks != null) {
20682 for (int stackId : resizedStacks) {
20683 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20691 /** Applies latest configuration and/or visibility updates if needed. */
20692 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20693 boolean kept = true;
20694 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20695 // mainStack is null during startup.
20696 if (mainStack != null) {
20697 if (changes != 0 && starting == null) {
20698 // If the configuration changed, and the caller is not already
20699 // in the process of starting an activity, then find the top
20700 // activity to check if its configuration needs to change.
20701 starting = mainStack.topRunningActivityLocked();
20704 if (starting != null) {
20705 kept = starting.ensureActivityConfigurationLocked(changes,
20706 false /* preserveWindow */);
20707 // And we need to make sure at this point that all other activities
20708 // are made visible with the correct configuration.
20709 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20710 !PRESERVE_WINDOWS);
20717 /** Helper method that requests bounds from WM and applies them to stack. */
20718 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20719 final Rect newStackBounds = new Rect();
20720 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20721 mStackSupervisor.resizeStackLocked(
20722 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20723 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20724 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20728 * Decide based on the configuration whether we should show the ANR,
20729 * crash, etc dialogs. The idea is that if there is no affordance to
20730 * press the on-screen buttons, or the user experience would be more
20731 * greatly impacted than the crash itself, we shouldn't show the dialog.
20733 * A thought: SystemUI might also want to get told about this, the Power
20734 * dialog / global actions also might want different behaviors.
20736 private static boolean shouldShowDialogs(Configuration config) {
20737 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20738 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20739 && config.navigation == Configuration.NAVIGATION_NONAV);
20740 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20741 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20742 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20743 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20744 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20745 return inputMethodExists && uiModeSupportsDialogs;
20749 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20750 synchronized (this) {
20751 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20752 if (srec != null) {
20753 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20759 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20760 Intent resultData) {
20762 synchronized (this) {
20763 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20765 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20771 public int getLaunchedFromUid(IBinder activityToken) {
20772 ActivityRecord srec;
20773 synchronized (this) {
20774 srec = ActivityRecord.forTokenLocked(activityToken);
20776 if (srec == null) {
20779 return srec.launchedFromUid;
20782 public String getLaunchedFromPackage(IBinder activityToken) {
20783 ActivityRecord srec;
20784 synchronized (this) {
20785 srec = ActivityRecord.forTokenLocked(activityToken);
20787 if (srec == null) {
20790 return srec.launchedFromPackage;
20793 // =========================================================
20794 // LIFETIME MANAGEMENT
20795 // =========================================================
20797 // Returns whether the app is receiving broadcast.
20798 // If receiving, fetch all broadcast queues which the app is
20799 // the current [or imminent] receiver on.
20800 private boolean isReceivingBroadcastLocked(ProcessRecord app,
20801 ArraySet<BroadcastQueue> receivingQueues) {
20802 if (!app.curReceivers.isEmpty()) {
20803 for (BroadcastRecord r : app.curReceivers) {
20804 receivingQueues.add(r.queue);
20809 // It's not the current receiver, but it might be starting up to become one
20810 for (BroadcastQueue queue : mBroadcastQueues) {
20811 final BroadcastRecord r = queue.mPendingBroadcast;
20812 if (r != null && r.curApp == app) {
20813 // found it; report which queue it's in
20814 receivingQueues.add(queue);
20818 return !receivingQueues.isEmpty();
20821 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20822 int targetUid, ComponentName targetComponent, String targetProcess) {
20823 if (!mTrackingAssociations) {
20826 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20827 = mAssociations.get(targetUid);
20828 if (components == null) {
20829 components = new ArrayMap<>();
20830 mAssociations.put(targetUid, components);
20832 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20833 if (sourceUids == null) {
20834 sourceUids = new SparseArray<>();
20835 components.put(targetComponent, sourceUids);
20837 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20838 if (sourceProcesses == null) {
20839 sourceProcesses = new ArrayMap<>();
20840 sourceUids.put(sourceUid, sourceProcesses);
20842 Association ass = sourceProcesses.get(sourceProcess);
20844 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20846 sourceProcesses.put(sourceProcess, ass);
20850 if (ass.mNesting == 1) {
20851 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20852 ass.mLastState = sourceState;
20857 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20858 ComponentName targetComponent) {
20859 if (!mTrackingAssociations) {
20862 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20863 = mAssociations.get(targetUid);
20864 if (components == null) {
20867 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20868 if (sourceUids == null) {
20871 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20872 if (sourceProcesses == null) {
20875 Association ass = sourceProcesses.get(sourceProcess);
20876 if (ass == null || ass.mNesting <= 0) {
20880 if (ass.mNesting == 0) {
20881 long uptime = SystemClock.uptimeMillis();
20882 ass.mTime += uptime - ass.mStartTime;
20883 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20884 += uptime - ass.mLastStateUptime;
20885 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20889 private void noteUidProcessState(final int uid, final int state) {
20890 mBatteryStatsService.noteUidProcessState(uid, state);
20891 if (mTrackingAssociations) {
20892 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20893 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20894 = mAssociations.valueAt(i1);
20895 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20896 SparseArray<ArrayMap<String, Association>> sourceUids
20897 = targetComponents.valueAt(i2);
20898 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20899 if (sourceProcesses != null) {
20900 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20901 Association ass = sourceProcesses.valueAt(i4);
20902 if (ass.mNesting >= 1) {
20903 // currently associated
20904 long uptime = SystemClock.uptimeMillis();
20905 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20906 += uptime - ass.mLastStateUptime;
20907 ass.mLastState = state;
20908 ass.mLastStateUptime = uptime;
20917 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20918 boolean doingAll, long now) {
20919 if (mAdjSeq == app.adjSeq) {
20920 // This adjustment has already been computed.
20921 return app.curRawAdj;
20924 if (app.thread == null) {
20925 app.adjSeq = mAdjSeq;
20926 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20927 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20928 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20931 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20932 app.adjSource = null;
20933 app.adjTarget = null;
20935 app.cached = false;
20937 final int activitiesSize = app.activities.size();
20939 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20940 // The max adjustment doesn't allow this app to be anything
20941 // below foreground, so it is not worth doing work for it.
20942 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20943 app.adjType = "fixed";
20944 app.adjSeq = mAdjSeq;
20945 app.curRawAdj = app.maxAdj;
20946 app.foregroundActivities = false;
20947 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20948 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20949 // System processes can do UI, and when they do we want to have
20950 // them trim their memory after the user leaves the UI. To
20951 // facilitate this, here we need to determine whether or not it
20952 // is currently showing UI.
20953 app.systemNoUi = true;
20954 if (app == TOP_APP) {
20955 app.systemNoUi = false;
20956 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20957 app.adjType = "pers-top-activity";
20958 } else if (app.hasTopUi) {
20959 app.systemNoUi = false;
20960 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20961 app.adjType = "pers-top-ui";
20962 } else if (activitiesSize > 0) {
20963 for (int j = 0; j < activitiesSize; j++) {
20964 final ActivityRecord r = app.activities.get(j);
20966 app.systemNoUi = false;
20970 if (!app.systemNoUi) {
20971 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20973 return (app.curAdj=app.maxAdj);
20976 app.systemNoUi = false;
20978 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20980 // Determine the importance of the process, starting with most
20981 // important to least, and assign an appropriate OOM adjustment.
20985 boolean foregroundActivities = false;
20986 mTmpBroadcastQueue.clear();
20987 if (app == TOP_APP) {
20988 // The last app on the list is the foreground app.
20989 adj = ProcessList.FOREGROUND_APP_ADJ;
20990 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20991 app.adjType = "top-activity";
20992 foregroundActivities = true;
20993 procState = PROCESS_STATE_CUR_TOP;
20994 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20995 } else if (app.instr != null) {
20996 // Don't want to kill running instrumentation.
20997 adj = ProcessList.FOREGROUND_APP_ADJ;
20998 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20999 app.adjType = "instrumentation";
21000 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21001 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
21002 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
21003 // An app that is currently receiving a broadcast also
21004 // counts as being in the foreground for OOM killer purposes.
21005 // It's placed in a sched group based on the nature of the
21006 // broadcast as reflected by which queue it's active in.
21007 adj = ProcessList.FOREGROUND_APP_ADJ;
21008 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
21009 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
21010 app.adjType = "broadcast";
21011 procState = ActivityManager.PROCESS_STATE_RECEIVER;
21012 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
21013 } else if (app.executingServices.size() > 0) {
21014 // An app that is currently executing a service callback also
21015 // counts as being in the foreground.
21016 adj = ProcessList.FOREGROUND_APP_ADJ;
21017 schedGroup = app.execServicesFg ?
21018 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
21019 app.adjType = "exec-service";
21020 procState = ActivityManager.PROCESS_STATE_SERVICE;
21021 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
21022 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
21024 // As far as we know the process is empty. We may change our mind later.
21025 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21026 // At this point we don't actually know the adjustment. Use the cached adj
21027 // value that the caller wants us to.
21029 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21032 app.adjType = "cch-empty";
21033 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
21036 // Examine all activities if not already foreground.
21037 if (!foregroundActivities && activitiesSize > 0) {
21038 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
21039 for (int j = 0; j < activitiesSize; j++) {
21040 final ActivityRecord r = app.activities.get(j);
21041 if (r.app != app) {
21042 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
21043 + " instead of expected " + app);
21044 if (r.app == null || (r.app.uid == app.uid)) {
21045 // Only fix things up when they look sane
21052 // App has a visible activity; only upgrade adjustment.
21053 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21054 adj = ProcessList.VISIBLE_APP_ADJ;
21055 app.adjType = "vis-activity";
21056 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
21058 if (procState > PROCESS_STATE_CUR_TOP) {
21059 procState = PROCESS_STATE_CUR_TOP;
21060 app.adjType = "vis-activity";
21061 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
21063 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21064 app.cached = false;
21066 foregroundActivities = true;
21067 final TaskRecord task = r.getTask();
21068 if (task != null && minLayer > 0) {
21069 final int layer = task.mLayerRank;
21070 if (layer >= 0 && minLayer > layer) {
21075 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21076 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21077 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21078 app.adjType = "pause-activity";
21079 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21081 if (procState > PROCESS_STATE_CUR_TOP) {
21082 procState = PROCESS_STATE_CUR_TOP;
21083 app.adjType = "pause-activity";
21084 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21086 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21087 app.cached = false;
21089 foregroundActivities = true;
21090 } else if (r.state == ActivityState.STOPPING) {
21091 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21092 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21093 app.adjType = "stop-activity";
21094 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21096 // For the process state, we will at this point consider the
21097 // process to be cached. It will be cached either as an activity
21098 // or empty depending on whether the activity is finishing. We do
21099 // this so that we can treat the process as cached for purposes of
21100 // memory trimming (determing current memory level, trim command to
21101 // send to process) since there can be an arbitrary number of stopping
21102 // processes and they should soon all go into the cached state.
21103 if (!r.finishing) {
21104 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21105 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21106 app.adjType = "stop-activity";
21107 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21110 app.cached = false;
21112 foregroundActivities = true;
21114 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21115 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21116 app.adjType = "cch-act";
21117 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21121 if (adj == ProcessList.VISIBLE_APP_ADJ) {
21126 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21127 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21128 if (app.foregroundServices) {
21129 // The user is aware of this app, so make it visible.
21130 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21131 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21132 app.cached = false;
21133 app.adjType = "fg-service";
21134 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21135 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21136 } else if (app.hasOverlayUi) {
21137 // The process is display an overlay UI.
21138 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21139 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21140 app.cached = false;
21141 app.adjType = "has-overlay-ui";
21142 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21143 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21147 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21148 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21149 if (app.forcingToImportant != null) {
21150 // This is currently used for toasts... they are not interactive, and
21151 // we don't want them to cause the app to become fully foreground (and
21152 // thus out of background check), so we yes the best background level we can.
21153 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21154 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21155 app.cached = false;
21156 app.adjType = "force-imp";
21157 app.adjSource = app.forcingToImportant;
21158 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21159 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21163 if (app == mHeavyWeightProcess) {
21164 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21165 // We don't want to kill the current heavy-weight process.
21166 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21167 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21168 app.cached = false;
21169 app.adjType = "heavy";
21170 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21172 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21173 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21174 app.adjType = "heavy";
21175 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21179 if (app == mHomeProcess) {
21180 if (adj > ProcessList.HOME_APP_ADJ) {
21181 // This process is hosting what we currently consider to be the
21182 // home app, so we don't want to let it go into the background.
21183 adj = ProcessList.HOME_APP_ADJ;
21184 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21185 app.cached = false;
21186 app.adjType = "home";
21187 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21189 if (procState > ActivityManager.PROCESS_STATE_HOME) {
21190 procState = ActivityManager.PROCESS_STATE_HOME;
21191 app.adjType = "home";
21192 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21196 if (app == mPreviousProcess && app.activities.size() > 0) {
21197 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21198 // This was the previous process that showed UI to the user.
21199 // We want to try to keep it around more aggressively, to give
21200 // a good experience around switching between two apps.
21201 adj = ProcessList.PREVIOUS_APP_ADJ;
21202 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21203 app.cached = false;
21204 app.adjType = "previous";
21205 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21207 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21208 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21209 app.adjType = "previous";
21210 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21214 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21215 + " reason=" + app.adjType);
21217 // By default, we use the computed adjustment. It may be changed if
21218 // there are applications dependent on our services or providers, but
21219 // this gives us a baseline and makes sure we don't get into an
21220 // infinite recursion.
21221 app.adjSeq = mAdjSeq;
21222 app.curRawAdj = adj;
21223 app.hasStartedServices = false;
21225 if (mBackupTarget != null && app == mBackupTarget.app) {
21226 // If possible we want to avoid killing apps while they're being backed up
21227 if (adj > ProcessList.BACKUP_APP_ADJ) {
21228 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21229 adj = ProcessList.BACKUP_APP_ADJ;
21230 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21231 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21233 app.adjType = "backup";
21234 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21235 app.cached = false;
21237 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21238 procState = ActivityManager.PROCESS_STATE_BACKUP;
21239 app.adjType = "backup";
21240 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21244 boolean mayBeTop = false;
21245 String mayBeTopType = null;
21246 Object mayBeTopSource = null;
21247 Object mayBeTopTarget = null;
21249 for (int is = app.services.size()-1;
21250 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21251 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21252 || procState > ActivityManager.PROCESS_STATE_TOP);
21254 ServiceRecord s = app.services.valueAt(is);
21255 if (s.startRequested) {
21256 app.hasStartedServices = true;
21257 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21258 procState = ActivityManager.PROCESS_STATE_SERVICE;
21259 app.adjType = "started-services";
21260 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21262 if (app.hasShownUi && app != mHomeProcess) {
21263 // If this process has shown some UI, let it immediately
21264 // go to the LRU list because it may be pretty heavy with
21265 // UI stuff. We'll tag it with a label just to help
21266 // debug and understand what is going on.
21267 if (adj > ProcessList.SERVICE_ADJ) {
21268 app.adjType = "cch-started-ui-services";
21271 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21272 // This service has seen some activity within
21273 // recent memory, so we will keep its process ahead
21274 // of the background processes.
21275 if (adj > ProcessList.SERVICE_ADJ) {
21276 adj = ProcessList.SERVICE_ADJ;
21277 app.adjType = "started-services";
21278 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21279 app.cached = false;
21282 // If we have let the service slide into the background
21283 // state, still have some text describing what it is doing
21284 // even though the service no longer has an impact.
21285 if (adj > ProcessList.SERVICE_ADJ) {
21286 app.adjType = "cch-started-services";
21291 for (int conni = s.connections.size()-1;
21292 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21293 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21294 || procState > ActivityManager.PROCESS_STATE_TOP);
21296 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21298 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21299 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21300 || procState > ActivityManager.PROCESS_STATE_TOP);
21302 // XXX should compute this based on the max of
21303 // all connected clients.
21304 ConnectionRecord cr = clist.get(i);
21305 if (cr.binding.client == app) {
21306 // Binding to ourself is not interesting.
21310 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21311 ProcessRecord client = cr.binding.client;
21312 int clientAdj = computeOomAdjLocked(client, cachedAdj,
21313 TOP_APP, doingAll, now);
21314 int clientProcState = client.curProcState;
21315 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21316 // If the other app is cached for any reason, for purposes here
21317 // we are going to consider it empty. The specific cached state
21318 // doesn't propagate except under certain conditions.
21319 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21321 String adjType = null;
21322 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21323 // Not doing bind OOM management, so treat
21324 // this guy more like a started service.
21325 if (app.hasShownUi && app != mHomeProcess) {
21326 // If this process has shown some UI, let it immediately
21327 // go to the LRU list because it may be pretty heavy with
21328 // UI stuff. We'll tag it with a label just to help
21329 // debug and understand what is going on.
21330 if (adj > clientAdj) {
21331 adjType = "cch-bound-ui-services";
21333 app.cached = false;
21335 clientProcState = procState;
21337 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21338 // This service has not seen activity within
21339 // recent memory, so allow it to drop to the
21340 // LRU list if there is no other reason to keep
21341 // it around. We'll also tag it with a label just
21342 // to help debug and undertand what is going on.
21343 if (adj > clientAdj) {
21344 adjType = "cch-bound-services";
21350 if (adj > clientAdj) {
21351 // If this process has recently shown UI, and
21352 // the process that is binding to it is less
21353 // important than being visible, then we don't
21354 // care about the binding as much as we care
21355 // about letting this process get into the LRU
21356 // list to be killed and restarted if needed for
21358 if (app.hasShownUi && app != mHomeProcess
21359 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21360 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21361 adjType = "cch-bound-ui-services";
21365 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21366 |Context.BIND_IMPORTANT)) != 0) {
21367 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21368 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21369 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21370 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21371 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21372 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21373 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21374 newAdj = clientAdj;
21376 if (adj > ProcessList.VISIBLE_APP_ADJ) {
21377 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21382 if (!client.cached) {
21383 app.cached = false;
21385 if (adj > newAdj) {
21387 adjType = "service";
21391 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21392 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21393 // This will treat important bound services identically to
21394 // the top app, which may behave differently than generic
21395 // foreground work.
21396 if (client.curSchedGroup > schedGroup) {
21397 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21398 schedGroup = client.curSchedGroup;
21400 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21403 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21404 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21405 // Special handling of clients who are in the top state.
21406 // We *may* want to consider this process to be in the
21407 // top state as well, but only if there is not another
21408 // reason for it to be running. Being on the top is a
21409 // special state, meaning you are specifically running
21410 // for the current top app. If the process is already
21411 // running in the background for some other reason, it
21412 // is more important to continue considering it to be
21413 // in the background state.
21415 mayBeTopType = "service";
21416 mayBeTopSource = cr.binding.client;
21417 mayBeTopTarget = s.name;
21418 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21420 // Special handling for above-top states (persistent
21421 // processes). These should not bring the current process
21422 // into the top state, since they are not on top. Instead
21423 // give them the best state after that.
21424 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21426 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21427 } else if (mWakefulness
21428 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21429 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21432 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21435 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21439 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21440 if (clientProcState <
21441 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21443 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21446 if (clientProcState <
21447 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21449 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21452 if (procState > clientProcState) {
21453 procState = clientProcState;
21454 if (adjType == null) {
21455 adjType = "service";
21458 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21459 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21460 app.pendingUiClean = true;
21462 if (adjType != null) {
21463 app.adjType = adjType;
21464 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21465 .REASON_SERVICE_IN_USE;
21466 app.adjSource = cr.binding.client;
21467 app.adjSourceProcState = clientProcState;
21468 app.adjTarget = s.name;
21469 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21470 + ": " + app + ", due to " + cr.binding.client
21471 + " adj=" + adj + " procState=" + procState);
21474 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21475 app.treatLikeActivity = true;
21477 final ActivityRecord a = cr.activity;
21478 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21479 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21480 (a.visible || a.state == ActivityState.RESUMED ||
21481 a.state == ActivityState.PAUSING)) {
21482 adj = ProcessList.FOREGROUND_APP_ADJ;
21483 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21484 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21485 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21487 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21490 app.cached = false;
21491 app.adjType = "service";
21492 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21493 .REASON_SERVICE_IN_USE;
21495 app.adjSourceProcState = procState;
21496 app.adjTarget = s.name;
21497 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21505 for (int provi = app.pubProviders.size()-1;
21506 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21507 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21508 || procState > ActivityManager.PROCESS_STATE_TOP);
21510 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21511 for (int i = cpr.connections.size()-1;
21512 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21513 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21514 || procState > ActivityManager.PROCESS_STATE_TOP);
21516 ContentProviderConnection conn = cpr.connections.get(i);
21517 ProcessRecord client = conn.client;
21518 if (client == app) {
21519 // Being our own client is not interesting.
21522 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21523 int clientProcState = client.curProcState;
21524 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21525 // If the other app is cached for any reason, for purposes here
21526 // we are going to consider it empty.
21527 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21529 String adjType = null;
21530 if (adj > clientAdj) {
21531 if (app.hasShownUi && app != mHomeProcess
21532 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21533 adjType = "cch-ui-provider";
21535 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21536 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21537 adjType = "provider";
21539 app.cached &= client.cached;
21541 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21542 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21543 // Special handling of clients who are in the top state.
21544 // We *may* want to consider this process to be in the
21545 // top state as well, but only if there is not another
21546 // reason for it to be running. Being on the top is a
21547 // special state, meaning you are specifically running
21548 // for the current top app. If the process is already
21549 // running in the background for some other reason, it
21550 // is more important to continue considering it to be
21551 // in the background state.
21553 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21554 mayBeTopType = adjType = "provider-top";
21555 mayBeTopSource = client;
21556 mayBeTopTarget = cpr.name;
21558 // Special handling for above-top states (persistent
21559 // processes). These should not bring the current process
21560 // into the top state, since they are not on top. Instead
21561 // give them the best state after that.
21563 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21564 if (adjType == null) {
21565 adjType = "provider";
21569 if (procState > clientProcState) {
21570 procState = clientProcState;
21572 if (client.curSchedGroup > schedGroup) {
21573 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21575 if (adjType != null) {
21576 app.adjType = adjType;
21577 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21578 .REASON_PROVIDER_IN_USE;
21579 app.adjSource = client;
21580 app.adjSourceProcState = clientProcState;
21581 app.adjTarget = cpr.name;
21582 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21583 + ": " + app + ", due to " + client
21584 + " adj=" + adj + " procState=" + procState);
21587 // If the provider has external (non-framework) process
21588 // dependencies, ensure that its adjustment is at least
21589 // FOREGROUND_APP_ADJ.
21590 if (cpr.hasExternalProcessHandles()) {
21591 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21592 adj = ProcessList.FOREGROUND_APP_ADJ;
21593 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21594 app.cached = false;
21595 app.adjType = "ext-provider";
21596 app.adjTarget = cpr.name;
21597 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21599 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21600 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21605 if (app.lastProviderTime > 0 &&
21606 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21607 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21608 adj = ProcessList.PREVIOUS_APP_ADJ;
21609 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21610 app.cached = false;
21611 app.adjType = "recent-provider";
21612 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21614 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21615 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21616 app.adjType = "recent-provider";
21617 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21621 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21622 // A client of one of our services or providers is in the top state. We
21623 // *may* want to be in the top state, but not if we are already running in
21624 // the background for some other reason. For the decision here, we are going
21625 // to pick out a few specific states that we want to remain in when a client
21626 // is top (states that tend to be longer-term) and otherwise allow it to go
21627 // to the top state.
21628 switch (procState) {
21629 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21630 // Something else is keeping it at this level, just leave it.
21632 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21633 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21634 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21635 case ActivityManager.PROCESS_STATE_SERVICE:
21636 // These all are longer-term states, so pull them up to the top
21637 // of the background states, but not all the way to the top state.
21638 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21639 app.adjType = mayBeTopType;
21640 app.adjSource = mayBeTopSource;
21641 app.adjTarget = mayBeTopTarget;
21642 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21643 + ": " + app + ", due to " + mayBeTopSource
21644 + " adj=" + adj + " procState=" + procState);
21647 // Otherwise, top is a better choice, so take it.
21648 procState = ActivityManager.PROCESS_STATE_TOP;
21649 app.adjType = mayBeTopType;
21650 app.adjSource = mayBeTopSource;
21651 app.adjTarget = mayBeTopTarget;
21652 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21653 + ": " + app + ", due to " + mayBeTopSource
21654 + " adj=" + adj + " procState=" + procState);
21659 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21660 if (app.hasClientActivities) {
21661 // This is a cached process, but with client activities. Mark it so.
21662 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21663 app.adjType = "cch-client-act";
21664 } else if (app.treatLikeActivity) {
21665 // This is a cached process, but somebody wants us to treat it like it has
21666 // an activity, okay!
21667 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21668 app.adjType = "cch-as-act";
21672 if (adj == ProcessList.SERVICE_ADJ) {
21674 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21675 mNewNumServiceProcs++;
21676 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21677 if (!app.serviceb) {
21678 // This service isn't far enough down on the LRU list to
21679 // normally be a B service, but if we are low on RAM and it
21680 // is large we want to force it down since we would prefer to
21681 // keep launcher over it.
21682 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21683 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21684 app.serviceHighRam = true;
21685 app.serviceb = true;
21686 //Slog.i(TAG, "ADJ " + app + " high ram!");
21688 mNewNumAServiceProcs++;
21689 //Slog.i(TAG, "ADJ " + app + " not high ram!");
21692 app.serviceHighRam = false;
21695 if (app.serviceb) {
21696 adj = ProcessList.SERVICE_B_ADJ;
21700 app.curRawAdj = adj;
21702 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21703 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21704 if (adj > app.maxAdj) {
21706 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21707 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21711 // Do final modification to adj. Everything we do between here and applying
21712 // the final setAdj must be done in this function, because we will also use
21713 // it when computing the final cached adj later. Note that we don't need to
21714 // worry about this for max adj above, since max adj will always be used to
21715 // keep it out of the cached vaues.
21716 app.curAdj = app.modifyRawOomAdj(adj);
21717 app.curSchedGroup = schedGroup;
21718 app.curProcState = procState;
21719 app.foregroundActivities = foregroundActivities;
21721 return app.curRawAdj;
21725 * Record new PSS sample for a process.
21727 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21729 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21731 proc.lastPssTime = now;
21732 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21733 if (DEBUG_PSS) Slog.d(TAG_PSS,
21734 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21735 + " state=" + ProcessList.makeProcStateString(procState));
21736 if (proc.initialIdlePss == 0) {
21737 proc.initialIdlePss = pss;
21739 proc.lastPss = pss;
21740 proc.lastSwapPss = swapPss;
21741 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21742 proc.lastCachedPss = pss;
21743 proc.lastCachedSwapPss = swapPss;
21746 final SparseArray<Pair<Long, String>> watchUids
21747 = mMemWatchProcesses.getMap().get(proc.processName);
21749 if (watchUids != null) {
21750 Pair<Long, String> val = watchUids.get(proc.uid);
21752 val = watchUids.get(0);
21758 if (check != null) {
21759 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21760 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21761 if (!isDebuggable) {
21762 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21763 isDebuggable = true;
21766 if (isDebuggable) {
21767 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21768 final ProcessRecord myProc = proc;
21769 final File heapdumpFile = DumpHeapProvider.getJavaFile();
21770 mMemWatchDumpProcName = proc.processName;
21771 mMemWatchDumpFile = heapdumpFile.toString();
21772 mMemWatchDumpPid = proc.pid;
21773 mMemWatchDumpUid = proc.uid;
21774 BackgroundThread.getHandler().post(new Runnable() {
21776 public void run() {
21777 revokeUriPermission(ActivityThread.currentActivityThread()
21778 .getApplicationThread(),
21779 null, DumpHeapActivity.JAVA_URI,
21780 Intent.FLAG_GRANT_READ_URI_PERMISSION
21781 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21782 UserHandle.myUserId());
21783 ParcelFileDescriptor fd = null;
21785 heapdumpFile.delete();
21786 fd = ParcelFileDescriptor.open(heapdumpFile,
21787 ParcelFileDescriptor.MODE_CREATE |
21788 ParcelFileDescriptor.MODE_TRUNCATE |
21789 ParcelFileDescriptor.MODE_WRITE_ONLY |
21790 ParcelFileDescriptor.MODE_APPEND);
21791 IApplicationThread thread = myProc.thread;
21792 if (thread != null) {
21794 if (DEBUG_PSS) Slog.d(TAG_PSS,
21795 "Requesting dump heap from "
21796 + myProc + " to " + heapdumpFile);
21797 thread.dumpHeap(/* managed= */ true,
21798 /* mallocInfo= */ false, /* runGc= */ false,
21799 heapdumpFile.toString(), fd);
21800 } catch (RemoteException e) {
21803 } catch (FileNotFoundException e) {
21804 e.printStackTrace();
21809 } catch (IOException e) {
21816 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21817 + ", but debugging not enabled");
21824 * Schedule PSS collection of a process.
21826 void requestPssLocked(ProcessRecord proc, int procState) {
21827 if (mPendingPssProcesses.contains(proc)) {
21830 if (mPendingPssProcesses.size() == 0) {
21831 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21833 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21834 proc.pssProcState = procState;
21835 mPendingPssProcesses.add(proc);
21839 * Schedule PSS collection of all processes.
21841 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21843 if (now < (mLastFullPssTime +
21844 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21845 : mConstants.FULL_PSS_MIN_INTERVAL))) {
21849 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
21850 mLastFullPssTime = now;
21851 mFullPssPending = true;
21852 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21853 mPendingPssProcesses.clear();
21854 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21855 ProcessRecord app = mLruProcesses.get(i);
21856 if (app.thread == null
21857 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21860 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21861 app.pssProcState = app.setProcState;
21862 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21863 mTestPssMode, isSleepingLocked(), now);
21864 mPendingPssProcesses.add(app);
21867 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21870 public void setTestPssMode(boolean enabled) {
21871 synchronized (this) {
21872 mTestPssMode = enabled;
21874 // Whenever we enable the mode, we want to take a snapshot all of current
21875 // process mem use.
21876 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21882 * Ask a given process to GC right now.
21884 final void performAppGcLocked(ProcessRecord app) {
21886 app.lastRequestedGc = SystemClock.uptimeMillis();
21887 if (app.thread != null) {
21888 if (app.reportLowMemory) {
21889 app.reportLowMemory = false;
21890 app.thread.scheduleLowMemory();
21892 app.thread.processInBackground();
21895 } catch (Exception e) {
21901 * Returns true if things are idle enough to perform GCs.
21903 private final boolean canGcNowLocked() {
21904 boolean processingBroadcasts = false;
21905 for (BroadcastQueue q : mBroadcastQueues) {
21906 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21907 processingBroadcasts = true;
21910 return !processingBroadcasts
21911 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21915 * Perform GCs on all processes that are waiting for it, but only
21916 * if things are idle.
21918 final void performAppGcsLocked() {
21919 final int N = mProcessesToGc.size();
21923 if (canGcNowLocked()) {
21924 while (mProcessesToGc.size() > 0) {
21925 ProcessRecord proc = mProcessesToGc.remove(0);
21926 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21927 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21928 <= SystemClock.uptimeMillis()) {
21929 // To avoid spamming the system, we will GC processes one
21930 // at a time, waiting a few seconds between each.
21931 performAppGcLocked(proc);
21932 scheduleAppGcsLocked();
21935 // It hasn't been long enough since we last GCed this
21936 // process... put it in the list to wait for its time.
21937 addProcessToGcListLocked(proc);
21943 scheduleAppGcsLocked();
21948 * If all looks good, perform GCs on all processes waiting for them.
21950 final void performAppGcsIfAppropriateLocked() {
21951 if (canGcNowLocked()) {
21952 performAppGcsLocked();
21955 // Still not idle, wait some more.
21956 scheduleAppGcsLocked();
21960 * Schedule the execution of all pending app GCs.
21962 final void scheduleAppGcsLocked() {
21963 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21965 if (mProcessesToGc.size() > 0) {
21966 // Schedule a GC for the time to the next process.
21967 ProcessRecord proc = mProcessesToGc.get(0);
21968 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21970 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21971 long now = SystemClock.uptimeMillis();
21972 if (when < (now+mConstants.GC_TIMEOUT)) {
21973 when = now + mConstants.GC_TIMEOUT;
21975 mHandler.sendMessageAtTime(msg, when);
21980 * Add a process to the array of processes waiting to be GCed. Keeps the
21981 * list in sorted order by the last GC time. The process can't already be
21984 final void addProcessToGcListLocked(ProcessRecord proc) {
21985 boolean added = false;
21986 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21987 if (mProcessesToGc.get(i).lastRequestedGc <
21988 proc.lastRequestedGc) {
21990 mProcessesToGc.add(i+1, proc);
21995 mProcessesToGc.add(0, proc);
22000 * Set up to ask a process to GC itself. This will either do it
22001 * immediately, or put it on the list of processes to gc the next
22002 * time things are idle.
22004 final void scheduleAppGcLocked(ProcessRecord app) {
22005 long now = SystemClock.uptimeMillis();
22006 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
22009 if (!mProcessesToGc.contains(app)) {
22010 addProcessToGcListLocked(app);
22011 scheduleAppGcsLocked();
22015 final void checkExcessivePowerUsageLocked() {
22016 updateCpuStatsNow();
22018 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22019 boolean doCpuKills = true;
22020 if (mLastPowerCheckUptime == 0) {
22021 doCpuKills = false;
22023 final long curUptime = SystemClock.uptimeMillis();
22024 final long uptimeSince = curUptime - mLastPowerCheckUptime;
22025 mLastPowerCheckUptime = curUptime;
22026 int i = mLruProcesses.size();
22029 ProcessRecord app = mLruProcesses.get(i);
22030 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22031 if (app.lastCpuTime <= 0) {
22034 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
22036 StringBuilder sb = new StringBuilder(128);
22037 sb.append("CPU for ");
22038 app.toShortString(sb);
22039 sb.append(": over ");
22040 TimeUtils.formatDuration(uptimeSince, sb);
22041 sb.append(" used ");
22042 TimeUtils.formatDuration(cputimeUsed, sb);
22044 sb.append((cputimeUsed*100)/uptimeSince);
22046 Slog.i(TAG_POWER, sb.toString());
22048 // If the process has used too much CPU over the last duration, the
22049 // user probably doesn't want this, so kill!
22050 if (doCpuKills && uptimeSince > 0) {
22051 // What is the limit for this process?
22053 long checkDur = curUptime - app.whenUnimportant;
22054 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
22055 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
22056 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
22057 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
22058 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
22059 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
22060 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
22062 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
22064 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
22065 synchronized (stats) {
22066 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
22067 uptimeSince, cputimeUsed);
22069 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
22070 + " dur=" + checkDur + " limit=" + cpuLimit, true);
22071 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22074 app.lastCpuTime = app.curCpuTime;
22079 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22081 boolean success = true;
22083 if (app.curRawAdj != app.setRawAdj) {
22084 app.setRawAdj = app.curRawAdj;
22089 if (app.curAdj != app.setAdj) {
22090 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22091 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22092 String msg = "Set " + app.pid + " " + app.processName + " adj "
22093 + app.curAdj + ": " + app.adjType;
22094 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22096 app.setAdj = app.curAdj;
22097 app.verifiedAdj = ProcessList.INVALID_ADJ;
22100 if (app.setSchedGroup != app.curSchedGroup) {
22101 int oldSchedGroup = app.setSchedGroup;
22102 app.setSchedGroup = app.curSchedGroup;
22103 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22104 String msg = "Setting sched group of " + app.processName
22105 + " to " + app.curSchedGroup;
22106 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22108 if (app.waitingToKill != null && app.curReceivers.isEmpty()
22109 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22110 app.kill(app.waitingToKill, true);
22114 switch (app.curSchedGroup) {
22115 case ProcessList.SCHED_GROUP_BACKGROUND:
22116 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22118 case ProcessList.SCHED_GROUP_TOP_APP:
22119 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22120 processGroup = THREAD_GROUP_TOP_APP;
22123 processGroup = THREAD_GROUP_DEFAULT;
22126 long oldId = Binder.clearCallingIdentity();
22128 setProcessGroup(app.pid, processGroup);
22129 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22130 // do nothing if we already switched to RT
22131 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22132 mVrController.onTopProcChangedLocked(app);
22133 if (mUseFifoUiScheduling) {
22134 // Switch UI pipeline for app to SCHED_FIFO
22135 app.savedPriority = Process.getThreadPriority(app.pid);
22136 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22137 if (app.renderThreadTid != 0) {
22138 scheduleAsFifoPriority(app.renderThreadTid,
22139 /* suppressLogs */true);
22140 if (DEBUG_OOM_ADJ) {
22141 Slog.d("UI_FIFO", "Set RenderThread (TID " +
22142 app.renderThreadTid + ") to FIFO");
22145 if (DEBUG_OOM_ADJ) {
22146 Slog.d("UI_FIFO", "Not setting RenderThread TID");
22150 // Boost priority for top app UI and render threads
22151 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22152 if (app.renderThreadTid != 0) {
22154 setThreadPriority(app.renderThreadTid,
22155 TOP_APP_PRIORITY_BOOST);
22156 } catch (IllegalArgumentException e) {
22157 // thread died, ignore
22162 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22163 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22164 mVrController.onTopProcChangedLocked(app);
22165 if (mUseFifoUiScheduling) {
22167 // Reset UI pipeline to SCHED_OTHER
22168 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22169 setThreadPriority(app.pid, app.savedPriority);
22170 if (app.renderThreadTid != 0) {
22171 setThreadScheduler(app.renderThreadTid,
22173 setThreadPriority(app.renderThreadTid, -4);
22175 } catch (IllegalArgumentException e) {
22177 "Failed to set scheduling policy, thread does not exist:\n"
22179 } catch (SecurityException e) {
22180 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22183 // Reset priority for top app UI and render threads
22184 setThreadPriority(app.pid, 0);
22185 if (app.renderThreadTid != 0) {
22186 setThreadPriority(app.renderThreadTid, 0);
22190 } catch (Exception e) {
22192 Slog.w(TAG, "Failed setting process group of " + app.pid
22193 + " to " + app.curSchedGroup);
22194 Slog.w(TAG, "at location", e);
22197 Binder.restoreCallingIdentity(oldId);
22201 if (app.repForegroundActivities != app.foregroundActivities) {
22202 app.repForegroundActivities = app.foregroundActivities;
22203 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22205 if (app.repProcState != app.curProcState) {
22206 app.repProcState = app.curProcState;
22207 if (app.thread != null) {
22210 //RuntimeException h = new RuntimeException("here");
22211 Slog.i(TAG, "Sending new process state " + app.repProcState
22212 + " to " + app /*, h*/);
22214 app.thread.setProcessState(app.repProcState);
22215 } catch (RemoteException e) {
22219 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22220 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22221 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22222 // Experimental code to more aggressively collect pss while
22223 // running test... the problem is that this tends to collect
22224 // the data right when a process is transitioning between process
22225 // states, which well tend to give noisy data.
22226 long start = SystemClock.uptimeMillis();
22227 long pss = Debug.getPss(app.pid, mTmpLong, null);
22228 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22229 mPendingPssProcesses.remove(app);
22230 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22231 + " to " + app.curProcState + ": "
22232 + (SystemClock.uptimeMillis()-start) + "ms");
22234 app.lastStateTime = now;
22235 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22236 mTestPssMode, isSleepingLocked(), now);
22237 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22238 + ProcessList.makeProcStateString(app.setProcState) + " to "
22239 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22240 + (app.nextPssTime-now) + ": " + app);
22242 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22243 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22245 requestPssLocked(app, app.setProcState);
22246 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22247 mTestPssMode, isSleepingLocked(), now);
22248 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22249 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22251 if (app.setProcState != app.curProcState) {
22252 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22253 String msg = "Proc state change of " + app.processName
22254 + " to " + app.curProcState;
22255 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22257 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22258 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22259 if (setImportant && !curImportant) {
22260 // This app is no longer something we consider important enough to allow to
22261 // use arbitrary amounts of battery power. Note
22262 // its current CPU time to later know to kill it if
22263 // it is not behaving well.
22264 app.whenUnimportant = now;
22265 app.lastCpuTime = 0;
22267 // Inform UsageStats of important process state change
22268 // Must be called before updating setProcState
22269 maybeUpdateUsageStatsLocked(app, nowElapsed);
22271 app.setProcState = app.curProcState;
22272 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22273 app.notCachedSinceIdle = false;
22276 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22278 app.procStateChanged = true;
22280 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22281 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22282 // For apps that sit around for a long time in the interactive state, we need
22283 // to report this at least once a day so they don't go idle.
22284 maybeUpdateUsageStatsLocked(app, nowElapsed);
22287 if (changes != 0) {
22288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22289 "Changes in " + app + ": " + changes);
22290 int i = mPendingProcessChanges.size()-1;
22291 ProcessChangeItem item = null;
22293 item = mPendingProcessChanges.get(i);
22294 if (item.pid == app.pid) {
22295 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22296 "Re-using existing item: " + item);
22302 // No existing item in pending changes; need a new one.
22303 final int NA = mAvailProcessChanges.size();
22305 item = mAvailProcessChanges.remove(NA-1);
22306 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22307 "Retrieving available item: " + item);
22309 item = new ProcessChangeItem();
22310 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22311 "Allocating new item: " + item);
22314 item.pid = app.pid;
22315 item.uid = app.info.uid;
22316 if (mPendingProcessChanges.size() == 0) {
22317 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22318 "*** Enqueueing dispatch processes changed!");
22319 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22321 mPendingProcessChanges.add(item);
22323 item.changes |= changes;
22324 item.foregroundActivities = app.repForegroundActivities;
22325 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22326 "Item " + Integer.toHexString(System.identityHashCode(item))
22327 + " " + app.toShortString() + ": changes=" + item.changes
22328 + " foreground=" + item.foregroundActivities
22329 + " type=" + app.adjType + " source=" + app.adjSource
22330 + " target=" + app.adjTarget);
22336 private boolean isEphemeralLocked(int uid) {
22337 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22338 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22341 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22346 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22347 final UidRecord.ChangeItem pendingChange;
22348 if (uidRec == null || uidRec.pendingChange == null) {
22349 if (mPendingUidChanges.size() == 0) {
22350 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22351 "*** Enqueueing dispatch uid changed!");
22352 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22354 final int NA = mAvailUidChanges.size();
22356 pendingChange = mAvailUidChanges.remove(NA-1);
22357 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22358 "Retrieving available item: " + pendingChange);
22360 pendingChange = new UidRecord.ChangeItem();
22361 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22362 "Allocating new item: " + pendingChange);
22364 if (uidRec != null) {
22365 uidRec.pendingChange = pendingChange;
22366 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22367 // If this uid is going away, and we haven't yet reported it is gone,
22369 change |= UidRecord.CHANGE_IDLE;
22371 } else if (uid < 0) {
22372 throw new IllegalArgumentException("No UidRecord or uid");
22374 pendingChange.uidRecord = uidRec;
22375 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22376 mPendingUidChanges.add(pendingChange);
22378 pendingChange = uidRec.pendingChange;
22379 // If there is no change in idle or active state, then keep whatever was pending.
22380 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22381 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22382 | UidRecord.CHANGE_ACTIVE));
22384 // If there is no change in cached or uncached state, then keep whatever was pending.
22385 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22386 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22387 | UidRecord.CHANGE_UNCACHED));
22389 // If this is a report of the UID being gone, then we shouldn't keep any previous
22390 // report of it being active or cached. (That is, a gone uid is never active,
22391 // and never cached.)
22392 if ((change & UidRecord.CHANGE_GONE) != 0) {
22393 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22394 if (!uidRec.idle) {
22395 // If this uid is going away, and we haven't yet reported it is gone,
22397 change |= UidRecord.CHANGE_IDLE;
22401 pendingChange.change = change;
22402 pendingChange.processState = uidRec != null
22403 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22404 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22405 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22406 if (uidRec != null) {
22407 uidRec.lastReportedChange = change;
22408 uidRec.updateLastDispatchedProcStateSeq(change);
22411 // Directly update the power manager, since we sit on top of it and it is critical
22412 // it be kept in sync (so wake locks will be held as soon as appropriate).
22413 if (mLocalPowerManager != null) {
22414 // TO DO: dispatch cached/uncached changes here, so we don't need to report
22415 // all proc state changes.
22416 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22417 mLocalPowerManager.uidActive(pendingChange.uid);
22419 if ((change & UidRecord.CHANGE_IDLE) != 0) {
22420 mLocalPowerManager.uidIdle(pendingChange.uid);
22422 if ((change & UidRecord.CHANGE_GONE) != 0) {
22423 mLocalPowerManager.uidGone(pendingChange.uid);
22425 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22426 pendingChange.processState);
22431 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22432 String authority) {
22433 if (app == null) return;
22434 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22435 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22436 if (userState == null) return;
22437 final long now = SystemClock.elapsedRealtime();
22438 Long lastReported = userState.mProviderLastReportedFg.get(authority);
22439 if (lastReported == null || lastReported < now - 60 * 1000L) {
22440 if (mSystemReady) {
22441 // Cannot touch the user stats if not system ready
22442 mUsageStatsService.reportContentProviderUsage(
22443 authority, providerPkgName, app.userId);
22445 userState.mProviderLastReportedFg.put(authority, now);
22450 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22451 if (DEBUG_USAGE_STATS) {
22452 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22453 + "] state changes: old = " + app.setProcState + ", new = "
22454 + app.curProcState);
22456 if (mUsageStatsService == null) {
22459 boolean isInteraction;
22460 // To avoid some abuse patterns, we are going to be careful about what we consider
22461 // to be an app interaction. Being the top activity doesn't count while the display
22462 // is sleeping, nor do short foreground services.
22463 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22464 isInteraction = true;
22465 app.fgInteractionTime = 0;
22466 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22467 if (app.fgInteractionTime == 0) {
22468 app.fgInteractionTime = nowElapsed;
22469 isInteraction = false;
22471 isInteraction = nowElapsed > app.fgInteractionTime
22472 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22475 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22476 app.fgInteractionTime = 0;
22478 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22479 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22480 app.interactionEventTime = nowElapsed;
22481 String[] packages = app.getPackageList();
22482 if (packages != null) {
22483 for (int i = 0; i < packages.length; i++) {
22484 mUsageStatsService.reportEvent(packages[i], app.userId,
22485 UsageEvents.Event.SYSTEM_INTERACTION);
22489 app.reportedInteraction = isInteraction;
22490 if (!isInteraction) {
22491 app.interactionEventTime = 0;
22495 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22496 if (proc.thread != null) {
22497 if (proc.baseProcessTracker != null) {
22498 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22503 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22504 ProcessRecord TOP_APP, boolean doingAll, long now) {
22505 if (app.thread == null) {
22509 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22511 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22514 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22516 if (isForeground != proc.foregroundServices) {
22517 proc.foregroundServices = isForeground;
22518 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22520 if (isForeground) {
22521 if (curProcs == null) {
22522 curProcs = new ArrayList<ProcessRecord>();
22523 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22525 if (!curProcs.contains(proc)) {
22526 curProcs.add(proc);
22527 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22528 proc.info.packageName, proc.info.uid);
22531 if (curProcs != null) {
22532 if (curProcs.remove(proc)) {
22533 mBatteryStatsService.noteEvent(
22534 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22535 proc.info.packageName, proc.info.uid);
22536 if (curProcs.size() <= 0) {
22537 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22543 updateOomAdjLocked();
22548 private final ActivityRecord resumedAppLocked() {
22549 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22553 pkg = act.packageName;
22554 uid = act.info.applicationInfo.uid;
22559 // Has the UID or resumed package name changed?
22560 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22561 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22562 if (mCurResumedPackage != null) {
22563 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22564 mCurResumedPackage, mCurResumedUid);
22566 mCurResumedPackage = pkg;
22567 mCurResumedUid = uid;
22568 if (mCurResumedPackage != null) {
22569 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22570 mCurResumedPackage, mCurResumedUid);
22577 * Update OomAdj for a specific process.
22578 * @param app The process to update
22579 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22580 * if necessary, or skip.
22581 * @return whether updateOomAdjLocked(app) was successful.
22583 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22584 final ActivityRecord TOP_ACT = resumedAppLocked();
22585 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22586 final boolean wasCached = app.cached;
22590 // This is the desired cached adjusment we want to tell it to use.
22591 // If our app is currently cached, we know it, and that is it. Otherwise,
22592 // we don't know it yet, and it needs to now be cached we will then
22593 // need to do a complete oom adj.
22594 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22595 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22596 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22597 SystemClock.uptimeMillis());
22599 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22600 // Changed to/from cached state, so apps after it in the LRU
22601 // list may also be changed.
22602 updateOomAdjLocked();
22607 final void updateOomAdjLocked() {
22608 final ActivityRecord TOP_ACT = resumedAppLocked();
22609 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22610 final long now = SystemClock.uptimeMillis();
22611 final long nowElapsed = SystemClock.elapsedRealtime();
22612 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22613 final int N = mLruProcesses.size();
22616 RuntimeException e = new RuntimeException();
22617 e.fillInStackTrace();
22618 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22621 // Reset state in all uid records.
22622 for (int i=mActiveUids.size()-1; i>=0; i--) {
22623 final UidRecord uidRec = mActiveUids.valueAt(i);
22624 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22625 "Starting update of " + uidRec);
22629 mStackSupervisor.rankTaskLayersIfNeeded();
22632 mNewNumServiceProcs = 0;
22633 mNewNumAServiceProcs = 0;
22635 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22636 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22638 // Let's determine how many processes we have running vs.
22639 // how many slots we have for background processes; we may want
22640 // to put multiple processes in a slot of there are enough of
22642 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22643 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22644 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22645 if (numEmptyProcs > cachedProcessLimit) {
22646 // If there are more empty processes than our limit on cached
22647 // processes, then use the cached process limit for the factor.
22648 // This ensures that the really old empty processes get pushed
22649 // down to the bottom, so if we are running low on memory we will
22650 // have a better chance at keeping around more cached processes
22651 // instead of a gazillion empty processes.
22652 numEmptyProcs = cachedProcessLimit;
22654 int emptyFactor = numEmptyProcs/numSlots;
22655 if (emptyFactor < 1) emptyFactor = 1;
22656 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22657 if (cachedFactor < 1) cachedFactor = 1;
22658 int stepCached = 0;
22662 int numTrimming = 0;
22664 mNumNonCachedProcs = 0;
22665 mNumCachedHiddenProcs = 0;
22667 // First update the OOM adjustment for each of the
22668 // application processes based on their current state.
22669 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22670 int nextCachedAdj = curCachedAdj+1;
22671 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22672 int nextEmptyAdj = curEmptyAdj+2;
22673 for (int i=N-1; i>=0; i--) {
22674 ProcessRecord app = mLruProcesses.get(i);
22675 if (!app.killedByAm && app.thread != null) {
22676 app.procStateChanged = false;
22677 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22679 // If we haven't yet assigned the final cached adj
22680 // to the process, do that now.
22681 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22682 switch (app.curProcState) {
22683 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22684 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22685 // This process is a cached process holding activities...
22686 // assign it the next cached value for that type, and then
22687 // step that cached level.
22688 app.curRawAdj = curCachedAdj;
22689 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22690 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22691 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22693 if (curCachedAdj != nextCachedAdj) {
22695 if (stepCached >= cachedFactor) {
22697 curCachedAdj = nextCachedAdj;
22698 nextCachedAdj += 2;
22699 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22700 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22706 // For everything else, assign next empty cached process
22707 // level and bump that up. Note that this means that
22708 // long-running services that have dropped down to the
22709 // cached level will be treated as empty (since their process
22710 // state is still as a service), which is what we want.
22711 app.curRawAdj = curEmptyAdj;
22712 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22713 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22714 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22716 if (curEmptyAdj != nextEmptyAdj) {
22718 if (stepEmpty >= emptyFactor) {
22720 curEmptyAdj = nextEmptyAdj;
22722 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22723 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22731 applyOomAdjLocked(app, true, now, nowElapsed);
22733 // Count the number of process types.
22734 switch (app.curProcState) {
22735 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22736 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22737 mNumCachedHiddenProcs++;
22739 if (numCached > cachedProcessLimit) {
22740 app.kill("cached #" + numCached, true);
22743 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22744 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22745 && app.lastActivityTime < oldTime) {
22746 app.kill("empty for "
22747 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22748 / 1000) + "s", true);
22751 if (numEmpty > emptyProcessLimit) {
22752 app.kill("empty #" + numEmpty, true);
22757 mNumNonCachedProcs++;
22761 if (app.isolated && app.services.size() <= 0) {
22762 // If this is an isolated process, and there are no
22763 // services running in it, then the process is no longer
22764 // needed. We agressively kill these because we can by
22765 // definition not re-use the same process again, and it is
22766 // good to avoid having whatever code was running in them
22767 // left sitting around after no longer needed.
22768 app.kill("isolated not needed", true);
22770 // Keeping this process, update its uid.
22771 final UidRecord uidRec = app.uidRecord;
22772 if (uidRec != null) {
22773 uidRec.ephemeral = app.info.isInstantApp();
22774 if (uidRec.curProcState > app.curProcState) {
22775 uidRec.curProcState = app.curProcState;
22777 if (app.foregroundServices) {
22778 uidRec.foregroundServices = true;
22783 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22784 && !app.killedByAm) {
22790 incrementProcStateSeqAndNotifyAppsLocked();
22792 mNumServiceProcs = mNewNumServiceProcs;
22794 // Now determine the memory trimming level of background processes.
22795 // Unfortunately we need to start at the back of the list to do this
22796 // properly. We only do this if the number of background apps we
22797 // are managing to keep around is less than half the maximum we desire;
22798 // if we are keeping a good number around, we'll let them use whatever
22799 // memory they want.
22800 final int numCachedAndEmpty = numCached + numEmpty;
22802 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22803 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22804 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22805 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22806 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22807 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22809 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22812 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22814 // We always allow the memory level to go up (better). We only allow it to go
22815 // down if we are in a state where that is allowed, *and* the total number of processes
22816 // has gone down since last time.
22817 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22818 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22819 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22820 if (memFactor > mLastMemoryLevel) {
22821 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22822 memFactor = mLastMemoryLevel;
22823 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22826 if (memFactor != mLastMemoryLevel) {
22827 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22829 mLastMemoryLevel = memFactor;
22830 mLastNumProcesses = mLruProcesses.size();
22831 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22832 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22833 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22834 if (mLowRamStartTime == 0) {
22835 mLowRamStartTime = now;
22839 switch (memFactor) {
22840 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22841 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22843 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22844 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22847 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22850 int factor = numTrimming/3;
22852 if (mHomeProcess != null) minFactor++;
22853 if (mPreviousProcess != null) minFactor++;
22854 if (factor < minFactor) factor = minFactor;
22855 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22856 for (int i=N-1; i>=0; i--) {
22857 ProcessRecord app = mLruProcesses.get(i);
22858 if (allChanged || app.procStateChanged) {
22859 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22860 app.procStateChanged = false;
22862 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22863 && !app.killedByAm) {
22864 if (app.trimMemoryLevel < curLevel && app.thread != null) {
22866 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22867 "Trimming memory of " + app.processName + " to " + curLevel);
22868 app.thread.scheduleTrimMemory(curLevel);
22869 } catch (RemoteException e) {
22872 // For now we won't do this; our memory trimming seems
22873 // to be good enough at this point that destroying
22874 // activities causes more harm than good.
22875 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22876 && app != mHomeProcess && app != mPreviousProcess) {
22877 // Need to do this on its own message because the stack may not
22878 // be in a consistent state at this point.
22879 // For these apps we will also finish their activities
22880 // to help them free memory.
22881 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22885 app.trimMemoryLevel = curLevel;
22887 if (step >= factor) {
22889 switch (curLevel) {
22890 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22891 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22893 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22894 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22898 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22899 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22900 && app.thread != null) {
22902 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22903 "Trimming memory of heavy-weight " + app.processName
22904 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22905 app.thread.scheduleTrimMemory(
22906 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22907 } catch (RemoteException e) {
22910 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22912 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22913 || app.systemNoUi) && app.pendingUiClean) {
22914 // If this application is now in the background and it
22915 // had done UI, then give it the special trim level to
22916 // have it free UI resources.
22917 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22918 if (app.trimMemoryLevel < level && app.thread != null) {
22920 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22921 "Trimming memory of bg-ui " + app.processName
22923 app.thread.scheduleTrimMemory(level);
22924 } catch (RemoteException e) {
22927 app.pendingUiClean = false;
22929 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22931 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22932 "Trimming memory of fg " + app.processName
22933 + " to " + fgTrimLevel);
22934 app.thread.scheduleTrimMemory(fgTrimLevel);
22935 } catch (RemoteException e) {
22938 app.trimMemoryLevel = fgTrimLevel;
22942 if (mLowRamStartTime != 0) {
22943 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22944 mLowRamStartTime = 0;
22946 for (int i=N-1; i>=0; i--) {
22947 ProcessRecord app = mLruProcesses.get(i);
22948 if (allChanged || app.procStateChanged) {
22949 setProcessTrackerStateLocked(app, trackerMemFactor, now);
22950 app.procStateChanged = false;
22952 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22953 || app.systemNoUi) && app.pendingUiClean) {
22954 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22955 && app.thread != null) {
22957 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22958 "Trimming memory of ui hidden " + app.processName
22959 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22960 app.thread.scheduleTrimMemory(
22961 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22962 } catch (RemoteException e) {
22965 app.pendingUiClean = false;
22967 app.trimMemoryLevel = 0;
22971 if (mAlwaysFinishActivities) {
22972 // Need to do this on its own message because the stack may not
22973 // be in a consistent state at this point.
22974 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22978 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22981 ArrayList<UidRecord> becameIdle = null;
22983 // Update from any uid changes.
22984 if (mLocalPowerManager != null) {
22985 mLocalPowerManager.startUidChanges();
22987 for (int i=mActiveUids.size()-1; i>=0; i--) {
22988 final UidRecord uidRec = mActiveUids.valueAt(i);
22989 int uidChange = UidRecord.CHANGE_PROCSTATE;
22990 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22991 && (uidRec.setProcState != uidRec.curProcState
22992 || uidRec.setWhitelist != uidRec.curWhitelist)) {
22993 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22994 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22995 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22996 + " to " + uidRec.curWhitelist);
22997 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22998 && !uidRec.curWhitelist) {
22999 // UID is now in the background (and not on the temp whitelist). Was it
23000 // previously in the foreground (or on the temp whitelist)?
23001 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
23002 || uidRec.setWhitelist) {
23003 uidRec.lastBackgroundTime = nowElapsed;
23004 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
23005 // Note: the background settle time is in elapsed realtime, while
23006 // the handler time base is uptime. All this means is that we may
23007 // stop background uids later than we had intended, but that only
23008 // happens because the device was sleeping so we are okay anyway.
23009 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23010 mConstants.BACKGROUND_SETTLE_TIME);
23013 if (uidRec.idle && !uidRec.setIdle) {
23014 uidChange = UidRecord.CHANGE_IDLE;
23015 if (becameIdle == null) {
23016 becameIdle = new ArrayList<>();
23018 becameIdle.add(uidRec);
23022 uidChange = UidRecord.CHANGE_ACTIVE;
23023 EventLogTags.writeAmUidActive(uidRec.uid);
23024 uidRec.idle = false;
23026 uidRec.lastBackgroundTime = 0;
23028 final boolean wasCached = uidRec.setProcState
23029 > ActivityManager.PROCESS_STATE_RECEIVER;
23030 final boolean isCached = uidRec.curProcState
23031 > ActivityManager.PROCESS_STATE_RECEIVER;
23032 if (wasCached != isCached ||
23033 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
23034 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
23036 uidRec.setProcState = uidRec.curProcState;
23037 uidRec.setWhitelist = uidRec.curWhitelist;
23038 uidRec.setIdle = uidRec.idle;
23039 enqueueUidChangeLocked(uidRec, -1, uidChange);
23040 noteUidProcessState(uidRec.uid, uidRec.curProcState);
23041 if (uidRec.foregroundServices) {
23042 mServices.foregroundServiceProcStateChangedLocked(uidRec);
23046 if (mLocalPowerManager != null) {
23047 mLocalPowerManager.finishUidChanges();
23050 if (becameIdle != null) {
23051 // If we have any new uids that became idle this time, we need to make sure
23052 // they aren't left with running services.
23053 for (int i = becameIdle.size() - 1; i >= 0; i--) {
23054 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
23058 if (mProcessStats.shouldWriteNowLocked(now)) {
23059 mHandler.post(new Runnable() {
23060 @Override public void run() {
23061 synchronized (ActivityManagerService.this) {
23062 mProcessStats.writeStateAsyncLocked();
23068 if (DEBUG_OOM_ADJ) {
23069 final long duration = SystemClock.uptimeMillis() - now;
23071 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23072 new RuntimeException("here").fillInStackTrace());
23074 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23080 public void makePackageIdle(String packageName, int userId) {
23081 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23082 != PackageManager.PERMISSION_GRANTED) {
23083 String msg = "Permission Denial: makePackageIdle() from pid="
23084 + Binder.getCallingPid()
23085 + ", uid=" + Binder.getCallingUid()
23086 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23088 throw new SecurityException(msg);
23090 final int callingPid = Binder.getCallingPid();
23091 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23092 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23093 long callingId = Binder.clearCallingIdentity();
23094 synchronized(this) {
23096 IPackageManager pm = AppGlobals.getPackageManager();
23099 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23100 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23101 } catch (RemoteException e) {
23103 if (pkgUid == -1) {
23104 throw new IllegalArgumentException("Unknown package name " + packageName);
23107 if (mLocalPowerManager != null) {
23108 mLocalPowerManager.startUidChanges();
23110 final int appId = UserHandle.getAppId(pkgUid);
23111 final int N = mActiveUids.size();
23112 for (int i=N-1; i>=0; i--) {
23113 final UidRecord uidRec = mActiveUids.valueAt(i);
23114 final long bgTime = uidRec.lastBackgroundTime;
23115 if (bgTime > 0 && !uidRec.idle) {
23116 if (UserHandle.getAppId(uidRec.uid) == appId) {
23117 if (userId == UserHandle.USER_ALL ||
23118 userId == UserHandle.getUserId(uidRec.uid)) {
23119 EventLogTags.writeAmUidIdle(uidRec.uid);
23120 uidRec.idle = true;
23121 uidRec.setIdle = true;
23122 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23123 + " from package " + packageName + " user " + userId);
23124 doStopUidLocked(uidRec.uid, uidRec);
23130 if (mLocalPowerManager != null) {
23131 mLocalPowerManager.finishUidChanges();
23133 Binder.restoreCallingIdentity(callingId);
23138 final void idleUids() {
23139 synchronized (this) {
23140 final int N = mActiveUids.size();
23144 final long nowElapsed = SystemClock.elapsedRealtime();
23145 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23147 if (mLocalPowerManager != null) {
23148 mLocalPowerManager.startUidChanges();
23150 for (int i=N-1; i>=0; i--) {
23151 final UidRecord uidRec = mActiveUids.valueAt(i);
23152 final long bgTime = uidRec.lastBackgroundTime;
23153 if (bgTime > 0 && !uidRec.idle) {
23154 if (bgTime <= maxBgTime) {
23155 EventLogTags.writeAmUidIdle(uidRec.uid);
23156 uidRec.idle = true;
23157 uidRec.setIdle = true;
23158 doStopUidLocked(uidRec.uid, uidRec);
23160 if (nextTime == 0 || nextTime > bgTime) {
23166 if (mLocalPowerManager != null) {
23167 mLocalPowerManager.finishUidChanges();
23169 if (nextTime > 0) {
23170 mHandler.removeMessages(IDLE_UIDS_MSG);
23171 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23172 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23178 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23179 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23180 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23184 void incrementProcStateSeqAndNotifyAppsLocked() {
23185 if (mWaitForNetworkTimeoutMs <= 0) {
23188 // Used for identifying which uids need to block for network.
23189 ArrayList<Integer> blockingUids = null;
23190 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23191 final UidRecord uidRec = mActiveUids.valueAt(i);
23192 // If the network is not restricted for uid, then nothing to do here.
23193 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23196 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23199 // If process state is not changed, then there's nothing to do.
23200 if (uidRec.setProcState == uidRec.curProcState) {
23203 final int blockState = getBlockStateForUid(uidRec);
23204 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23205 // there's nothing the app needs to do in this scenario.
23206 if (blockState == NETWORK_STATE_NO_CHANGE) {
23209 synchronized (uidRec.networkStateLock) {
23210 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23211 if (blockState == NETWORK_STATE_BLOCK) {
23212 if (blockingUids == null) {
23213 blockingUids = new ArrayList<>();
23215 blockingUids.add(uidRec.uid);
23217 if (DEBUG_NETWORK) {
23218 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23219 + " threads for uid: " + uidRec);
23221 if (uidRec.waitingForNetwork) {
23222 uidRec.networkStateLock.notifyAll();
23228 // There are no uids that need to block, so nothing more to do.
23229 if (blockingUids == null) {
23233 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23234 final ProcessRecord app = mLruProcesses.get(i);
23235 if (!blockingUids.contains(app.uid)) {
23238 if (!app.killedByAm && app.thread != null) {
23239 final UidRecord uidRec = mActiveUids.get(app.uid);
23241 if (DEBUG_NETWORK) {
23242 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23245 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23246 } catch (RemoteException ignored) {
23253 * Checks if the uid is coming from background to foreground or vice versa and returns
23254 * appropriate block state based on this.
23256 * @return blockState based on whether the uid is coming from background to foreground or
23257 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23258 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23259 * {@link #NETWORK_STATE_NO_CHANGE}.
23262 int getBlockStateForUid(UidRecord uidRec) {
23263 // Denotes whether uid's process state is currently allowed network access.
23264 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23265 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23266 // Denotes whether uid's process state was previously allowed network access.
23267 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23268 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23270 // When the uid is coming to foreground, AMS should inform the app thread that it should
23271 // block for the network rules to get updated before launching an activity.
23272 if (!wasAllowed && isAllowed) {
23273 return NETWORK_STATE_BLOCK;
23275 // When the uid is going to background, AMS should inform the app thread that if an
23276 // activity launch is blocked for the network rules to get updated, it should be unblocked.
23277 if (wasAllowed && !isAllowed) {
23278 return NETWORK_STATE_UNBLOCK;
23280 return NETWORK_STATE_NO_CHANGE;
23283 final void runInBackgroundDisabled(int uid) {
23284 synchronized (this) {
23285 UidRecord uidRec = mActiveUids.get(uid);
23286 if (uidRec != null) {
23287 // This uid is actually running... should it be considered background now?
23289 doStopUidLocked(uidRec.uid, uidRec);
23292 // This uid isn't actually running... still send a report about it being "stopped".
23293 doStopUidLocked(uid, null);
23298 final void doStopUidLocked(int uid, final UidRecord uidRec) {
23299 mServices.stopInBackgroundLocked(uid);
23300 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23304 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23306 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23307 long duration, String tag) {
23308 if (DEBUG_WHITELISTS) {
23309 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23310 + targetUid + ", " + duration + ")");
23313 synchronized (mPidsSelfLocked) {
23314 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23316 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23320 if (!pr.whitelistManager) {
23321 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23322 != PackageManager.PERMISSION_GRANTED) {
23323 if (DEBUG_WHITELISTS) {
23324 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23325 + ": pid " + callerPid + " is not allowed");
23332 tempWhitelistUidLocked(targetUid, duration, tag);
23336 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23338 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23339 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23340 setUidTempWhitelistStateLocked(targetUid, true);
23341 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23344 void pushTempWhitelist() {
23346 final PendingTempWhitelist[] list;
23348 // First copy out the pending changes... we need to leave them in the map for now,
23349 // in case someone needs to check what is coming up while we don't have the lock held.
23350 synchronized(this) {
23351 N = mPendingTempWhitelist.size();
23352 list = new PendingTempWhitelist[N];
23353 for (int i = 0; i < N; i++) {
23354 list[i] = mPendingTempWhitelist.valueAt(i);
23358 // Now safely dispatch changes to device idle controller.
23359 for (int i = 0; i < N; i++) {
23360 PendingTempWhitelist ptw = list[i];
23361 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23362 ptw.duration, true, ptw.tag);
23365 // And now we can safely remove them from the map.
23366 synchronized(this) {
23367 for (int i = 0; i < N; i++) {
23368 PendingTempWhitelist ptw = list[i];
23369 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23370 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23371 mPendingTempWhitelist.removeAt(index);
23377 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23378 boolean changed = false;
23379 for (int i=mActiveUids.size()-1; i>=0; i--) {
23380 final UidRecord uidRec = mActiveUids.valueAt(i);
23381 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23382 uidRec.curWhitelist = onWhitelist;
23387 updateOomAdjLocked();
23391 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23392 boolean changed = false;
23393 final UidRecord uidRec = mActiveUids.get(uid);
23394 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23395 uidRec.curWhitelist = onWhitelist;
23396 updateOomAdjLocked();
23400 final void trimApplications() {
23401 synchronized (this) {
23404 // First remove any unused application processes whose package
23405 // has been removed.
23406 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23407 final ProcessRecord app = mRemovedProcesses.get(i);
23408 if (app.activities.size() == 0
23409 && app.curReceivers.isEmpty() && app.services.size() == 0) {
23411 TAG, "Exiting empty application process "
23412 + app.toShortString() + " ("
23413 + (app.thread != null ? app.thread.asBinder() : null)
23415 if (app.pid > 0 && app.pid != MY_PID) {
23416 app.kill("empty", false);
23419 app.thread.scheduleExit();
23420 } catch (Exception e) {
23421 // Ignore exceptions.
23424 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23425 mRemovedProcesses.remove(i);
23427 if (app.persistent) {
23428 addAppLocked(app.info, null, false, null /* ABI override */);
23433 // Now update the oom adj for all processes.
23434 updateOomAdjLocked();
23438 /** This method sends the specified signal to each of the persistent apps */
23439 public void signalPersistentProcesses(int sig) throws RemoteException {
23440 if (sig != SIGNAL_USR1) {
23441 throw new SecurityException("Only SIGNAL_USR1 is allowed");
23444 synchronized (this) {
23445 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23446 != PackageManager.PERMISSION_GRANTED) {
23447 throw new SecurityException("Requires permission "
23448 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23451 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23452 ProcessRecord r = mLruProcesses.get(i);
23453 if (r.thread != null && r.persistent) {
23454 sendSignal(r.pid, sig);
23460 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23461 if (proc == null || proc == mProfileProc) {
23462 proc = mProfileProc;
23463 profileType = mProfileType;
23464 clearProfilerLocked();
23466 if (proc == null) {
23470 proc.thread.profilerControl(false, null, profileType);
23471 } catch (RemoteException e) {
23472 throw new IllegalStateException("Process disappeared");
23476 private void clearProfilerLocked() {
23477 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23479 mProfilerInfo.profileFd.close();
23480 } catch (IOException e) {
23483 mProfileApp = null;
23484 mProfileProc = null;
23485 mProfilerInfo = null;
23488 public boolean profileControl(String process, int userId, boolean start,
23489 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23492 synchronized (this) {
23493 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23494 // its own permission.
23495 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23496 != PackageManager.PERMISSION_GRANTED) {
23497 throw new SecurityException("Requires permission "
23498 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23501 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23502 throw new IllegalArgumentException("null profile info or fd");
23505 ProcessRecord proc = null;
23506 if (process != null) {
23507 proc = findProcessLocked(process, userId, "profileControl");
23510 if (start && (proc == null || proc.thread == null)) {
23511 throw new IllegalArgumentException("Unknown process: " + process);
23515 stopProfilerLocked(null, 0);
23516 setProfileApp(proc.info, proc.processName, profilerInfo);
23517 mProfileProc = proc;
23518 mProfileType = profileType;
23519 ParcelFileDescriptor fd = profilerInfo.profileFd;
23522 } catch (IOException e) {
23525 profilerInfo.profileFd = fd;
23526 proc.thread.profilerControl(start, profilerInfo, profileType);
23529 mProfilerInfo.profileFd.close();
23530 } catch (IOException e) {
23532 mProfilerInfo.profileFd = null;
23534 stopProfilerLocked(proc, profileType);
23535 if (profilerInfo != null && profilerInfo.profileFd != null) {
23537 profilerInfo.profileFd.close();
23538 } catch (IOException e) {
23545 } catch (RemoteException e) {
23546 throw new IllegalStateException("Process disappeared");
23548 if (profilerInfo != null && profilerInfo.profileFd != null) {
23550 profilerInfo.profileFd.close();
23551 } catch (IOException e) {
23557 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23558 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23559 userId, true, ALLOW_FULL_ONLY, callName, null);
23560 ProcessRecord proc = null;
23562 int pid = Integer.parseInt(process);
23563 synchronized (mPidsSelfLocked) {
23564 proc = mPidsSelfLocked.get(pid);
23566 } catch (NumberFormatException e) {
23569 if (proc == null) {
23570 ArrayMap<String, SparseArray<ProcessRecord>> all
23571 = mProcessNames.getMap();
23572 SparseArray<ProcessRecord> procs = all.get(process);
23573 if (procs != null && procs.size() > 0) {
23574 proc = procs.valueAt(0);
23575 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23576 for (int i=1; i<procs.size(); i++) {
23577 ProcessRecord thisProc = procs.valueAt(i);
23578 if (thisProc.userId == userId) {
23590 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23591 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23594 synchronized (this) {
23595 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23596 // its own permission (same as profileControl).
23597 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23598 != PackageManager.PERMISSION_GRANTED) {
23599 throw new SecurityException("Requires permission "
23600 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23604 throw new IllegalArgumentException("null fd");
23607 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23608 if (proc == null || proc.thread == null) {
23609 throw new IllegalArgumentException("Unknown process: " + process);
23612 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23613 if (!isDebuggable) {
23614 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23615 throw new SecurityException("Process not debuggable: " + proc);
23619 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23623 } catch (RemoteException e) {
23624 throw new IllegalStateException("Process disappeared");
23629 } catch (IOException e) {
23636 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23637 String reportPackage) {
23638 if (processName != null) {
23639 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23640 "setDumpHeapDebugLimit()");
23642 synchronized (mPidsSelfLocked) {
23643 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23644 if (proc == null) {
23645 throw new SecurityException("No process found for calling pid "
23646 + Binder.getCallingPid());
23648 if (!Build.IS_DEBUGGABLE
23649 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23650 throw new SecurityException("Not running a debuggable build");
23652 processName = proc.processName;
23654 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23655 throw new SecurityException("Package " + reportPackage + " is not running in "
23660 synchronized (this) {
23661 if (maxMemSize > 0) {
23662 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23665 mMemWatchProcesses.remove(processName, uid);
23667 mMemWatchProcesses.getMap().remove(processName);
23674 public void dumpHeapFinished(String path) {
23675 synchronized (this) {
23676 if (Binder.getCallingPid() != mMemWatchDumpPid) {
23677 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23678 + " does not match last pid " + mMemWatchDumpPid);
23681 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23682 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23683 + " does not match last path " + mMemWatchDumpFile);
23686 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23687 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23689 // Forced gc to clean up the remnant hprof fd.
23690 Runtime.getRuntime().gc();
23694 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23695 public void monitor() {
23696 synchronized (this) { }
23699 void onCoreSettingsChange(Bundle settings) {
23700 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23701 ProcessRecord processRecord = mLruProcesses.get(i);
23703 if (processRecord.thread != null) {
23704 processRecord.thread.setCoreSettings(settings);
23706 } catch (RemoteException re) {
23712 // Multi-user methods
23715 * Start user, if its not already running, but don't bring it to foreground.
23718 public boolean startUserInBackground(final int userId) {
23719 return mUserController.startUser(userId, /* foreground */ false);
23723 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23724 return mUserController.unlockUser(userId, token, secret, listener);
23728 public boolean switchUser(final int targetUserId) {
23729 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23731 UserInfo targetUserInfo;
23732 synchronized (this) {
23733 currentUserId = mUserController.getCurrentUserIdLocked();
23734 targetUserInfo = mUserController.getUserInfo(targetUserId);
23735 if (targetUserId == currentUserId) {
23736 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23739 if (targetUserInfo == null) {
23740 Slog.w(TAG, "No user info for user #" + targetUserId);
23743 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23744 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23745 + " when device is in demo mode");
23748 if (!targetUserInfo.supportsSwitchTo()) {
23749 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23752 if (targetUserInfo.isManagedProfile()) {
23753 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23756 mUserController.setTargetUserIdLocked(targetUserId);
23758 if (mUserController.mUserSwitchUiEnabled) {
23759 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23760 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23761 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23762 mUiHandler.sendMessage(mHandler.obtainMessage(
23763 START_USER_SWITCH_UI_MSG, userNames));
23765 mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23766 mHandler.sendMessage(mHandler.obtainMessage(
23767 START_USER_SWITCH_FG_MSG, targetUserId, 0));
23772 void scheduleStartProfilesLocked() {
23773 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23774 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23775 DateUtils.SECOND_IN_MILLIS);
23780 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23781 return mUserController.stopUser(userId, force, callback);
23785 public UserInfo getCurrentUser() {
23786 return mUserController.getCurrentUser();
23789 String getStartedUserState(int userId) {
23790 synchronized (this) {
23791 final UserState userState = mUserController.getStartedUserStateLocked(userId);
23792 return UserState.stateToString(userState.state);
23797 public boolean isUserRunning(int userId, int flags) {
23798 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23799 && checkCallingPermission(INTERACT_ACROSS_USERS)
23800 != PackageManager.PERMISSION_GRANTED) {
23801 String msg = "Permission Denial: isUserRunning() from pid="
23802 + Binder.getCallingPid()
23803 + ", uid=" + Binder.getCallingUid()
23804 + " requires " + INTERACT_ACROSS_USERS;
23806 throw new SecurityException(msg);
23808 synchronized (this) {
23809 return mUserController.isUserRunningLocked(userId, flags);
23814 public int[] getRunningUserIds() {
23815 if (checkCallingPermission(INTERACT_ACROSS_USERS)
23816 != PackageManager.PERMISSION_GRANTED) {
23817 String msg = "Permission Denial: isUserRunning() from pid="
23818 + Binder.getCallingPid()
23819 + ", uid=" + Binder.getCallingUid()
23820 + " requires " + INTERACT_ACROSS_USERS;
23822 throw new SecurityException(msg);
23824 synchronized (this) {
23825 return mUserController.getStartedUserArrayLocked();
23830 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23831 mUserController.registerUserSwitchObserver(observer, name);
23835 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23836 mUserController.unregisterUserSwitchObserver(observer);
23839 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23840 if (info == null) return null;
23841 ApplicationInfo newInfo = new ApplicationInfo(info);
23842 newInfo.initForUser(userId);
23846 public boolean isUserStopped(int userId) {
23847 synchronized (this) {
23848 return mUserController.getStartedUserStateLocked(userId) == null;
23852 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23854 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23858 ActivityInfo info = new ActivityInfo(aInfo);
23859 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23863 private boolean processSanityChecksLocked(ProcessRecord process) {
23864 if (process == null || process.thread == null) {
23868 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23869 if (!isDebuggable) {
23870 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23878 public boolean startBinderTracking() throws RemoteException {
23879 synchronized (this) {
23880 mBinderTransactionTrackingEnabled = true;
23881 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23882 // permission (same as profileControl).
23883 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23884 != PackageManager.PERMISSION_GRANTED) {
23885 throw new SecurityException("Requires permission "
23886 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23889 for (int i = 0; i < mLruProcesses.size(); i++) {
23890 ProcessRecord process = mLruProcesses.get(i);
23891 if (!processSanityChecksLocked(process)) {
23895 process.thread.startBinderTracking();
23896 } catch (RemoteException e) {
23897 Log.v(TAG, "Process disappared");
23904 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23906 synchronized (this) {
23907 mBinderTransactionTrackingEnabled = false;
23908 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23909 // permission (same as profileControl).
23910 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23911 != PackageManager.PERMISSION_GRANTED) {
23912 throw new SecurityException("Requires permission "
23913 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23917 throw new IllegalArgumentException("null fd");
23920 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23921 pw.println("Binder transaction traces for all processes.\n");
23922 for (ProcessRecord process : mLruProcesses) {
23923 if (!processSanityChecksLocked(process)) {
23927 pw.println("Traces for process: " + process.processName);
23930 TransferPipe tp = new TransferPipe();
23932 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23933 tp.go(fd.getFileDescriptor());
23937 } catch (IOException e) {
23938 pw.println("Failure while dumping IPC traces from " + process +
23939 ". Exception: " + e);
23941 } catch (RemoteException e) {
23942 pw.println("Got a RemoteException while dumping IPC traces from " +
23943 process + ". Exception: " + e);
23954 } catch (IOException e) {
23961 final class LocalService extends ActivityManagerInternal {
23963 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23964 int targetUserId) {
23965 synchronized (ActivityManagerService.this) {
23966 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23967 targetPkg, intent, null, targetUserId);
23972 public String checkContentProviderAccess(String authority, int userId) {
23973 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23977 public void onWakefulnessChanged(int wakefulness) {
23978 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23982 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23983 String processName, String abiOverride, int uid, Runnable crashHandler) {
23984 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23985 processName, abiOverride, uid, crashHandler);
23989 public SleepToken acquireSleepToken(String tag, int displayId) {
23990 Preconditions.checkNotNull(tag);
23991 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23995 public ComponentName getHomeActivityForUser(int userId) {
23996 synchronized (ActivityManagerService.this) {
23997 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23998 return homeActivity == null ? null : homeActivity.realActivity;
24003 public void onUserRemoved(int userId) {
24004 synchronized (ActivityManagerService.this) {
24005 ActivityManagerService.this.onUserStoppedLocked(userId);
24007 mBatteryStatsService.onUserRemoved(userId);
24011 public void onLocalVoiceInteractionStarted(IBinder activity,
24012 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
24013 synchronized (ActivityManagerService.this) {
24014 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
24015 voiceSession, voiceInteractor);
24020 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
24021 synchronized (ActivityManagerService.this) {
24022 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
24023 reasons, timestamp);
24028 public void notifyAppTransitionFinished() {
24029 synchronized (ActivityManagerService.this) {
24030 mStackSupervisor.notifyAppTransitionDone();
24035 public void notifyAppTransitionCancelled() {
24036 synchronized (ActivityManagerService.this) {
24037 mStackSupervisor.notifyAppTransitionDone();
24042 public List<IBinder> getTopVisibleActivities() {
24043 synchronized (ActivityManagerService.this) {
24044 return mStackSupervisor.getTopVisibleActivities();
24049 public void notifyDockedStackMinimizedChanged(boolean minimized) {
24050 synchronized (ActivityManagerService.this) {
24051 mStackSupervisor.setDockedStackMinimized(minimized);
24056 public void killForegroundAppsForUser(int userHandle) {
24057 synchronized (ActivityManagerService.this) {
24058 final ArrayList<ProcessRecord> procs = new ArrayList<>();
24059 final int NP = mProcessNames.getMap().size();
24060 for (int ip = 0; ip < NP; ip++) {
24061 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
24062 final int NA = apps.size();
24063 for (int ia = 0; ia < NA; ia++) {
24064 final ProcessRecord app = apps.valueAt(ia);
24065 if (app.persistent) {
24066 // We don't kill persistent processes.
24071 } else if (app.userId == userHandle && app.foregroundActivities) {
24072 app.removed = true;
24078 final int N = procs.size();
24079 for (int i = 0; i < N; i++) {
24080 removeProcessLocked(procs.get(i), false, true, "kill all fg");
24086 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24088 if (!(target instanceof PendingIntentRecord)) {
24089 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24092 synchronized (ActivityManagerService.this) {
24093 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24098 public void setDeviceIdleWhitelist(int[] appids) {
24099 synchronized (ActivityManagerService.this) {
24100 mDeviceIdleWhitelist = appids;
24105 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24106 synchronized (ActivityManagerService.this) {
24107 mDeviceIdleTempWhitelist = appids;
24108 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24113 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24115 Preconditions.checkNotNull(values, "Configuration must not be null");
24116 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24117 synchronized (ActivityManagerService.this) {
24118 updateConfigurationLocked(values, null, false, true, userId,
24119 false /* deferResume */);
24124 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24126 Preconditions.checkNotNull(intents, "intents");
24127 final String[] resolvedTypes = new String[intents.length];
24128 for (int i = 0; i < intents.length; i++) {
24129 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24132 // UID of the package on user userId.
24133 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24134 // packageUid may not be initialized.
24135 int packageUid = 0;
24137 packageUid = AppGlobals.getPackageManager().getPackageUid(
24138 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24139 } catch (RemoteException e) {
24140 // Shouldn't happen.
24143 synchronized (ActivityManagerService.this) {
24144 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24145 /*resultTo*/ null, bOptions, userId);
24150 public int getUidProcessState(int uid) {
24151 return getUidState(uid);
24155 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24156 synchronized (ActivityManagerService.this) {
24158 // We might change the visibilities here, so prepare an empty app transition which
24159 // might be overridden later if we actually change visibilities.
24160 final boolean wasTransitionSet =
24161 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24162 if (!wasTransitionSet) {
24163 mWindowManager.prepareAppTransition(TRANSIT_NONE,
24164 false /* alwaysKeepCurrent */);
24166 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24168 // If there was a transition set already we don't want to interfere with it as we
24169 // might be starting it too early.
24170 if (!wasTransitionSet) {
24171 mWindowManager.executeAppTransition();
24174 if (callback != null) {
24180 public boolean isSystemReady() {
24181 // no need to synchronize(this) just to read & return the value
24182 return mSystemReady;
24186 public void notifyKeyguardTrustedChanged() {
24187 synchronized (ActivityManagerService.this) {
24188 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24189 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24195 * Sets if the given pid has an overlay UI or not.
24197 * @param pid The pid we are setting overlay UI for.
24198 * @param hasOverlayUi True if the process has overlay UI.
24199 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24202 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24203 synchronized (ActivityManagerService.this) {
24204 final ProcessRecord pr;
24205 synchronized (mPidsSelfLocked) {
24206 pr = mPidsSelfLocked.get(pid);
24208 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24212 if (pr.hasOverlayUi == hasOverlayUi) {
24215 pr.hasOverlayUi = hasOverlayUi;
24216 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24217 updateOomAdjLocked(pr, true);
24222 * Called after the network policy rules are updated by
24223 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24224 * and {@param procStateSeq}.
24227 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24228 if (DEBUG_NETWORK) {
24229 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24230 + uid + " seq: " + procStateSeq);
24233 synchronized (ActivityManagerService.this) {
24234 record = mActiveUids.get(uid);
24235 if (record == null) {
24236 if (DEBUG_NETWORK) {
24237 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24238 + " procStateSeq: " + procStateSeq);
24243 synchronized (record.networkStateLock) {
24244 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24245 if (DEBUG_NETWORK) {
24246 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24247 + " been handled for uid: " + uid);
24251 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24252 if (record.curProcStateSeq > procStateSeq) {
24253 if (DEBUG_NETWORK) {
24254 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24255 + ", curProcstateSeq: " + record.curProcStateSeq
24256 + ", procStateSeq: " + procStateSeq);
24260 if (record.waitingForNetwork) {
24261 if (DEBUG_NETWORK) {
24262 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24263 + ", procStateSeq: " + procStateSeq);
24265 record.networkStateLock.notifyAll();
24271 * Called after virtual display Id is updated by
24272 * {@link com.android.server.vr.Vr2dDisplay} with a specific
24273 * {@param vrVr2dDisplayId}.
24276 public void setVr2dDisplayId(int vr2dDisplayId) {
24278 Slog.d(TAG, "setVr2dDisplayId called for: " +
24281 synchronized (ActivityManagerService.this) {
24282 mVr2dDisplayId = vr2dDisplayId;
24287 public void saveANRState(String reason) {
24288 synchronized (ActivityManagerService.this) {
24289 final StringWriter sw = new StringWriter();
24290 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24291 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24292 if (reason != null) {
24293 pw.println(" Reason: " + reason);
24296 mActivityStarter.dump(pw, " ", null);
24298 pw.println("-------------------------------------------------------------------------------");
24299 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24300 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24305 mLastANRState = sw.toString();
24310 public void clearSavedANRState() {
24311 synchronized (ActivityManagerService.this) {
24312 mLastANRState = null;
24317 public void setFocusedActivity(IBinder token) {
24318 synchronized (ActivityManagerService.this) {
24319 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24321 throw new IllegalArgumentException(
24322 "setFocusedActivity: No activity record matching token=" + token);
24324 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24325 r, "setFocusedActivity")) {
24326 mStackSupervisor.resumeFocusedStackTopActivityLocked();
24332 public void registerScreenObserver(ScreenObserver observer) {
24333 mScreenObservers.add(observer);
24338 * Called by app main thread to wait for the network policy rules to get updated.
24340 * @param procStateSeq The sequence number indicating the process state change that the main
24341 * thread is interested in.
24344 public void waitForNetworkStateUpdate(long procStateSeq) {
24345 final int callingUid = Binder.getCallingUid();
24346 if (DEBUG_NETWORK) {
24347 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24350 synchronized (this) {
24351 record = mActiveUids.get(callingUid);
24352 if (record == null) {
24356 synchronized (record.networkStateLock) {
24357 if (record.lastDispatchedProcStateSeq < procStateSeq) {
24358 if (DEBUG_NETWORK) {
24359 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24360 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24361 + " lastProcStateSeqDispatchedToObservers: "
24362 + record.lastDispatchedProcStateSeq);
24366 if (record.curProcStateSeq > procStateSeq) {
24367 if (DEBUG_NETWORK) {
24368 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24369 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24370 + ", procStateSeq: " + procStateSeq);
24374 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24375 if (DEBUG_NETWORK) {
24376 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24377 + procStateSeq + ", so no need to wait. Uid: "
24378 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24379 + record.lastNetworkUpdatedProcStateSeq);
24384 if (DEBUG_NETWORK) {
24385 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24386 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24388 final long startTime = SystemClock.uptimeMillis();
24389 record.waitingForNetwork = true;
24390 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24391 record.waitingForNetwork = false;
24392 final long totalTime = SystemClock.uptimeMillis() - startTime;
24393 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24394 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24395 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24396 + procStateSeq + " UidRec: " + record
24397 + " validateUidRec: " + mValidateUids.get(callingUid));
24399 } catch (InterruptedException e) {
24400 Thread.currentThread().interrupt();
24405 public void waitForBroadcastIdle(PrintWriter pw) {
24406 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24408 boolean idle = true;
24409 synchronized (this) {
24410 for (BroadcastQueue queue : mBroadcastQueues) {
24411 if (!queue.isIdle()) {
24412 final String msg = "Waiting for queue " + queue + " to become idle...";
24422 final String msg = "All broadcast queues are idle!";
24428 SystemClock.sleep(1000);
24434 * Return the user id of the last resumed activity.
24437 public @UserIdInt int getLastResumedActivityUserId() {
24438 enforceCallingPermission(
24439 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24440 synchronized (this) {
24441 if (mLastResumedActivity == null) {
24442 return mUserController.getCurrentUserIdLocked();
24444 return mLastResumedActivity.userId;
24449 * An implementation of IAppTask, that allows an app to manage its own tasks via
24450 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
24451 * only the process that calls getAppTasks() can call the AppTask methods.
24453 class AppTaskImpl extends IAppTask.Stub {
24454 private int mTaskId;
24455 private int mCallingUid;
24457 public AppTaskImpl(int taskId, int callingUid) {
24459 mCallingUid = callingUid;
24462 private void checkCaller() {
24463 if (mCallingUid != Binder.getCallingUid()) {
24464 throw new SecurityException("Caller " + mCallingUid
24465 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24470 public void finishAndRemoveTask() {
24473 synchronized (ActivityManagerService.this) {
24474 long origId = Binder.clearCallingIdentity();
24476 // We remove the task from recents to preserve backwards
24477 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24478 REMOVE_FROM_RECENTS)) {
24479 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24482 Binder.restoreCallingIdentity(origId);
24488 public ActivityManager.RecentTaskInfo getTaskInfo() {
24491 synchronized (ActivityManagerService.this) {
24492 long origId = Binder.clearCallingIdentity();
24494 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24496 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24498 return createRecentTaskInfoFromTaskRecord(tr);
24500 Binder.restoreCallingIdentity(origId);
24506 public void moveToFront() {
24508 // Will bring task to front if it already has a root activity.
24509 final long origId = Binder.clearCallingIdentity();
24511 synchronized (this) {
24512 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24515 Binder.restoreCallingIdentity(origId);
24520 public int startActivity(IBinder whoThread, String callingPackage,
24521 Intent intent, String resolvedType, Bundle bOptions) {
24524 int callingUser = UserHandle.getCallingUserId();
24526 IApplicationThread appThread;
24527 synchronized (ActivityManagerService.this) {
24528 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24530 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24532 appThread = IApplicationThread.Stub.asInterface(whoThread);
24533 if (appThread == null) {
24534 throw new IllegalArgumentException("Bad app thread " + appThread);
24537 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24538 resolvedType, null, null, null, null, 0, 0, null, null,
24539 null, bOptions, false, callingUser, tr, "AppTaskImpl");
24543 public void setExcludeFromRecents(boolean exclude) {
24546 synchronized (ActivityManagerService.this) {
24547 long origId = Binder.clearCallingIdentity();
24549 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24551 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24553 Intent intent = tr.getBaseIntent();
24555 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24557 intent.setFlags(intent.getFlags()
24558 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24561 Binder.restoreCallingIdentity(origId);
24568 * Kill processes for the user with id userId and that depend on the package named packageName
24571 public void killPackageDependents(String packageName, int userId) {
24572 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24573 if (packageName == null) {
24574 throw new NullPointerException(
24575 "Cannot kill the dependents of a package without its name.");
24578 long callingId = Binder.clearCallingIdentity();
24579 IPackageManager pm = AppGlobals.getPackageManager();
24582 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24583 } catch (RemoteException e) {
24585 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24586 throw new IllegalArgumentException(
24587 "Cannot kill dependents of non-existing package " + packageName);
24590 synchronized(this) {
24591 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24592 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24593 "dep: " + packageName);
24596 Binder.restoreCallingIdentity(callingId);
24601 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24602 throws RemoteException {
24603 final long callingId = Binder.clearCallingIdentity();
24605 mKeyguardController.dismissKeyguard(token, callback);
24607 Binder.restoreCallingIdentity(callingId);
24612 public int restartUserInBackground(final int userId) {
24613 return mUserController.restartUser(userId, /* foreground */ false);
24617 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24618 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24619 "scheduleApplicationInfoChanged()");
24621 synchronized (this) {
24622 final long origId = Binder.clearCallingIdentity();
24624 updateApplicationInfoLocked(packageNames, userId);
24626 Binder.restoreCallingIdentity(origId);
24631 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24632 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24633 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24634 final ProcessRecord app = mLruProcesses.get(i);
24635 if (app.thread == null) {
24639 if (userId != UserHandle.USER_ALL && app.userId != userId) {
24643 final int packageCount = app.pkgList.size();
24644 for (int j = 0; j < packageCount; j++) {
24645 final String packageName = app.pkgList.keyAt(j);
24646 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24648 final ApplicationInfo ai = AppGlobals.getPackageManager()
24649 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24651 app.thread.scheduleApplicationInfoChanged(ai);
24653 } catch (RemoteException e) {
24654 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24655 packageName, app));
24663 * Attach an agent to the specified process (proces name or PID)
24665 public void attachAgent(String process, String path) {
24667 synchronized (this) {
24668 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24669 if (proc == null || proc.thread == null) {
24670 throw new IllegalArgumentException("Unknown process: " + process);
24673 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24674 if (!isDebuggable) {
24675 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24676 throw new SecurityException("Process not debuggable: " + proc);
24680 proc.thread.attachAgent(path);
24682 } catch (RemoteException e) {
24683 throw new IllegalStateException("Process disappeared");
24688 public static class Injector {
24689 private NetworkManagementInternal mNmi;
24691 public Context getContext() {
24695 public AppOpsService getAppOpsService(File file, Handler handler) {
24696 return new AppOpsService(file, handler);
24699 public Handler getUiHandler(ActivityManagerService service) {
24700 return service.new UiHandler();
24703 public boolean isNetworkRestrictedForUid(int uid) {
24704 if (ensureHasNetworkManagementInternal()) {
24705 return mNmi.isNetworkRestrictedForUid(uid);
24710 private boolean ensureHasNetworkManagementInternal() {
24711 if (mNmi == null) {
24712 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24714 return mNmi != null;
24719 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24720 throws RemoteException {
24721 synchronized (this) {
24722 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24726 final long origId = Binder.clearCallingIdentity();
24728 r.setShowWhenLocked(showWhenLocked);
24730 Binder.restoreCallingIdentity(origId);
24736 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24737 synchronized (this) {
24738 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24742 final long origId = Binder.clearCallingIdentity();
24744 r.setTurnScreenOn(turnScreenOn);
24746 Binder.restoreCallingIdentity(origId);